/** * 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); }
/** * 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; }
/** * 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 (>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; }