예제 #1
0
 /**
  * Create a prop, add it to the scene with its base at the insertion point, and pick it. Assumes
  * that the application is in world-building mode.
  *
  * @param propType which kind of prop to add (not null)
  * @param relativeSize the prop's size relative to standard (>0)
  */
 private void addAsPick(String propType, float relativeSize) {
   assert propType != null;
   assert relativeSize > 0f : relativeSize;
   /*
    * Create the prop.
    */
   Node node = create(propType, relativeSize);
   /*
    * The new prop is to be the ONLY picked spatial, so unpick the rest.
    */
   PickablesNode pickables = scene.getWorld().getPickables();
   pickables.clearPick();
   /*
    * Add and pick the prop.
    */
   pickables.add(node);
   SpatialProperties.setPicked(node, true);
   /*
    * Initialize the prop's position.
    */
   Cursor3DIndicator cursor3D = scene.getIndicators().getCursor3D();
   Vector3f baseLocation = cursor3D.getWorldLocation();
   float baseY = MySpatial.getMinY(node);
   Vector3f centerLocation = baseLocation.add(0f, -baseY, 0f);
   MySpatial.setWorldLocation(node, centerLocation);
 }
예제 #2
0
  /**
   * Create a prop without adding it to the scene.
   *
   * @param propType which kind of prop to add (not null)
   * @param relativeSize the prop's size relative to standard (>0)
   * @return a new node to represent the prop, or null if the model is invalid
   */
  private Node create(String propType, float relativeSize) {
    assert propType != null;
    assert relativeSize > 0f : relativeSize;

    Node propNode = loadModel(propType);
    Node modelNode = (Node) propNode.getChild(0);
    List<Spatial> parts = modelNode.getChildren();
    /*
     * Texture each part of the prop and specify its hardness.
     */
    for (Spatial part : parts) {
      String partName = part.getName();
      if (!(part instanceof Geometry)) {
        logger.log(Level.SEVERE, "Prop part {0} is not a geometry.", MyString.quote(partName));
        return null;
      }
      String materialName = material(partName);
      SpatialProperties.setHardness(part, materialName);
      Material material = Assets.loadBlockMaterial(materialName);
      part.setMaterial(material);
    }
    /*
     * Set the scale factor.
     */
    float scaleFactor = scene.getScaleFactor();
    float modelScale = relativeSize / scaleFactor;
    propNode.setLocalScale(modelScale);
    assert getRelativeSize(propNode) == relativeSize : relativeSize;
    /*
     * Set other properties.
     */
    propNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
    /*
     * Give the prop a physics control.
     */
    CollisionShape shape = createShape(propType, relativeSize, parts);
    float mass = calculateMass(propType, relativeSize);
    RigidBodyControl rigidBodyControl = new RigidBodyControl(shape, mass);
    propNode.addControl(rigidBodyControl);
    /*
     * Configure the physics control.
     */
    rigidBodyControl.setFriction(friction);
    scene.getWorld().getPhysics().addObject(rigidBodyControl);
    /*
     * Give the prop a PickedControl.
     */
    SpatialProperties.setPickType(propNode, pickType);
    PickedControl pickedControl = new PickedControl();
    propNode.addControl(pickedControl);

    return propNode;
  }
예제 #3
0
  /**
   * Generate a collision shape for a prop.
   *
   * @param propType the type of the prop (not null)
   * @param relativeSize the prop's size relative to standard (&gt;0)
   * @param parts (not null)
   * @return a new instance
   */
  private CollisionShape createShape(String propType, float relativeSize, List<Spatial> parts) {
    assert propType != null;
    assert relativeSize > 0f : relativeSize;
    assert parts != null;
    assert !parts.isEmpty();

    if ("barrel".equals(propType)) {
      /*
       * Generate a cylindrical shape aligned with the Y-axis.
       */
      float halfHeight = 0.5f * relativeSize; // meters
      float radius = 0.472f * relativeSize; // meters
      Vector3f halfExtents = new Vector3f(radius, halfHeight, radius);
      float scaleFactor = scene.getScaleFactor();
      halfExtents.divideLocal(scaleFactor);
      CollisionShape shape = new CylinderCollisionShape(halfExtents, PhysicsSpace.AXIS_Y);
      return shape;
    }
    /*
     * Generate a compound shape composed of GImpact shapes,
     * one for each geometry.
     */
    CompoundCollisionShape shape = new CompoundCollisionShape();
    for (Spatial part : parts) {
      Geometry geometry = (Geometry) part;
      Mesh mesh = geometry.getMesh();
      CollisionShape partShape = new GImpactCollisionShape(mesh);
      Vector3f scale = part.getWorldScale();
      partShape.setScale(scale);
      shape.addChildShape(partShape, Vector3f.ZERO);
    }
    return shape;
  }
예제 #4
0
 /**
  * Reload a prop and unpick it.
  *
  * @param originalProp which prop to reload (not null)
  */
 public void reload(Spatial originalProp) {
   String name = originalProp.getName();
   logger.log(Level.INFO, "reloading prop {0}", MyString.quote(name));
   Node reloaded = duplicate(originalProp);
   scene.deleteSpatial(originalProp);
   reloaded.setName(name);
 }
예제 #5
0
  /**
   * Get the relative size of a prop.
   *
   * @param spatial which prop (not null)
   * @return the prop's size relative to standard (&gt;0)
   */
  public float getRelativeSize(Spatial spatial) {
    assert spatial != null;

    float result = spatial.getWorldScale().x;
    result *= scene.getScaleFactor();
    return result;
  }
예제 #6
0
  /**
   * Load a prop model without adding it to the scene.
   *
   * @param propType which kind of prop to load (not null)
   */
  private Node loadModel(String propType) {
    assert propType != null;
    /*
     * Load the prop model.
     */
    Node node = Assets.loadPropModel(propType);
    /*
     * Generate a unique name for the new prop.
     */
    NameGenerator nameGenerator = scene.getNameGenerator();
    String name = nameGenerator.unique(propType);
    node.setName(name);

    return node;
  }
예제 #7
0
  /**
   * Create a prop and add it to the scene. Assumes that the application is in world-building mode.
   *
   * @param propType which kind of prop to add (not null)
   * @param relativeSize the prop's size relative to standard (&gt;0)
   * @param centerLocation world coordinates for the prop's center (unaffected, not null)
   * @param orientation initial orientation of the prop (unaffected, unit vector)
   */
  Node add(String propType, float relativeSize, Vector3f centerLocation, Quaternion orientation) {
    assert propType != null;
    assert relativeSize > 0f : relativeSize;
    assert orientation != null;
    /*
     * Create the prop and add it to the scene.
     */
    Node node = create(propType, relativeSize);
    scene.getWorld().getPickables().add(node);
    /*
     * Position the prop.
     */
    MySpatial.setWorldOrientation(node, orientation);
    MySpatial.setWorldLocation(node, centerLocation);

    return node;
  }