@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);
  }
Пример #3
0
  @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() {}
  }
}
Пример #5
0
 public void read(JmeImporter e) throws IOException {
   center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone());
 }