• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.jme3.bullet.util;
33 
34 import com.bulletphysics.collision.shapes.IndexedMesh;
35 import com.bulletphysics.dom.HeightfieldTerrainShape;
36 import com.jme3.math.FastMath;
37 import com.jme3.scene.Mesh;
38 import com.jme3.scene.VertexBuffer.Type;
39 import com.jme3.scene.mesh.IndexBuffer;
40 import com.jme3.util.BufferUtils;
41 import java.nio.ByteBuffer;
42 import java.nio.FloatBuffer;
43 
44 /**
45  * Nice convenience methods for conversion between javax.vecmath and com.jme3.math
46  * Objects, also some jme to jbullet mesh conversion.
47  * @author normenhansen
48  */
49 public class Converter {
50 
Converter()51     private Converter() {
52     }
53 
convert(javax.vecmath.Vector3f oldVec)54     public static com.jme3.math.Vector3f convert(javax.vecmath.Vector3f oldVec) {
55         com.jme3.math.Vector3f newVec = new com.jme3.math.Vector3f();
56         convert(oldVec, newVec);
57         return newVec;
58     }
59 
convert(javax.vecmath.Vector3f oldVec, com.jme3.math.Vector3f newVec)60     public static com.jme3.math.Vector3f convert(javax.vecmath.Vector3f oldVec, com.jme3.math.Vector3f newVec) {
61         newVec.x = oldVec.x;
62         newVec.y = oldVec.y;
63         newVec.z = oldVec.z;
64         return newVec;
65     }
66 
convert(com.jme3.math.Vector3f oldVec)67     public static javax.vecmath.Vector3f convert(com.jme3.math.Vector3f oldVec) {
68         javax.vecmath.Vector3f newVec = new javax.vecmath.Vector3f();
69         convert(oldVec, newVec);
70         return newVec;
71     }
72 
convert(com.jme3.math.Vector3f oldVec, javax.vecmath.Vector3f newVec)73     public static javax.vecmath.Vector3f convert(com.jme3.math.Vector3f oldVec, javax.vecmath.Vector3f newVec) {
74         newVec.x = oldVec.x;
75         newVec.y = oldVec.y;
76         newVec.z = oldVec.z;
77         return newVec;
78     }
79 
convert(com.jme3.math.Quaternion oldQuat, javax.vecmath.Quat4f newQuat)80     public static javax.vecmath.Quat4f convert(com.jme3.math.Quaternion oldQuat, javax.vecmath.Quat4f newQuat) {
81         newQuat.w = oldQuat.getW();
82         newQuat.x = oldQuat.getX();
83         newQuat.y = oldQuat.getY();
84         newQuat.z = oldQuat.getZ();
85         return newQuat;
86     }
87 
convert(com.jme3.math.Quaternion oldQuat)88     public static javax.vecmath.Quat4f convert(com.jme3.math.Quaternion oldQuat) {
89         javax.vecmath.Quat4f newQuat = new javax.vecmath.Quat4f();
90         convert(oldQuat, newQuat);
91         return newQuat;
92     }
93 
convert(javax.vecmath.Quat4f oldQuat, com.jme3.math.Quaternion newQuat)94     public static com.jme3.math.Quaternion convert(javax.vecmath.Quat4f oldQuat, com.jme3.math.Quaternion newQuat) {
95         newQuat.set(oldQuat.x, oldQuat.y, oldQuat.z, oldQuat.w);
96         return newQuat;
97     }
98 
convert(javax.vecmath.Quat4f oldQuat)99     public static com.jme3.math.Quaternion convert(javax.vecmath.Quat4f oldQuat) {
100         com.jme3.math.Quaternion newQuat = new com.jme3.math.Quaternion();
101         convert(oldQuat, newQuat);
102         return newQuat;
103     }
104 
convert(javax.vecmath.Matrix3f oldMatrix, com.jme3.math.Quaternion newQuaternion)105     public static com.jme3.math.Quaternion convert(javax.vecmath.Matrix3f oldMatrix, com.jme3.math.Quaternion newQuaternion) {
106         // the trace is the sum of the diagonal elements; see
107         // http://mathworld.wolfram.com/MatrixTrace.html
108         float t = oldMatrix.m00 + oldMatrix.m11 + oldMatrix.m22;
109         float w, x, y, z;
110         // we protect the division by s by ensuring that s>=1
111         if (t >= 0) { // |w| >= .5
112             float s = FastMath.sqrt(t + 1); // |s|>=1 ...
113             w = 0.5f * s;
114             s = 0.5f / s;                 // so this division isn't bad
115             x = (oldMatrix.m21 - oldMatrix.m12) * s;
116             y = (oldMatrix.m02 - oldMatrix.m20) * s;
117             z = (oldMatrix.m10 - oldMatrix.m01) * s;
118         } else if ((oldMatrix.m00 > oldMatrix.m11) && (oldMatrix.m00 > oldMatrix.m22)) {
119             float s = FastMath.sqrt(1.0f + oldMatrix.m00 - oldMatrix.m11 - oldMatrix.m22); // |s|>=1
120             x = s * 0.5f; // |x| >= .5
121             s = 0.5f / s;
122             y = (oldMatrix.m10 + oldMatrix.m01) * s;
123             z = (oldMatrix.m02 + oldMatrix.m20) * s;
124             w = (oldMatrix.m21 - oldMatrix.m12) * s;
125         } else if (oldMatrix.m11 > oldMatrix.m22) {
126             float s = FastMath.sqrt(1.0f + oldMatrix.m11 - oldMatrix.m00 - oldMatrix.m22); // |s|>=1
127             y = s * 0.5f; // |y| >= .5
128             s = 0.5f / s;
129             x = (oldMatrix.m10 + oldMatrix.m01) * s;
130             z = (oldMatrix.m21 + oldMatrix.m12) * s;
131             w = (oldMatrix.m02 - oldMatrix.m20) * s;
132         } else {
133             float s = FastMath.sqrt(1.0f + oldMatrix.m22 - oldMatrix.m00 - oldMatrix.m11); // |s|>=1
134             z = s * 0.5f; // |z| >= .5
135             s = 0.5f / s;
136             x = (oldMatrix.m02 + oldMatrix.m20) * s;
137             y = (oldMatrix.m21 + oldMatrix.m12) * s;
138             w = (oldMatrix.m10 - oldMatrix.m01) * s;
139         }
140         return newQuaternion.set(x, y, z, w);
141     }
142 
convert(com.jme3.math.Quaternion oldQuaternion, javax.vecmath.Matrix3f newMatrix)143     public static javax.vecmath.Matrix3f convert(com.jme3.math.Quaternion oldQuaternion, javax.vecmath.Matrix3f newMatrix) {
144         float norm = oldQuaternion.getW() * oldQuaternion.getW() + oldQuaternion.getX() * oldQuaternion.getX() + oldQuaternion.getY() * oldQuaternion.getY() + oldQuaternion.getZ() * oldQuaternion.getZ();
145         float s = (norm == 1f) ? 2f : (norm > 0f) ? 2f / norm : 0;
146 
147         // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs
148         // will be used 2-4 times each.
149         float xs = oldQuaternion.getX() * s;
150         float ys = oldQuaternion.getY() * s;
151         float zs = oldQuaternion.getZ() * s;
152         float xx = oldQuaternion.getX() * xs;
153         float xy = oldQuaternion.getX() * ys;
154         float xz = oldQuaternion.getX() * zs;
155         float xw = oldQuaternion.getW() * xs;
156         float yy = oldQuaternion.getY() * ys;
157         float yz = oldQuaternion.getY() * zs;
158         float yw = oldQuaternion.getW() * ys;
159         float zz = oldQuaternion.getZ() * zs;
160         float zw = oldQuaternion.getW() * zs;
161 
162         // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here
163         newMatrix.m00 = 1 - (yy + zz);
164         newMatrix.m01 = (xy - zw);
165         newMatrix.m02 = (xz + yw);
166         newMatrix.m10 = (xy + zw);
167         newMatrix.m11 = 1 - (xx + zz);
168         newMatrix.m12 = (yz - xw);
169         newMatrix.m20 = (xz - yw);
170         newMatrix.m21 = (yz + xw);
171         newMatrix.m22 = 1 - (xx + yy);
172 
173         return newMatrix;
174     }
175 
convert(javax.vecmath.Matrix3f oldMatrix)176     public static com.jme3.math.Matrix3f convert(javax.vecmath.Matrix3f oldMatrix) {
177         com.jme3.math.Matrix3f newMatrix = new com.jme3.math.Matrix3f();
178         convert(oldMatrix, newMatrix);
179         return newMatrix;
180     }
181 
convert(javax.vecmath.Matrix3f oldMatrix, com.jme3.math.Matrix3f newMatrix)182     public static com.jme3.math.Matrix3f convert(javax.vecmath.Matrix3f oldMatrix, com.jme3.math.Matrix3f newMatrix) {
183         newMatrix.set(0, 0, oldMatrix.m00);
184         newMatrix.set(0, 1, oldMatrix.m01);
185         newMatrix.set(0, 2, oldMatrix.m02);
186         newMatrix.set(1, 0, oldMatrix.m10);
187         newMatrix.set(1, 1, oldMatrix.m11);
188         newMatrix.set(1, 2, oldMatrix.m12);
189         newMatrix.set(2, 0, oldMatrix.m20);
190         newMatrix.set(2, 1, oldMatrix.m21);
191         newMatrix.set(2, 2, oldMatrix.m22);
192         return newMatrix;
193     }
194 
convert(com.jme3.math.Matrix3f oldMatrix)195     public static javax.vecmath.Matrix3f convert(com.jme3.math.Matrix3f oldMatrix) {
196         javax.vecmath.Matrix3f newMatrix = new javax.vecmath.Matrix3f();
197         convert(oldMatrix, newMatrix);
198         return newMatrix;
199     }
200 
convert(com.jme3.math.Matrix3f oldMatrix, javax.vecmath.Matrix3f newMatrix)201     public static javax.vecmath.Matrix3f convert(com.jme3.math.Matrix3f oldMatrix, javax.vecmath.Matrix3f newMatrix) {
202         newMatrix.m00 = oldMatrix.get(0, 0);
203         newMatrix.m01 = oldMatrix.get(0, 1);
204         newMatrix.m02 = oldMatrix.get(0, 2);
205         newMatrix.m10 = oldMatrix.get(1, 0);
206         newMatrix.m11 = oldMatrix.get(1, 1);
207         newMatrix.m12 = oldMatrix.get(1, 2);
208         newMatrix.m20 = oldMatrix.get(2, 0);
209         newMatrix.m21 = oldMatrix.get(2, 1);
210         newMatrix.m22 = oldMatrix.get(2, 2);
211         return newMatrix;
212     }
213 
convert(com.jme3.math.Transform in, com.bulletphysics.linearmath.Transform out)214     public static com.bulletphysics.linearmath.Transform convert(com.jme3.math.Transform in, com.bulletphysics.linearmath.Transform out) {
215         convert(in.getTranslation(), out.origin);
216         convert(in.getRotation(), out.basis);
217         return out;
218     }
219 
convert(com.bulletphysics.linearmath.Transform in, com.jme3.math.Transform out)220     public static com.jme3.math.Transform convert(com.bulletphysics.linearmath.Transform in,  com.jme3.math.Transform out) {
221         convert(in.origin, out.getTranslation());
222         convert(in.basis, out.getRotation());
223         return out;
224     }
225 
convert(Mesh mesh)226     public static IndexedMesh convert(Mesh mesh) {
227         IndexedMesh jBulletIndexedMesh = new IndexedMesh();
228         jBulletIndexedMesh.triangleIndexBase = ByteBuffer.allocate(mesh.getTriangleCount() * 3 * 4);
229         jBulletIndexedMesh.vertexBase = ByteBuffer.allocate(mesh.getVertexCount() * 3 * 4);
230 
231         IndexBuffer indices = mesh.getIndicesAsList();
232 
233         FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
234         vertices.rewind();
235 
236         int verticesLength = mesh.getVertexCount() * 3;
237         jBulletIndexedMesh.numVertices = mesh.getVertexCount();
238         jBulletIndexedMesh.vertexStride = 12; //3 verts * 4 bytes per.
239         for (int i = 0; i < verticesLength; i++) {
240             float tempFloat = vertices.get();
241             jBulletIndexedMesh.vertexBase.putFloat(tempFloat);
242         }
243 
244         int indicesLength = mesh.getTriangleCount() * 3;
245         jBulletIndexedMesh.numTriangles = mesh.getTriangleCount();
246         jBulletIndexedMesh.triangleIndexStride = 12; //3 index entries * 4 bytes each.
247         for (int i = 0; i < indicesLength; i++) {
248             jBulletIndexedMesh.triangleIndexBase.putInt(indices.get(i));
249         }
250         vertices.rewind();
251         vertices.clear();
252 
253         return jBulletIndexedMesh;
254     }
255 
convert(IndexedMesh mesh)256     public static Mesh convert(IndexedMesh mesh) {
257         Mesh jmeMesh = new Mesh();
258 
259         jmeMesh.setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(mesh.numTriangles * 3));
260         jmeMesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(mesh.numVertices * 3));
261 
262         IndexBuffer indicess = jmeMesh.getIndexBuffer();
263         FloatBuffer vertices = jmeMesh.getFloatBuffer(Type.Position);
264 
265         for (int i = 0; i < mesh.numTriangles * 3; i++) {
266             indicess.put(i, mesh.triangleIndexBase.getInt(i * 4));
267         }
268 
269         for (int i = 0; i < mesh.numVertices * 3; i++) {
270             vertices.put(i, mesh.vertexBase.getFloat(i * 4));
271         }
272         jmeMesh.updateCounts();
273         jmeMesh.updateBound();
274         jmeMesh.getFloatBuffer(Type.Position).clear();
275 
276         return jmeMesh;
277     }
278 
convert(HeightfieldTerrainShape heightfieldShape)279     public static Mesh convert(HeightfieldTerrainShape heightfieldShape) {
280         return null; //TODO!!
281     }
282 }
283