md5 model and throwing a physics ball

well I was working on attaching and detaching models from bones and it turned into a possible dodgeball game, right now though you can just pick up and throw balls.and for performance checking hit 1,2,3 keys to toggle shadows, reflections, and shaders(lighting shader).

oh yeah wasd to move, f to pick up, and space to throw. robot model was made in blender and imported with md5reader2(slightly modified)

hopefully ill have some more time to work on this someday  :slight_smile:



edit: oh yeah the link xdmgames.com - This website is for sale! - xdmgames Resources and Information.

if you get error "failed to download…" just click it again I think my server is crappy

hehe pretty cool, a blender bender …

it looks really great, especially the floor.

mud2005 said:
robot model was made in blender and imported with md5reader2(slightly modified)


If your modifications can give any benefit to MD5 Reader 2 project, could you share them with the official project, considering that you are still in the member list of MD5 Reader 2 project on SourceForge.net?

Though, I got a little different error:
java.lang.Exception
at com.sun.javaws.Launcher.continueLaunch(Launcher.java:915)
at com.sun.javaws.Launcher.handleApplicationDesc(Launcher.java:522)
at com.sun.javaws.Launcher.handleLaunchFile(Launcher.java:218)
at com.sun.javaws.Launcher.run(Launcher.java:165)
at java.lang.Thread.run(Thread.java:613)

sure but thay are minor and may not be any help.

I took out the places where bounding boxes are set on the meshes cause I wanted bounding spheres

lines 147-148 in SkeletalModelInstance and lines 90-91 in ModelInstance

line 60 in AnimationAnimator I changed return false to true so I can play animation once and when I play animation I have to call player1.getThrowbingAnimator().setTime(player1.getThrowingAnimator().getMin()); to reset the animation

and there was a memory leak and some badly instantiated objects but after I found them they were already marked //tagged so I assume youve found these

the memory leak was in WeightedMesh.skinMesh and I just threw in a hack to fix it



               if (counter) {



         normals = BufferUtils.getVector3Array(mesh.getNormalBuffer(0));// tagged



         vectors = BufferUtils.getVector3Array(mesh.getVertexBuffer(0));// tagged



         counter = false;



      }



this was also already tagged.




Could you show how you set up the TextureRenderer for the reflection on the floor?

I'm currently struggling a bit with it :slight_smile:

sure, I got the code from this post http://www.jmonkeyengine.com/jmeforum/index.php?topic=3659.0 and the WaterRenderPass in jme (i think thats what I did its been a while) anyway heres the shader code:



simpleShader.vert

varying vec4 viewCoords;

void main()
{
gl_TexCoord[0]  = gl_MultiTexCoord0;


// This calculates our current projection coordinates
viewCoords = ftransform();
gl_Position = viewCoords;
}


simpleShader.frag

varying vec4 viewCoords;

uniform sampler2D reflection;
uniform sampler2D tex;


void main()
{
vec4 projCoord = viewCoords / viewCoords.q;
projCoord = (projCoord + 1.0) * 0.5;


projCoord.x = 1.0 - projCoord.x;


vec4 reflectionColor = 0.5 * (texture2D(reflection, projCoord.xy) + texture2D(tex,gl_TexCoord[0].st));

gl_FragColor = reflectionColor;
}



and ReflectRenderPass.java

package main;

/*
 * Copyright (c) 2003-2007 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.util.ArrayList;

import org.lwjgl.opengl.OpenGLException;
import org.lwjgl.opengl.Util;

import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.math.Plane;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.pass.Pass;
import com.jme.scene.Spatial;
import com.jme.scene.state.CullState;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;

/**
 * <code>ReflectRenderPass</code> Reflect effect pass.
 *
 * @author Rikard Herlitz (MrCoder)
 * @version $Id: ReflectRenderPass.java,v 1.1 2007/06/20 23:39:26 mud Exp $
 */
public class ReflectRenderPass extends Pass {
   private static final long serialVersionUID = 1L;

   private Camera cam;

   private TextureRenderer tRenderer;

   private Texture textureReflect;

   private ArrayList<Spatial> renderList;

   private ArrayList<Texture> texArray = new ArrayList<Texture>();

   private GLSLShaderObjectsState reflectionShader;

   private CullState cullBackFace;

   private TextureState ts;

   private Plane reflectPlane;

   private Vector3f calcVect = new Vector3f();

   private boolean supported = true;

   private int renderScale;

   public static String simpleShaderStr = "shaders/simpleReflectionShader";

   private String currentShaderStr;

   public void resetParameters() {
      reflectPlane = new Plane(new Vector3f(0.0f, 1.0f, 0.0f), 0.0f);

   }

   /**
    * Release pbuffers in TextureRenderer's. Preferably called from user
    * cleanup method.
    */
   public void cleanup() {
      if (isSupported())
         tRenderer.cleanup();
   }

   public boolean isSupported() {
      return supported;
   }

   /**
    * Creates a new ReflectRenderPass
    *
    * @param cam
    *            main rendercam to use for reflection settings etc
    * @param renderScale
    *            how many times smaller the reflection/refraction textures
    *            should be compared to the main display
    */
   public ReflectRenderPass(Camera cam, int renderScale,
         boolean useProjectedShader, boolean useRefraction) {
      this.cam = cam;
      this.renderScale = renderScale;
      resetParameters();
      initialize();
   }

   private void initialize() {

      DisplaySystem display = DisplaySystem.getDisplaySystem();

      reflectionShader = display.getRenderer().createGLSLShaderObjectsState();

      if (!reflectionShader.isSupported()) {
         supported = false;
      } else {
      }

      cullBackFace = display.getRenderer().createCullState();
      cullBackFace.setEnabled(true);
      cullBackFace.setCullMode(CullState.CS_BACK);

      if (isSupported()) {
         tRenderer = display.createTextureRenderer(display.getWidth()
               / renderScale, display.getHeight() / renderScale,
               TextureRenderer.RENDER_TEXTURE_2D);

         if (tRenderer.isSupported()) {
            tRenderer.setBackgroundColor(new ColorRGBA(0.0f, 0.0f, 0.0f,
                  1.0f));
            tRenderer.getCamera().setFrustum(cam.getFrustumNear(),
                  cam.getFrustumFar(), cam.getFrustumLeft(),
                  cam.getFrustumRight(), cam.getFrustumTop(),
                  cam.getFrustumBottom());

            textureReflect = new Texture();
            textureReflect.setWrap(Texture.WM_ECLAMP_S_ECLAMP_T);
            textureReflect.setFilter(Texture.FM_LINEAR);
            textureReflect.setScale(new Vector3f(-1.0f, 1.0f, 1.0f));
            textureReflect.setTranslation(new Vector3f(1.0f, 0.0f, 0.0f));
            tRenderer.setupTexture(textureReflect);

            ts = display.getRenderer().createTextureState();
            ts.setEnabled(true);

            Texture tex = TextureManager.loadTexture(
                  ReflectRenderPass.class.getClassLoader().getResource(
                        "images/dodgeCourtFloor.png"),
                  Texture.MM_LINEAR, Texture.FM_LINEAR, Image.GUESS_FORMAT_NO_S3TC, 0.0f, true);

            ts.setTexture(tex, 0);

            ts.setTexture(textureReflect, 1);

            reloadShader();
         } else {
            supported = false;
         }
      }

   }

   @Override
   protected void doUpdate(float tpf) {
      super.doUpdate(tpf);
   }

   public void doRender(Renderer r) {
      float camPlaneDist = reflectPlane.pseudoDistance(cam.getLocation());

      if (isSupported()) {
         reflectionShader.clearUniforms();

         reflectionShader.setUniform("tex", 0);
         reflectionShader.setUniform("reflection", 1);

         reflectionShader.apply();

         renderReflection();

      } else {
         ts.getTexture().setTranslation(
               new Vector3f(0, 0, 0));
      }
   }

   public void reloadShader() {
      currentShaderStr = simpleShaderStr;

      GLSLShaderObjectsState testShader = DisplaySystem.getDisplaySystem()
            .getRenderer().createGLSLShaderObjectsState();
      try {
         testShader.load(ReflectRenderPass.class.getClassLoader()
               .getResource(currentShaderStr + ".vert"),
               ReflectRenderPass.class.getClassLoader().getResource(
                     currentShaderStr + ".frag"));
         testShader.apply();
         Util.checkGLError();
      } catch (OpenGLException e) {
         e.printStackTrace();
         return;
      }

      reflectionShader.load(ReflectRenderPass.class.getClassLoader()
            .getResource(currentShaderStr + ".vert"),
            ReflectRenderPass.class.getClassLoader().getResource(
                  currentShaderStr + ".frag"));

   }

   public void setReflectEffectOnSpatial(Spatial spatial) {
      spatial.setRenderState(cullBackFace);
      if (isSupported()) {
         spatial.setRenderQueueMode(Renderer.QUEUE_SKIP);
         spatial.setRenderState(reflectionShader);
         spatial.setRenderState(ts);
      } else {
         spatial.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
         spatial.setLightCombineMode(LightState.OFF);
         spatial.setRenderState(ts);
      }
      spatial.updateRenderState();
   }

   // temporary vectors for mem opt.
   private Vector3f tmpLocation = new Vector3f();

   private Vector3f camReflectPos = new Vector3f();

   private Vector3f camReflectDir = new Vector3f();

   private Vector3f camReflectUp = new Vector3f();

   private Vector3f camReflectLeft = new Vector3f();

   private Vector3f camLocation = new Vector3f();

   private void renderReflection() {

      camLocation.set(cam.getLocation());

      float planeDistance = reflectPlane.pseudoDistance(camLocation);
      calcVect.set(reflectPlane.getNormal()).multLocal(planeDistance * 2.0f);
      camReflectPos.set(camLocation.subtractLocal(calcVect));

      camLocation.set(cam.getLocation()).addLocal(cam.getDirection());
      planeDistance = reflectPlane.pseudoDistance(camLocation);
      calcVect.set(reflectPlane.getNormal()).multLocal(planeDistance * 2.0f);
      camReflectDir.set(camLocation.subtractLocal(calcVect)).subtractLocal(
            camReflectPos).normalizeLocal();

      camLocation.set(cam.getLocation()).addLocal(cam.getUp());
      planeDistance = reflectPlane.pseudoDistance(camLocation);
      calcVect.set(reflectPlane.getNormal()).multLocal(planeDistance * 2.0f);
      camReflectUp.set(camLocation.subtractLocal(calcVect)).subtractLocal(
            camReflectPos).normalizeLocal();

      camReflectLeft.set(camReflectDir).crossLocal(camReflectUp)
            .normalizeLocal();

      tRenderer.getCamera().getLocation().set(camReflectPos);
      tRenderer.getCamera().getDirection().set(camReflectDir);
      tRenderer.getCamera().getUp().set(camReflectUp);
      tRenderer.getCamera().getLeft().set(camReflectLeft);

      texArray.clear();
      texArray.add(textureReflect);
      tRenderer.render(renderList, texArray);

   }

   public void removeReflectedScene(Spatial renderNode) {
      if (renderList != null) {
         //System.out.println(renderList.remove(renderNode));
      }
   }

   public void clearReflectedScene() {
      if (renderList != null) {
         renderList.clear();
      }
   }

   public void setReflectedScene(Spatial renderNode) {
      if (renderList == null) {
         renderList = new ArrayList<Spatial>();
      }
      renderList.clear();
      renderList.add(renderNode);
      renderNode.updateRenderState();
   }

   public void addReflectedScene(Spatial renderNode) {
      if (renderList == null) {
         renderList = new ArrayList<Spatial>();
      }
      if (!renderList.contains(renderNode)) {
         renderList.add(renderNode);
         renderNode.updateRenderState();
      }
   }

   public Camera getCam() {
      return cam;
   }

   public void setCam(Camera cam) {
      this.cam = cam;
   }

   public float getPlaneHeight() {
      return reflectPlane.getConstant();
   }

   public void setPlaneHeight(float planeHeight) {
      this.reflectPlane.setConstant(planeHeight);
   }

   public Vector3f getNormal() {
      return reflectPlane.getNormal();
   }

   public void setNormal(Vector3f normal) {
      reflectPlane.setNormal(normal);
   }

   public Plane getReflectPlane() {
      return reflectPlane;
   }

   public void setReflectPlane(Plane reflectPlane) {
      this.reflectPlane = reflectPlane;
   }

   public Texture getTextureReflect() {
      return textureReflect;
   }

   public int getRenderScale() {
      return renderScale;
   }

   public void setRenderScale(int renderScale) {
      this.renderScale = renderScale;
   }
}



then add this is your renderpass code:

       reflectRenderPass = new ReflectRenderPass(cam, 1, true, true);

      reflectRenderPass.setReflectEffectOnSpatial(court.getFloor());

      reflectRenderPass.addReflectedScene(player2.getDynamicNode());

                pManager.add(reflectRenderPass);



good luck  :)

cool thanks i'll try it out

nice and smooth :smiley:



Maybe it should be a tutorial or demo/test :wink:





I just wanted to let you know that I also got an error (I think it's the same as Ender's) and I believe we are both on MacOSX, it runs fine for me in windows though.

Looks very awesome!

Keep up the good work! :slight_smile:

I just wanted to let you know that I also got an error (I think it's the same as Ender's) and I believe we are both on MacOSX, it runs fine for me in windows though


Im not surprised, I dont have a mac to test on. sorry to all the mac guys. It has been tested in windows and Linux.
basixs said:
I just wanted to let you know that I also got an error (I think it's the same as Ender's) and I believe we are both on MacOSX, it runs fine for me in windows though.


Yes we are both on Mac OS X :).

I do not have time to investigate what it is. Though it is not a error caused by jME or LWJGL. I think a bug with WebStart.