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
35 */
36
37#include "com_jme3_bullet_objects_PhysicsCharacter.h"
38#include "jmeBulletUtil.h"
39#include "BulletCollision/CollisionDispatch/btGhostObject.h"
40#include "BulletDynamics/Character/btKinematicCharacterController.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46    /*
47     * Class:     com_jme3_bullet_objects_PhysicsCharacter
48     * Method:    createGhostObject
49     * Signature: ()J
50     */
51    JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createGhostObject
52    (JNIEnv * env, jobject object) {
53        jmeClasses::initJavaClasses(env);
54        btPairCachingGhostObject* ghost = new btPairCachingGhostObject();
55        return reinterpret_cast<jlong>(ghost);
56    }
57
58    /*
59     * Class:     com_jme3_bullet_objects_PhysicsCharacter
60     * Method:    setCharacterFlags
61     * Signature: (J)V
62     */
63    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCharacterFlags
64    (JNIEnv *env, jobject object, jlong ghostId) {
65        btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(ghostId);
66        if (ghost == NULL) {
67            jclass newExc = env->FindClass("java/lang/NullPointerException");
68            env->ThrowNew(newExc, "The native object does not exist.");
69            return;
70        }
71        ghost->setCollisionFlags(/*ghost->getCollisionFlags() |*/ btCollisionObject::CF_CHARACTER_OBJECT);
72        ghost->setCollisionFlags(ghost->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
73    }
74
75    /*
76     * Class:     com_jme3_bullet_objects_PhysicsCharacter
77     * Method:    createCharacterObject
78     * Signature: (JJF)J
79     */
80    JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createCharacterObject
81    (JNIEnv *env, jobject object, jlong objectId, jlong shapeId, jfloat stepHeight) {
82        btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
83        if (ghost == NULL) {
84            jclass newExc = env->FindClass("java/lang/NullPointerException");
85            env->ThrowNew(newExc, "The native object does not exist.");
86            return 0;
87        }
88        //TODO: check convexshape!
89        btConvexShape* shape = reinterpret_cast<btConvexShape*>(shapeId);
90        btKinematicCharacterController* character = new btKinematicCharacterController(ghost, shape, stepHeight);
91        return reinterpret_cast<jlong>(character);
92    }
93
94    /*
95     * Class:     com_jme3_bullet_objects_PhysicsCharacter
96     * Method:    warp
97     * Signature: (JLcom/jme3/math/Vector3f;)V
98     */
99    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_warp
100    (JNIEnv *env, jobject object, jlong objectId, jobject vector) {
101        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
102        if (character == NULL) {
103            jclass newExc = env->FindClass("java/lang/NullPointerException");
104            env->ThrowNew(newExc, "The native object does not exist.");
105            return;
106        }
107        btVector3 vec = btVector3();
108        jmeBulletUtil::convert(env, vector, &vec);
109        character->warp(vec);
110    }
111
112    /*
113     * Class:     com_jme3_bullet_objects_PhysicsCharacter
114     * Method:    setWalkDirection
115     * Signature: (JLcom/jme3/math/Vector3f;)V
116     */
117    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setWalkDirection
118    (JNIEnv *env, jobject object, jlong objectId, jobject vector) {
119        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
120        if (character == NULL) {
121            jclass newExc = env->FindClass("java/lang/NullPointerException");
122            env->ThrowNew(newExc, "The native object does not exist.");
123            return;
124        }
125        btVector3 vec = btVector3();
126        jmeBulletUtil::convert(env, vector, &vec);
127        character->setWalkDirection(vec);
128    }
129
130    /*
131     * Class:     com_jme3_bullet_objects_PhysicsCharacter
132     * Method:    setUpAxis
133     * Signature: (JI)V
134     */
135    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setUpAxis
136    (JNIEnv *env, jobject object, jlong objectId, jint value) {
137        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
138        if (character == NULL) {
139            jclass newExc = env->FindClass("java/lang/NullPointerException");
140            env->ThrowNew(newExc, "The native object does not exist.");
141            return;
142        }
143        character->setUpAxis(value);
144    }
145
146    /*
147     * Class:     com_jme3_bullet_objects_PhysicsCharacter
148     * Method:    setFallSpeed
149     * Signature: (JF)V
150     */
151    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setFallSpeed
152    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
153        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
154        if (character == NULL) {
155            jclass newExc = env->FindClass("java/lang/NullPointerException");
156            env->ThrowNew(newExc, "The native object does not exist.");
157            return;
158        }
159        character->setFallSpeed(value);
160    }
161
162    /*
163     * Class:     com_jme3_bullet_objects_PhysicsCharacter
164     * Method:    setJumpSpeed
165     * Signature: (JF)V
166     */
167    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setJumpSpeed
168    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
169        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
170        if (character == NULL) {
171            jclass newExc = env->FindClass("java/lang/NullPointerException");
172            env->ThrowNew(newExc, "The native object does not exist.");
173            return;
174        }
175        character->setJumpSpeed(value);
176    }
177
178    /*
179     * Class:     com_jme3_bullet_objects_PhysicsCharacter
180     * Method:    setGravity
181     * Signature: (JF)V
182     */
183    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setGravity
184    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
185        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
186        if (character == NULL) {
187            jclass newExc = env->FindClass("java/lang/NullPointerException");
188            env->ThrowNew(newExc, "The native object does not exist.");
189            return;
190        }
191        character->setGravity(value);
192    }
193
194    /*
195     * Class:     com_jme3_bullet_objects_PhysicsCharacter
196     * Method:    getGravity
197     * Signature: (J)F
198     */
199    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getGravity
200    (JNIEnv *env, jobject object, jlong objectId) {
201        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
202        if (character == NULL) {
203            jclass newExc = env->FindClass("java/lang/NullPointerException");
204            env->ThrowNew(newExc, "The native object does not exist.");
205            return 0;
206        }
207        return character->getGravity();
208    }
209
210    /*
211     * Class:     com_jme3_bullet_objects_PhysicsCharacter
212     * Method:    setMaxSlope
213     * Signature: (JF)V
214     */
215    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setMaxSlope
216    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
217        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
218        if (character == NULL) {
219            jclass newExc = env->FindClass("java/lang/NullPointerException");
220            env->ThrowNew(newExc, "The native object does not exist.");
221            return;
222        }
223        character->setMaxSlope(value);
224    }
225
226    /*
227     * Class:     com_jme3_bullet_objects_PhysicsCharacter
228     * Method:    getMaxSlope
229     * Signature: (J)F
230     */
231    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getMaxSlope
232    (JNIEnv *env, jobject object, jlong objectId) {
233        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
234        if (character == NULL) {
235            jclass newExc = env->FindClass("java/lang/NullPointerException");
236            env->ThrowNew(newExc, "The native object does not exist.");
237            return 0;
238        }
239        return character->getMaxSlope();
240    }
241
242    /*
243     * Class:     com_jme3_bullet_objects_PhysicsCharacter
244     * Method:    onGround
245     * Signature: (J)Z
246     */
247    JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_onGround
248    (JNIEnv *env, jobject object, jlong objectId) {
249        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
250        if (character == NULL) {
251            jclass newExc = env->FindClass("java/lang/NullPointerException");
252            env->ThrowNew(newExc, "The native object does not exist.");
253            return false;
254        }
255        return character->onGround();
256    }
257
258    /*
259     * Class:     com_jme3_bullet_objects_PhysicsCharacter
260     * Method:    jump
261     * Signature: (J)V
262     */
263    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_jump
264    (JNIEnv *env, jobject object, jlong objectId) {
265        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
266        if (character == NULL) {
267            jclass newExc = env->FindClass("java/lang/NullPointerException");
268            env->ThrowNew(newExc, "The native object does not exist.");
269            return;
270        }
271        character->jump();
272    }
273
274    /*
275     * Class:     com_jme3_bullet_objects_PhysicsCharacter
276     * Method:    getPhysicsLocation
277     * Signature: (JLcom/jme3/math/Vector3f;)V
278     */
279    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getPhysicsLocation
280    (JNIEnv *env, jobject object, jlong objectId, jobject value) {
281        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
282        if (ghost == NULL) {
283            jclass newExc = env->FindClass("java/lang/NullPointerException");
284            env->ThrowNew(newExc, "The native object does not exist.");
285            return;
286        }
287        jmeBulletUtil::convert(env, &ghost->getWorldTransform().getOrigin(), value);
288    }
289
290    /*
291     * Class:     com_jme3_bullet_objects_PhysicsCharacter
292     * Method:    setCcdSweptSphereRadius
293     * Signature: (JF)V
294     */
295    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdSweptSphereRadius
296    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
297        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
298        if (ghost == NULL) {
299            jclass newExc = env->FindClass("java/lang/NullPointerException");
300            env->ThrowNew(newExc, "The native object does not exist.");
301            return;
302        }
303        ghost->setCcdSweptSphereRadius(value);
304    }
305
306    /*
307     * Class:     com_jme3_bullet_objects_PhysicsCharacter
308     * Method:    setCcdMotionThreshold
309     * Signature: (JF)V
310     */
311    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdMotionThreshold
312    (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
313        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
314        if (ghost == NULL) {
315            jclass newExc = env->FindClass("java/lang/NullPointerException");
316            env->ThrowNew(newExc, "The native object does not exist.");
317            return;
318        }
319        ghost->setCcdMotionThreshold(value);
320    }
321
322    /*
323     * Class:     com_jme3_bullet_objects_PhysicsCharacter
324     * Method:    getCcdSweptSphereRadius
325     * Signature: (J)F
326     */
327    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSweptSphereRadius
328    (JNIEnv *env, jobject object, jlong objectId) {
329        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
330        if (ghost == NULL) {
331            jclass newExc = env->FindClass("java/lang/NullPointerException");
332            env->ThrowNew(newExc, "The native object does not exist.");
333            return 0;
334        }
335        return ghost->getCcdSweptSphereRadius();
336    }
337
338    /*
339     * Class:     com_jme3_bullet_objects_PhysicsCharacter
340     * Method:    getCcdMotionThreshold
341     * Signature: (J)F
342     */
343    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdMotionThreshold
344    (JNIEnv *env, jobject object, jlong objectId) {
345        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
346        if (ghost == NULL) {
347            jclass newExc = env->FindClass("java/lang/NullPointerException");
348            env->ThrowNew(newExc, "The native object does not exist.");
349            return 0;
350        }
351        return ghost->getCcdMotionThreshold();
352    }
353
354    /*
355     * Class:     com_jme3_bullet_objects_PhysicsCharacter
356     * Method:    getCcdSquareMotionThreshold
357     * Signature: (J)F
358     */
359    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSquareMotionThreshold
360    (JNIEnv *env, jobject object, jlong objectId) {
361        btGhostObject* ghost = reinterpret_cast<btGhostObject*>(objectId);
362        if (ghost == NULL) {
363            jclass newExc = env->FindClass("java/lang/NullPointerException");
364            env->ThrowNew(newExc, "The native object does not exist.");
365            return 0;
366        }
367        return ghost->getCcdSquareMotionThreshold();
368    }
369
370    /*
371     * Class:     com_jme3_bullet_objects_PhysicsCharacter
372     * Method:    finalizeNativeCharacter
373     * Signature: (J)V
374     */
375    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_finalizeNativeCharacter
376    (JNIEnv *env, jobject object, jlong objectId) {
377        btKinematicCharacterController* character = reinterpret_cast<btKinematicCharacterController*>(objectId);
378        if (character == NULL) {
379            jclass newExc = env->FindClass("java/lang/NullPointerException");
380            env->ThrowNew(newExc, "The native object does not exist.");
381            return;
382        }
383        delete(character);
384    }
385
386#ifdef __cplusplus
387}
388#endif
389