@Override public void read(JmeImporter im) throws IOException { InputCapsule ic = im.getCapsule(this); // NOTE: In previous versions of jME3, initialVelocity was called startVelocity if (ic.getSavableVersion(DefaultParticleInfluencer.class) == 0) { initialVelocity = (Vector3f) ic.readSavable("startVelocity", Vector3f.ZERO.clone()); } else { initialVelocity = (Vector3f) ic.readSavable("initialVelocity", Vector3f.ZERO.clone()); } velocityVariation = ic.readFloat("variation", 0.2f); }
@Override public void read(JmeImporter e) throws IOException { super.read(e); InputCapsule capsule = e.getCapsule(this); float mass = capsule.readFloat("mass", 1.0f); this.mass = mass; rebuildRigidBody(); setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone())); setFriction(capsule.readFloat("friction", 0.5f)); setKinematic(capsule.readBoolean("kinematic", false)); setRestitution(capsule.readFloat("restitution", 0)); setAngularFactor(capsule.readFloat("angularFactor", 1)); setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0)); setSleepingThresholds( capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f)); setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0)); setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0)); setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f())); setPhysicsRotation((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f())); joints = capsule.readSavableArrayList("joints", null); }
@Override public void simpleInitApp() { JmeCanvasContext ctx = (JmeCanvasContext) getContext(); gui = new GUI(this, ctx.getCanvas()); gui.show(); flyCam.setEnabled(false); Box b = new Box(1, 1, 1); Geometry geom = new Geometry("Box", b); Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", ColorRGBA.Blue); geom.setMaterial(mat); rootNode.attachChild(geom); cinematic = new Cinematic(rootNode, 5); MotionPath path = new MotionPath(); path.addWayPoint(Vector3f.ZERO.clone()); path.addWayPoint(new Vector3f(10, 0, 0)); MotionEvent motionEvent = new MotionEvent(geom, path, 5); cinematic.addCinematicEvent(0, motionEvent); cinematic.fitDuration(); cinematic.setLoopMode(LoopMode.Loop); stateManager.attach(cinematic); }
/** * Simple Water renders a simple plane that use reflection and refraction to look like water. It's * pretty basic, but much faster than the WaterFilter It's useful if you aim low specs hardware and * still want a good looking water. Usage is : <code> * SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager); * //setting the scene to use for reflection * waterProcessor.setReflectionScene(mainScene); * //setting the light position * waterProcessor.setLightPosition(lightPos); * * //setting the water plane * Vector3f waterLocation=new Vector3f(0,-20,0); * waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y))); * //setting the water color * waterProcessor.setWaterColor(ColorRGBA.Brown); * * //creating a quad to render water to * Quad quad = new Quad(400,400); * * //the texture coordinates define the general size of the waves * quad.scaleTextureCoordinates(new Vector2f(6f,6f)); * * //creating a geom to attach the water material * Geometry water=new Geometry("water", quad); * water.setLocalTranslation(-200, -20, 250); * water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); * //finally setting the material * water.setMaterial(waterProcessor.getMaterial()); * * //attaching the water to the root node * rootNode.attachChild(water); * </code> * * @author Normen Hansen & Rémy Bouquet */ public class SimpleWaterProcessor implements SceneProcessor { protected RenderManager rm; protected ViewPort vp; protected Spatial reflectionScene; protected ViewPort reflectionView; protected ViewPort refractionView; protected FrameBuffer reflectionBuffer; protected FrameBuffer refractionBuffer; protected Camera reflectionCam; protected Camera refractionCam; protected Texture2D reflectionTexture; protected Texture2D refractionTexture; protected Texture2D depthTexture; protected Texture2D normalTexture; protected Texture2D dudvTexture; protected int renderWidth = 512; protected int renderHeight = 512; protected Plane plane = new Plane(Vector3f.UNIT_Y, Vector3f.ZERO.dot(Vector3f.UNIT_Y)); protected float speed = 0.05f; protected Ray ray = new Ray(); protected Vector3f targetLocation = new Vector3f(); protected AssetManager manager; protected Material material; protected float waterDepth = 1; protected float waterTransparency = 0.4f; protected boolean debug = false; private Picture dispRefraction; private Picture dispReflection; private Picture dispDepth; private Plane reflectionClipPlane; private Plane refractionClipPlane; private float refractionClippingOffset = 0.3f; private float reflectionClippingOffset = -5f; private float distortionScale = 0.2f; private float distortionMix = 0.5f; private float texScale = 1f; /** * Creates a SimpleWaterProcessor * * @param manager the asset manager */ public SimpleWaterProcessor(AssetManager manager) { this.manager = manager; material = new Material(manager, "Common/MatDefs/Water/SimpleWater.j3md"); material.setFloat("waterDepth", waterDepth); material.setFloat("waterTransparency", waterTransparency / 10); material.setColor("waterColor", ColorRGBA.White); material.setVector3("lightPos", new Vector3f(1, -1, 1)); material.setFloat("distortionScale", distortionScale); material.setFloat("distortionMix", distortionMix); material.setFloat("texScale", texScale); updateClipPlanes(); } public void initialize(RenderManager rm, ViewPort vp) { this.rm = rm; this.vp = vp; loadTextures(manager); createTextures(); applyTextures(material); createPreViews(); material.setVector2( "FrustumNearFar", new Vector2f(vp.getCamera().getFrustumNear(), vp.getCamera().getFrustumFar())); if (debug) { dispRefraction = new Picture("dispRefraction"); dispRefraction.setTexture(manager, refractionTexture, false); dispReflection = new Picture("dispRefraction"); dispReflection.setTexture(manager, reflectionTexture, false); dispDepth = new Picture("depthTexture"); dispDepth.setTexture(manager, depthTexture, false); } } public void reshape(ViewPort vp, int w, int h) {} public boolean isInitialized() { return rm != null; } float time = 0; float savedTpf = 0; public void preFrame(float tpf) { time = time + (tpf * speed); if (time > 1f) { time = 0; } material.setFloat("time", time); savedTpf = tpf; } public void postQueue(RenderQueue rq) { Camera sceneCam = rm.getCurrentCamera(); // update refraction cam refractionCam.setLocation(sceneCam.getLocation()); refractionCam.setRotation(sceneCam.getRotation()); refractionCam.setFrustum( sceneCam.getFrustumNear(), sceneCam.getFrustumFar(), sceneCam.getFrustumLeft(), sceneCam.getFrustumRight(), sceneCam.getFrustumTop(), sceneCam.getFrustumBottom()); refractionCam.setParallelProjection(sceneCam.isParallelProjection()); // update reflection cam WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam); // Rendering reflection and refraction rm.renderViewPort(reflectionView, savedTpf); rm.renderViewPort(refractionView, savedTpf); rm.getRenderer().setFrameBuffer(vp.getOutputFrameBuffer()); rm.setCamera(sceneCam, false); } public void postFrame(FrameBuffer out) { if (debug) { displayMap(rm.getRenderer(), dispRefraction, 64); displayMap(rm.getRenderer(), dispReflection, 256); displayMap(rm.getRenderer(), dispDepth, 448); } } public void cleanup() {} // debug only : displays maps protected void displayMap(Renderer r, Picture pic, int left) { Camera cam = vp.getCamera(); rm.setCamera(cam, true); int h = cam.getHeight(); pic.setPosition(left, h / 20f); pic.setWidth(128); pic.setHeight(128); pic.updateGeometricState(); rm.renderGeometry(pic); rm.setCamera(cam, false); } protected void loadTextures(AssetManager manager) { normalTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/water_normalmap.png"); dudvTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/dudv_map.jpg"); normalTexture.setWrap(WrapMode.Repeat); dudvTexture.setWrap(WrapMode.Repeat); } protected void createTextures() { reflectionTexture = new Texture2D(renderWidth, renderHeight, Format.RGBA8); refractionTexture = new Texture2D(renderWidth, renderHeight, Format.RGBA8); depthTexture = new Texture2D(renderWidth, renderHeight, Format.Depth); } protected void applyTextures(Material mat) { mat.setTexture("water_reflection", reflectionTexture); mat.setTexture("water_refraction", refractionTexture); mat.setTexture("water_depthmap", depthTexture); mat.setTexture("water_normalmap", normalTexture); mat.setTexture("water_dudvmap", dudvTexture); } protected void createPreViews() { reflectionCam = new Camera(renderWidth, renderHeight); refractionCam = new Camera(renderWidth, renderHeight); // create a pre-view. a view that is rendered before the main view reflectionView = new ViewPort("Reflection View", reflectionCam); reflectionView.setClearFlags(true, true, true); reflectionView.setBackgroundColor(ColorRGBA.Black); // create offscreen framebuffer reflectionBuffer = new FrameBuffer(renderWidth, renderHeight, 1); // setup framebuffer to use texture reflectionBuffer.setDepthBuffer(Format.Depth); reflectionBuffer.setColorTexture(reflectionTexture); // set viewport to render to offscreen framebuffer reflectionView.setOutputFrameBuffer(reflectionBuffer); reflectionView.addProcessor( new ReflectionProcessor(reflectionCam, reflectionBuffer, reflectionClipPlane)); // attach the scene to the viewport to be rendered reflectionView.attachScene(reflectionScene); // create a pre-view. a view that is rendered before the main view refractionView = new ViewPort("Refraction View", refractionCam); refractionView.setClearFlags(true, true, true); refractionView.setBackgroundColor(ColorRGBA.Black); // create offscreen framebuffer refractionBuffer = new FrameBuffer(renderWidth, renderHeight, 1); // setup framebuffer to use texture refractionBuffer.setDepthBuffer(Format.Depth); refractionBuffer.setColorTexture(refractionTexture); refractionBuffer.setDepthTexture(depthTexture); // set viewport to render to offscreen framebuffer refractionView.setOutputFrameBuffer(refractionBuffer); refractionView.addProcessor(new RefractionProcessor()); // attach the scene to the viewport to be rendered refractionView.attachScene(reflectionScene); } protected void destroyViews() { // rm.removePreView(reflectionView); rm.removePreView(refractionView); } /** * Get the water material from this processor, apply this to your water quad. * * @return */ public Material getMaterial() { return material; } /** * Sets the reflected scene, should not include the water quad! Set before adding processor. * * @param spat */ public void setReflectionScene(Spatial spat) { reflectionScene = spat; } /** * returns the width of the reflection and refraction textures * * @return */ public int getRenderWidth() { return renderWidth; } /** * returns the height of the reflection and refraction textures * * @return */ public int getRenderHeight() { return renderHeight; } /** * Set the reflection Texture render size, set before adding the processor! * * @param width * @param height */ public void setRenderSize(int width, int height) { renderWidth = width; renderHeight = height; } /** * returns the water plane * * @return */ public Plane getPlane() { return plane; } /** * Set the water plane for this processor. * * @param plane */ public void setPlane(Plane plane) { this.plane.setConstant(plane.getConstant()); this.plane.setNormal(plane.getNormal()); updateClipPlanes(); } /** * Set the water plane using an origin (location) and a normal (reflection direction). * * @param origin Set to 0,-6,0 if your water quad is at that location for correct reflection * @param normal Set to 0,1,0 (Vector3f.UNIT_Y) for normal planar water */ public void setPlane(Vector3f origin, Vector3f normal) { this.plane.setOriginNormal(origin, normal); updateClipPlanes(); } private void updateClipPlanes() { reflectionClipPlane = plane.clone(); reflectionClipPlane.setConstant(reflectionClipPlane.getConstant() + reflectionClippingOffset); refractionClipPlane = plane.clone(); refractionClipPlane.setConstant(refractionClipPlane.getConstant() + refractionClippingOffset); } /** * Set the light Position for the processor * * @param position */ // TODO maybe we should provide a convenient method to compute position from direction public void setLightPosition(Vector3f position) { material.setVector3("lightPos", position); } /** * Set the color that will be added to the refraction texture. * * @param color */ public void setWaterColor(ColorRGBA color) { material.setColor("waterColor", color); } /** * Higher values make the refraction texture shine through earlier. Default is 4 * * @param depth */ public void setWaterDepth(float depth) { waterDepth = depth; material.setFloat("waterDepth", depth); } /** * return the water depth * * @return */ public float getWaterDepth() { return waterDepth; } /** * returns water transparency * * @return */ public float getWaterTransparency() { return waterTransparency; } /** * sets the water transparency default os 0.1f * * @param waterTransparency */ public void setWaterTransparency(float waterTransparency) { this.waterTransparency = Math.max(0, waterTransparency); material.setFloat("waterTransparency", waterTransparency / 10); } /** * Sets the speed of the wave animation, default = 0.05f. * * @param speed */ public void setWaveSpeed(float speed) { this.speed = speed; } /** * returns the speed of the wave animation. * * @return the speed */ public float getWaveSpeed() { return speed; } /** Sets the scale of distortion by the normal map, default = 0.2 */ public void setDistortionScale(float value) { distortionScale = value; material.setFloat("distortionScale", distortionScale); } /** Sets how the normal and dudv map are mixed to create the wave effect, default = 0.5 */ public void setDistortionMix(float value) { distortionMix = value; material.setFloat("distortionMix", distortionMix); } /** * Sets the scale of the normal/dudv texture, default = 1. Note that the waves should be scaled by * the texture coordinates of the quad to avoid animation artifacts, use * mesh.scaleTextureCoordinates(Vector2f) for that. */ public void setTexScale(float value) { texScale = value; material.setFloat("texScale", texScale); } /** * returns the scale of distortion by the normal map, default = 0.2 * * @return the distortion scale */ public float getDistortionScale() { return distortionScale; } /** * returns how the normal and dudv map are mixed to create the wave effect, default = 0.5 * * @return the distortion mix */ public float getDistortionMix() { return distortionMix; } /** * returns the scale of the normal/dudv texture, default = 1. Note that the waves should be scaled * by the texture coordinates of the quad to avoid animation artifacts, use * mesh.scaleTextureCoordinates(Vector2f) for that. * * @return the textures scale */ public float getTexScale() { return texScale; } /** * retruns true if the waterprocessor is in debug mode * * @return */ public boolean isDebug() { return debug; } /** * set to true to display reflection and refraction textures in the GUI for debug purpose * * @param debug */ public void setDebug(boolean debug) { this.debug = debug; } /** * Creates a quad with the water material applied to it. * * @param width * @param height * @return */ public Geometry createWaterGeometry(float width, float height) { Quad quad = new Quad(width, height); Geometry geom = new Geometry("WaterGeometry", quad); geom.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); geom.setMaterial(material); return geom; } /** * returns the reflection clipping plane offset * * @return */ public float getReflectionClippingOffset() { return reflectionClippingOffset; } /** * sets the reflection clipping plane offset set a nagetive value to lower the clipping plane for * relection texture rendering. * * @param reflectionClippingOffset */ public void setReflectionClippingOffset(float reflectionClippingOffset) { this.reflectionClippingOffset = reflectionClippingOffset; updateClipPlanes(); } /** * returns the refraction clipping plane offset * * @return */ public float getRefractionClippingOffset() { return refractionClippingOffset; } /** * Sets the refraction clipping plane offset set a positive value to raise the clipping plane for * refraction texture rendering * * @param refractionClippingOffset */ public void setRefractionClippingOffset(float refractionClippingOffset) { this.refractionClippingOffset = refractionClippingOffset; updateClipPlanes(); } /** Refraction Processor */ public class RefractionProcessor implements SceneProcessor { RenderManager rm; ViewPort vp; public void initialize(RenderManager rm, ViewPort vp) { this.rm = rm; this.vp = vp; } public void reshape(ViewPort vp, int w, int h) {} public boolean isInitialized() { return rm != null; } public void preFrame(float tpf) { refractionCam.setClipPlane(refractionClipPlane, Plane.Side.Negative); // ,-1 } public void postQueue(RenderQueue rq) {} public void postFrame(FrameBuffer out) {} public void cleanup() {} } }
public void read(JmeImporter e) throws IOException { center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone()); }