Package com.bulletphysics.demos.opengl

Source Code of com.bulletphysics.demos.opengl.GLShapeDrawer

/*
* Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
*
* Bullet Continuous Collision Detection and Physics Library
* Copyright (c) 2003-2008 Erwin Coumans  http://www.bulletphysics.com/
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
*    claim that you wrote the original software. If you use this software
*    in a product, an acknowledgment in the product documentation would be
*    appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

package com.bulletphysics.demos.opengl;

import com.bulletphysics.util.ObjectArrayList;
import com.bulletphysics.collision.broadphase.BroadphaseNativeType;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.CompoundShape;
import com.bulletphysics.collision.shapes.ConcaveShape;
import com.bulletphysics.collision.shapes.ConvexShape;
import com.bulletphysics.collision.shapes.CylinderShape;
import com.bulletphysics.collision.shapes.InternalTriangleIndexCallback;
import com.bulletphysics.collision.shapes.PolyhedralConvexShape;
import com.bulletphysics.collision.shapes.ShapeHull;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.collision.shapes.StaticPlaneShape;
import com.bulletphysics.collision.shapes.TriangleCallback;
import com.bulletphysics.linearmath.DebugDrawModes;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.linearmath.TransformUtil;
import com.bulletphysics.linearmath.VectorUtil;
import com.bulletphysics.util.IntArrayList;
import com.bulletphysics.util.ObjectPool;
import javax.vecmath.Vector3f;
//import static org.lwjgl.opengl.GL11.*;
//import static org.lwjgl.opengl.glu.GLU.*;
import static com.bulletphysics.demos.opengl.IGL.*;

/**
*
* @author jezek2
*/
public class GLShapeDrawer {

  /*
  private static Map<CollisionShape,TriMeshKey> g_display_lists = new HashMap<CollisionShape,TriMeshKey>();
 
  private static int OGL_get_displaylist_for_shape(CollisionShape shape) {
    // JAVA NOTE: rewritten
    TriMeshKey trimesh = g_display_lists.get(shape);
    if (trimesh != null) {
      return trimesh.dlist;
    }

    return 0;
  }

  private static void OGL_displaylist_clean() {
    // JAVA NOTE: rewritten
    for (TriMeshKey trimesh : g_display_lists.values()) {
      glDeleteLists(trimesh.dlist, 1);
    }

    g_display_lists.clear();
  }
  */

  public static void drawCoordSystem(IGL gl) {
    gl.glBegin(GL_LINES);
    gl.glColor3f(1, 0, 0);
    gl.glVertex3f(0, 0, 0);
    gl.glVertex3f(1, 0, 0);
    gl.glColor3f(0, 1, 0);
    gl.glVertex3f(0, 0, 0);
    gl.glVertex3f(0, 1, 0);
    gl.glColor3f(0, 0, 1);
    gl.glVertex3f(0, 0, 0);
    gl.glVertex3f(0, 0, 1);
    gl.glEnd();
  }

  private static float[] glMat = new float[16];
 
  public static void drawOpenGL(IGL gl, Transform trans, CollisionShape shape, Vector3f color, int debugMode) {
    ObjectPool<Transform> transformsPool = ObjectPool.get(Transform.class);
    ObjectPool<Vector3f> vectorsPool = ObjectPool.get(Vector3f.class);

    //System.out.println("shape="+shape+" type="+BroadphaseNativeTypes.forValue(shape.getShapeType()));

    gl.glPushMatrix();
    trans.getOpenGLMatrix(glMat);
    gl.glMultMatrix(glMat);
//    if (shape.getShapeType() == BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE.getValue())
//    {
//      const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
//      const btConvexShape* convexShape = scalingShape->getChildShape();
//      float  scalingFactor = (float)scalingShape->getUniformScalingFactor();
//      {
//        btScalar tmpScaling[4][4]={{scalingFactor,0,0,0},
//          {0,scalingFactor,0,0},
//          {0,0,scalingFactor,0},
//          {0,0,0,1}};
//
//        drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode);
//      }
//      glPopMatrix();
//      return;
//    }

    if (shape.getShapeType() == BroadphaseNativeType.COMPOUND_SHAPE_PROXYTYPE) {
      CompoundShape compoundShape = (CompoundShape) shape;
      Transform childTrans = transformsPool.get();
      for (int i = compoundShape.getNumChildShapes() - 1; i >= 0; i--) {
        compoundShape.getChildTransform(i, childTrans);
        CollisionShape colShape = compoundShape.getChildShape(i);
        drawOpenGL(gl, childTrans, colShape, color, debugMode);
      }
      transformsPool.release(childTrans);
    }
    else {
      //drawCoordSystem();

      //glPushMatrix();

      gl.glEnable(GL_COLOR_MATERIAL);
      gl.glColor3f(color.x, color.y, color.z);

      boolean useWireframeFallback = true;

      if ((debugMode & DebugDrawModes.DRAW_WIREFRAME) == 0) {
        // you can comment out any of the specific cases, and use the default
        // the benefit of 'default' is that it approximates the actual collision shape including collision margin
       
        switch (shape.getShapeType()) {
          case BOX_SHAPE_PROXYTYPE: {
            BoxShape boxShape = (BoxShape) shape;
            Vector3f halfExtent = boxShape.getHalfExtentsWithMargin(vectorsPool.get());
            gl.glScalef(2f * halfExtent.x, 2f * halfExtent.y, 2f * halfExtent.z);
            gl.drawCube(1f);
            vectorsPool.release(halfExtent);
            useWireframeFallback = false;
            break;
          }
          case SPHERE_SHAPE_PROXYTYPE: {
            SphereShape sphereShape = (SphereShape) shape;
            float radius = sphereShape.getMargin(); // radius doesn't include the margin, so draw with margin
            // TODO: glutSolidSphere(radius,10,10);
            //sphere.draw(radius, 8, 8);
            gl.drawSphere(radius, 10, 10);
            /*
            glPointSize(10f);
            glBegin(GL_POINTS);
            glVertex3f(0f, 0f, 0f);
            glEnd();
            glPointSize(1f);
            */
            useWireframeFallback = false;
            break;
          }
//        case CONE_SHAPE_PROXYTYPE:
//          {
//            const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
//            int upIndex = coneShape->getConeUpIndex();
//            float radius = coneShape->getRadius();//+coneShape->getMargin();
//            float height = coneShape->getHeight();//+coneShape->getMargin();
//            switch (upIndex)
//            {
//            case 0:
//              glRotatef(90.0, 0.0, 1.0, 0.0);
//              break;
//            case 1:
//              glRotatef(-90.0, 1.0, 0.0, 0.0);
//              break;
//            case 2:
//              break;
//            default:
//              {
//              }
//            };
//
//            glTranslatef(0.0, 0.0, -0.5*height);
//            glutSolidCone(radius,height,10,10);
//            useWireframeFallback = false;
//            break;
//
//          }

          case STATIC_PLANE_PROXYTYPE:
          {
            StaticPlaneShape staticPlaneShape = (StaticPlaneShape)shape;
            float planeConst = staticPlaneShape.getPlaneConstant();
            Vector3f planeNormal = staticPlaneShape.getPlaneNormal(vectorsPool.get());
            Vector3f planeOrigin = vectorsPool.get();
            planeOrigin.scale(planeConst, planeNormal);
            Vector3f vec0 = vectorsPool.get();
            Vector3f vec1 = vectorsPool.get();
            TransformUtil.planeSpace1(planeNormal,vec0,vec1);
            float vecLen = 100f;
           
            Vector3f pt0 = vectorsPool.get();
            pt0.scaleAdd(vecLen, vec0, planeOrigin);

            Vector3f pt1 = vectorsPool.get();
            pt1.scale(vecLen, vec0);
            pt1.sub(planeOrigin, pt1);

            Vector3f pt2 = vectorsPool.get();
            pt2.scaleAdd(vecLen, vec1, planeOrigin);

            Vector3f pt3 = vectorsPool.get();
            pt3.scale(vecLen, vec1);
            pt3.sub(planeOrigin, pt3);
           
            gl.glBegin(gl.GL_LINES);
            gl.glVertex3f(pt0.x,pt0.y,pt0.z);
            gl.glVertex3f(pt1.x,pt1.y,pt1.z);
            gl.glVertex3f(pt2.x,pt2.y,pt2.z);
            gl.glVertex3f(pt3.x,pt3.y,pt3.z);
            gl.glEnd();
           
            vectorsPool.release(planeNormal);
            vectorsPool.release(planeOrigin);
            vectorsPool.release(vec0);
            vectorsPool.release(vec1);
            vectorsPool.release(pt0);
            vectorsPool.release(pt1);
            vectorsPool.release(pt2);
            vectorsPool.release(pt3);
           
            break;
          }
         
        case CYLINDER_SHAPE_PROXYTYPE:
          {
            CylinderShape cylinder = (CylinderShape) shape;
            int upAxis = cylinder.getUpAxis();

            float radius = cylinder.getRadius();
            Vector3f halfVec = vectorsPool.get();
            float halfHeight = VectorUtil.getCoord(cylinder.getHalfExtentsWithMargin(halfVec), upAxis);

            gl.drawCylinder(radius, halfHeight, upAxis);
           
            vectorsPool.release(halfVec);

            break;
          }
          default: {
            if (shape.isConvex())
            {
              ConvexShape convexShape = (ConvexShape)shape;
              if (shape.getUserPointer() == null)
              {
                // create a hull approximation
                ShapeHull hull = new ShapeHull(convexShape);

                // JAVA NOTE: not needed
                ///// cleanup memory
                //m_shapeHulls.push_back(hull);

                float margin = shape.getMargin();
                hull.buildHull(margin);
                convexShape.setUserPointer(hull);

                //printf("numTriangles = %d\n", hull->numTriangles ());
                //printf("numIndices = %d\n", hull->numIndices ());
                //printf("numVertices = %d\n", hull->numVertices ());
              }

              if (shape.getUserPointer() != null)
              {
                //glutSolidCube(1.0);
                ShapeHull hull = (ShapeHull)shape.getUserPointer();
               
                Vector3f normal = vectorsPool.get();
                Vector3f tmp1 = vectorsPool.get();
                Vector3f tmp2 = vectorsPool.get();

                if (hull.numTriangles () > 0)
                {
                  int index = 0;
                  IntArrayList idx = hull.getIndexPointer();
                  ObjectArrayList<Vector3f> vtx = hull.getVertexPointer();

                  gl.glBegin (gl.GL_TRIANGLES);

                  for (int i=0; i<hull.numTriangles (); i++)
                  {
                    int i1 = index++;
                    int i2 = index++;
                    int i3 = index++;
                    assert(i1 < hull.numIndices () &&
                      i2 < hull.numIndices () &&
                      i3 < hull.numIndices ());

                    int index1 = idx.get(i1);
                    int index2 = idx.get(i2);
                    int index3 = idx.get(i3);
                    assert(index1 < hull.numVertices () &&
                      index2 < hull.numVertices () &&
                      index3 < hull.numVertices ());

                    Vector3f v1 = vtx.getQuick(index1);
                    Vector3f v2 = vtx.getQuick(index2);
                    Vector3f v3 = vtx.getQuick(index3);
                    tmp1.sub(v3, v1);
                    tmp2.sub(v2, v1);
                    normal.cross(tmp1, tmp2);
                    normal.normalize();

                    gl.glNormal3f(normal.x,normal.y,normal.z);
                    gl.glVertex3f (v1.x, v1.y, v1.z);
                    gl.glVertex3f (v2.x, v2.y, v2.z);
                    gl.glVertex3f (v3.x, v3.y, v3.z);

                  }
                  gl.glEnd ();
                }
               
                vectorsPool.release(normal);
                vectorsPool.release(tmp1);
                vectorsPool.release(tmp2);
              }
            } else
            {
  //            printf("unhandled drawing\n");
            }           

          }

        }

      }

      if (useWireframeFallback) {
        // for polyhedral shapes
        if (shape.isPolyhedral()) {
          PolyhedralConvexShape polyshape = (PolyhedralConvexShape) shape;

          gl.glBegin(GL_LINES);

          Vector3f a = vectorsPool.get(), b = vectorsPool.get();
          int i;
          for (i = 0; i < polyshape.getNumEdges(); i++) {
            polyshape.getEdge(i, a, b);

            gl.glVertex3f(a.x, a.y, a.z);
            gl.glVertex3f(b.x, b.y, b.z);
          }
          gl.glEnd();
         
          vectorsPool.release(a);
          vectorsPool.release(b);

//          if (debugMode==btIDebugDraw::DBG_DrawFeaturesText)
//          {
//            glRasterPos3f(0.0,  0.0,  0.0);
//            //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),polyshape->getExtraDebugInfo());
//
//            glColor3f(1.f, 1.f, 1.f);
//            for (i=0;i<polyshape->getNumVertices();i++)
//            {
//              btPoint3 vtx;
//              polyshape->getVertex(i,vtx);
//              glRasterPos3f(vtx.x(),  vtx.y(),  vtx.z());
//              char buf[12];
//              sprintf(buf," %d",i);
//              BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
//            }
//
//            for (i=0;i<polyshape->getNumPlanes();i++)
//            {
//              btVector3 normal;
//              btPoint3 vtx;
//              polyshape->getPlane(normal,vtx,i);
//              btScalar d = vtx.dot(normal);
//
//              glRasterPos3f(normal.x()*d,  normal.y()*d, normal.z()*d);
//              char buf[12];
//              sprintf(buf," plane %d",i);
//              BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
//
//            }
//          }


        }
      }

//    #ifdef USE_DISPLAY_LISTS
//
//    if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
//      {
//        GLuint dlist =   OGL_get_displaylist_for_shape((btCollisionShape * )shape);
//        if (dlist)
//        {
//          glCallList(dlist);
//        }
//        else
//        {
//    #else   
      if (shape.isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
      //    if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
      {
        ConcaveShape concaveMesh = (ConcaveShape) shape;
        //btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
        //btVector3 aabbMax(100,100,100);//btScalar(1e30),btScalar(1e30),btScalar(1e30));

        //todo pass camera, for some culling
        Vector3f aabbMax = vectorsPool.get();
        aabbMax.set(1e30f, 1e30f, 1e30f);
        Vector3f aabbMin = vectorsPool.get();
        aabbMin.set(-1e30f, -1e30f, -1e30f);

        GlDrawcallback drawCallback = new GlDrawcallback(gl);
        drawCallback.wireframe = (debugMode & DebugDrawModes.DRAW_WIREFRAME) != 0;

        concaveMesh.processAllTriangles(drawCallback, aabbMin, aabbMax);
       
        vectorsPool.release(aabbMax);
        vectorsPool.release(aabbMin);
      }
      //#endif

      //#ifdef USE_DISPLAY_LISTS
      //    }
      //  }
      //#endif

//      if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
//      {
//        btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
//
//        //todo: pass camera for some culling     
//        btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
//        btVector3 aabbMin(-btScalar(1e30),-btScalar(1e30),-btScalar(1e30));
//        TriangleGlDrawcallback drawCallback;
//        convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
//
//      }

      // TODO: error in original sources GL_DEPTH_BUFFER_BIT instead of GL_DEPTH_TEST
      //gl.glDisable(GL_DEPTH_TEST);
      //glRasterPos3f(0, 0, 0);//mvtx.x(),  vtx.y(),  vtx.z());
      if ((debugMode & DebugDrawModes.DRAW_TEXT) != 0) {
        // TODO: BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),shape->getName());
      }

      if ((debugMode & DebugDrawModes.DRAW_FEATURES_TEXT) != 0) {
        //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),shape->getExtraDebugInfo());
      }
      //gl.glEnable(GL_DEPTH_TEST);

      //glPopMatrix();
    }
    gl.glPopMatrix();
  }
 
  ////////////////////////////////////////////////////////////////////////////
 
  private static class TriMeshKey {
    public CollisionShape shape;
    public int dlist; // OpenGL display list 
  }
 
  private static class GlDisplaylistDrawcallback extends TriangleCallback {
    private IGL gl;
   
    private final Vector3f diff1 = new Vector3f();
    private final Vector3f diff2 = new Vector3f();
    private final Vector3f normal = new Vector3f();

    public GlDisplaylistDrawcallback(IGL gl) {
      this.gl = gl;
    }
   
    public void processTriangle(Vector3f[] triangle, int partId, int triangleIndex) {
      diff1.sub(triangle[1], triangle[0]);
      diff2.sub(triangle[2], triangle[0]);
      normal.cross(diff1, diff2);

      normal.normalize();

      gl.glBegin(GL_TRIANGLES);
      gl.glColor3f(0, 1, 0);
      gl.glNormal3f(normal.x, normal.y, normal.z);
      gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);

      gl.glColor3f(0, 1, 0);
      gl.glNormal3f(normal.x, normal.y, normal.z);
      gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);

      gl.glColor3f(0, 1, 0);
      gl.glNormal3f(normal.x, normal.y, normal.z);
      gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
      gl.glEnd();

      /*glBegin(GL_LINES);
      glColor3f(1, 1, 0);
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
      glColor3f(1, 1, 0);
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
      glColor3f(1, 1, 0);
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
      glNormal3d(normal.getX(),normal.getY(),normal.getZ());
      glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
      glEnd();*/
    }
  }
 
  private static class GlDrawcallback extends TriangleCallback {
    private IGL gl;
    public boolean wireframe = false;

    public GlDrawcallback(IGL gl) {
      this.gl = gl;
    }
   
    public void processTriangle(Vector3f[] triangle, int partId, int triangleIndex) {
      if (wireframe) {
        gl.glBegin(GL_LINES);
        gl.glColor3f(1, 0, 0);
        gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);
        gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);
        gl.glColor3f(0, 1, 0);
        gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
        gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);
        gl.glColor3f(0, 0, 1);
        gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
        gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);
        gl.glEnd();
      }
      else {
        gl.glBegin(GL_TRIANGLES);
        gl.glColor3f(1, 0, 0);
        gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);
        gl.glColor3f(0, 1, 0);
        gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);
        gl.glColor3f(0, 0, 1);
        gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
        gl.glEnd();
      }
    }
  }
 
  private static class TriangleGlDrawcallback extends InternalTriangleIndexCallback {
    private IGL gl;

    public TriangleGlDrawcallback(IGL gl) {
      this.gl = gl;
    }
   
    public void internalProcessTriangleIndex(Vector3f[] triangle, int partId, int triangleIndex) {
      gl.glBegin(GL_TRIANGLES);//LINES);
      gl.glColor3f(1, 0, 0);
      gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);
      gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);
      gl.glColor3f(0, 1, 0);
      gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
      gl.glVertex3f(triangle[1].x, triangle[1].y, triangle[1].z);
      gl.glColor3f(0, 0, 1);
      gl.glVertex3f(triangle[2].x, triangle[2].y, triangle[2].z);
      gl.glVertex3f(triangle[0].x, triangle[0].y, triangle[0].z);
      gl.glEnd();
    }
  }
 
}
TOP

Related Classes of com.bulletphysics.demos.opengl.GLShapeDrawer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.