1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/**
34 * Author: Normen Hansen, CJ Hare
35 */
36#include "com_jme3_bullet_util_DebugShapeFactory.h"
37#include "jmeBulletUtil.h"
38#include "BulletCollision/CollisionShapes/btShapeHull.h"
39
40class DebugCallback : public btTriangleCallback, public btInternalTriangleIndexCallback {
41public:
42    JNIEnv* env;
43    jobject callback;
44
45    DebugCallback(JNIEnv* env, jobject object) {
46        this->env = env;
47        this->callback = object;
48    }
49
50    virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) {
51        processTriangle(triangle, partId, triangleIndex);
52    }
53
54    virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) {
55        btVector3 vertexA, vertexB, vertexC;
56        vertexA = triangle[0];
57        vertexB = triangle[1];
58        vertexC = triangle[2];
59        env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexA.getX(), vertexA.getY(), vertexA.getZ(), partId, triangleIndex);
60        if (env->ExceptionCheck()) {
61            env->Throw(env->ExceptionOccurred());
62            return;
63        }
64//        triangle =
65        env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexB.getX(), vertexB.getY(), vertexB.getZ(), partId, triangleIndex);
66        if (env->ExceptionCheck()) {
67            env->Throw(env->ExceptionOccurred());
68            return;
69        }
70        env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexC.getX(), vertexC.getY(), vertexC.getZ(), partId, triangleIndex);
71        if (env->ExceptionCheck()) {
72            env->Throw(env->ExceptionOccurred());
73            return;
74        }
75    }
76};
77
78#ifdef __cplusplus
79extern "C" {
80#endif
81
82    /* Inaccessible static: _00024assertionsDisabled */
83
84    /*
85     * Class:     com_jme3_bullet_util_DebugShapeFactory
86     * Method:    getVertices
87     * Signature: (JLcom/jme3/bullet/util/DebugMeshCallback;)V
88     */
89    JNIEXPORT void JNICALL Java_com_jme3_bullet_util_DebugShapeFactory_getVertices
90    (JNIEnv *env, jclass clazz, jlong shapeId, jobject callback) {
91        btCollisionShape* shape = reinterpret_cast<btCollisionShape*>(shapeId);
92        if (shape->isConcave()) {
93            btConcaveShape* concave = reinterpret_cast<btConcaveShape*>(shape);
94            DebugCallback* clb = new DebugCallback(env, callback);
95            btVector3 min = btVector3(-1e30, -1e30, -1e30);
96            btVector3 max = btVector3(1e30, 1e30, 1e30);
97            concave->processAllTriangles(clb, min, max);
98            delete(clb);
99        } else if (shape->isConvex()) {
100            btConvexShape* convexShape = reinterpret_cast<btConvexShape*>(shape);
101            // Check there is a hull shape to render
102            if (convexShape->getUserPointer() == NULL) {
103                // create a hull approximation
104                btShapeHull* hull = new btShapeHull(convexShape);
105                float margin = convexShape->getMargin();
106                hull->buildHull(margin);
107                convexShape->setUserPointer(hull);
108            }
109
110            btShapeHull* hull = (btShapeHull*) convexShape->getUserPointer();
111
112            int numberOfTriangles = hull->numTriangles();
113            int numberOfFloats = 3 * 3 * numberOfTriangles;
114            int byteBufferSize = numberOfFloats * 4;
115
116            // Loop variables
117            const unsigned int* hullIndices = hull->getIndexPointer();
118            const btVector3* hullVertices = hull->getVertexPointer();
119            btVector3 vertexA, vertexB, vertexC;
120            int index = 0;
121
122            for (int i = 0; i < numberOfTriangles; i++) {
123                // Grab the data for this triangle from the hull
124                vertexA = hullVertices[hullIndices[index++]];
125                vertexB = hullVertices[hullIndices[index++]];
126                vertexC = hullVertices[hullIndices[index++]];
127
128                // Put the verticies into the vertex buffer
129                env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexA.getX(), vertexA.getY(), vertexA.getZ());
130                if (env->ExceptionCheck()) {
131                    env->Throw(env->ExceptionOccurred());
132                    return;
133                }
134                env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexB.getX(), vertexB.getY(), vertexB.getZ());
135                if (env->ExceptionCheck()) {
136                    env->Throw(env->ExceptionOccurred());
137                    return;
138                }
139                env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexC.getX(), vertexC.getY(), vertexC.getZ());
140                if (env->ExceptionCheck()) {
141                    env->Throw(env->ExceptionOccurred());
142                    return;
143                }
144            }
145            delete hull;
146            convexShape->setUserPointer(NULL);
147        }
148    }
149
150#ifdef __cplusplus
151}
152#endif
153