My favorites
▼
|
Sign in
vlengine
Java 3D game engine
Project Home
Source
Checkout
Browse
Changes
Source path:
svn
/
trunk
/
vle_cleanup
/
src
/
com
/
vlengine
/
scene
/
animation
/
x
/
XSoftSkinner.java
‹r3
r8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
* Copyright (c) 2008 VL Engine
* 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 'VL Engine' 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.
*/
package com.vlengine.scene.animation.x;
import com.vlengine.bounding.BoundingVolume;
import com.vlengine.bounding.CollisionVolume;
import com.vlengine.math.Matrix4f;
import com.vlengine.math.Vector3f;
import com.vlengine.model.Geometry;
import com.vlengine.model.XWeightedGeometry;
import com.vlengine.renderer.RenderContext;
import com.vlengine.scene.Renderable;
import com.vlengine.util.FastList;
import com.vlengine.util.IntList;
import com.vlengine.util.geom.VertexAttribute;
import com.vlengine.util.geom.VertexBuffer;
import com.vlengine.util.geom.VertexFormat;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
/**
* Class that perform software skinning on a single batch
* @author vear (Arpad Vekas)
*/
public class XSoftSkinner extends Geometry implements XAnimatedItem {
// the geometry has to have all the attributes in different
// buffers
protected XWeightedGeometry model;
// the current transformation matrices for the bones
protected Matrix4f[] boneMats;
protected boolean needsRefresh = true;
ByteBuffer mappedBuffer = null;
public void setMatrixValues(Matrix4f[] origBoneMats) {
IntList boneMapping = model.getBoneMapping();
if(boneMats == null || boneMats.length != boneMapping.size()) {
boneMats = new Matrix4f[boneMapping.size()];
for(int i=0; i<boneMats.length; i++) {
boneMats[i] = new Matrix4f();
}
}
for(int l=0, ml=boneMapping.size(); l<ml; l++) {
// the bone-s mapped id for this animated item
int origBone = boneMapping.get(l);
//if(origBone!=0) {
// TODO: just for testing
//skinTransforms[origBone].loadIdentity();
// if this bone is actualy required in the item
boneMats[l].set(origBoneMats[origBone]);
boneMats[l].transposeLocal();
//}
}
needsRefresh = true;
}
public IntList getBoneMapping() {
return model.getBoneMapping();
}
public XWeightedGeometry getModel() {
return model;
}
public void setModel(XWeightedGeometry model) {
this.model = model;
// copy over stuff from the model
// we need to transfer everything from the XWeightedGeometry, and need to create
// an empty position VBO, with no VBO
// go over the buffers of the model
// TODO: this way of copying is not working if the attributes are interleaved!
FastList<VertexAttribute> attribs = model.getAllAttributes(null);
for(int i=0; i<attribs.size(); i++) {
VertexAttribute va = attribs.get(i);
if(va.type != VertexAttribute.USAGE_POSITION
&& va.type != VertexAttribute.USAGE_WEIGHTINDICES
&& va.type != VertexAttribute.USAGE_WEIGHTS
&& va.type != VertexAttribute.USAGE_NUMWEIGHTS
&& va.type != VertexAttribute.USAGE_NORMAL
) {
VertexBuffer vbm = model.getAttribBuffer(va.type);
// add the buffer as ours
this.addAttribBuffer(vbm, model.getStartVertex(va.type));
}
}
// copy over the index buffer from the model too
this.setIndexBuffer(model.getIndexBuffer());
this.setStartIndex(model.getStartIndex());
this.setNumIndex(model.getNumIndex());
}
/**
* Setup this skinner, this will require access to a render context,
* since it is doing VBO mapping
*/
protected void mapBuffers(RenderContext ctx) {
// get the VBO id
VertexBuffer vb = this.getAttribBuffer(VertexAttribute.USAGE_POSITION);
VertexBuffer nb = this.getAttribBuffer(VertexAttribute.USAGE_NORMAL);
if(vb==null) {
// create vertex buffer for position data, and map it
// TODO: this should be done in two steps, using deferredloader
vb = ctx.getRenderer().allocVertexBuffer(
VertexFormat.getDefaultFormat(VertexFormat.setRequested(0, VertexAttribute.USAGE_POSITION))
, model.getNumVertex(), null);
this.addAttribBuffer(vb, 0);
// create vertex buffer for normal data
nb = ctx.getRenderer().allocVertexBuffer(
VertexFormat.getDefaultFormat(VertexFormat.setRequested(0, VertexAttribute.USAGE_NORMAL))
, model.getNumVertex(), null);
this.addAttribBuffer(nb, 0);
}
// map the ogl memory
// TODO: in multithreading environment we need to maintain two sets of the buffer
// switching to new one with each update
ctx.getRenderer().mapVertexBuffer(vb);
ctx.getRenderer().mapVertexBuffer(nb);
}
protected void unMapBuffers(RenderContext ctx) {
VertexBuffer vb = this.getAttribBuffer(VertexAttribute.USAGE_POSITION);
VertexBuffer nb = this.getAttribBuffer(VertexAttribute.USAGE_NORMAL);
ctx.getRenderer().unMapVertexBuffer(vb);
ctx.getRenderer().unMapVertexBuffer(nb);
}
public void skinMesh() {
// get hte position buffer
FloatBuffer pb = model.getAttribBuffer(VertexAttribute.USAGE_POSITION).getDataBuffer();
pb.rewind();
// get the normal buffer
FloatBuffer nb = model.getAttribBuffer(VertexAttribute.USAGE_NORMAL).getDataBuffer();
nb.rewind();
// TODO: this may need to be reworked to vertexiterators
// get matrix weights
FloatBuffer wb = model.getAttribBuffer(VertexAttribute.USAGE_WEIGHTS).getDataBuffer();
wb.rewind();
// get matrix indices
FloatBuffer ib = model.getAttribBuffer(VertexAttribute.USAGE_WEIGHTINDICES).getDataBuffer();
ib.rewind();
// get num indices
FloatBuffer inb = model.getAttribBuffer(VertexAttribute.USAGE_NUMWEIGHTS).getDataBuffer();
inb.rewind();
// get the target position buffer
FloatBuffer tpb = getAttribBuffer(VertexAttribute.USAGE_POSITION).getDataBuffer();
tpb.rewind();
// get the target normal buffer
FloatBuffer tnb = getAttribBuffer(VertexAttribute.USAGE_NORMAL).getDataBuffer();
tnb.rewind();
// source vectors
Vector3f sPosition = new Vector3f();
Vector3f sNormal = new Vector3f();
// matrix weights
float[] matWeights = new float[4];
Vector3f tvec = new Vector3f();
// target vectors
Vector3f tPosition = new Vector3f();
Vector3f tNormal = new Vector3f();
// go over every vertex
for(int i=0, mi=this.getNumVertex(); i<mi; i++) {
// rerieve source vectors
sPosition.x = pb.get(); sPosition.y = pb.get(); sPosition.z = pb.get();
sNormal.x = nb.get(); sNormal.y = nb.get(); sNormal.z = nb.get();
// number of indices
int numIndex = Float.floatToIntBits(inb.get(i)) & 0xff;
// the matrix indices
int matIndex = Float.floatToIntBits(ib.get(i));
// the matrix weights
wb.position(i*4);
wb.get(matWeights);
// clear vectors holding result values
tPosition.set(0,0,0);
tNormal.set(0, 0, 0);
// go over each of the weights
for(int j=0; j<numIndex; j++) {
// get the matrix index
int mati = matIndex & 0xff;
// shift the index
matIndex = matIndex >> 8;
// fetch the matrix
Matrix4f mat = boneMats[mati];
// transform position
tvec.set(sPosition);
mat.mult(tvec, tvec);
// scale the vector by weight
tvec.scale(matWeights[j]);
// sum up into final position
tPosition.addLocal(tvec);
// rotate normal
tvec.set(sNormal);
mat.rotateVect(tvec);
tvec.scale(matWeights[j]);
tNormal.addLocal(tvec);
}
//tPosition.set(sPosition);
//tNormal.set(sNormal);
// we got the final position and normal, put them into the buffers
tpb.put(tPosition.x).put(tPosition.y).put(tPosition.z);
tnb.put(tNormal.x).put(tNormal.y).put(tNormal.z);
}
// rewind the buffers
pb.rewind();
nb.rewind();
wb.rewind();
ib.rewind();
inb.rewind();
tpb.rewind();
tnb.rewind();
}
@Override
public boolean preDraw(RenderContext ctx, Renderable r) {
// if the mesh needs to be updated, update it
if(needsRefresh) {
// allocate ogl memory if its not yet allocated
// map the buffer to java memory too
mapBuffers(ctx);
// do the actual skinning (generate vertices)
skinMesh();
// release the buffers, so OGL can use them during rendering
unMapBuffers(ctx);
// map a buffer from OpenGL
needsRefresh = false;
}
return true;
}
@Override
public void createCollisionVolume(Vector3f cellSize) {
CollisionVolume cvm = model.getCollisionVolume();
if(cvm!=null && cvm.getCellSize().equals(cellSize)) {
this.collisionVolume = cvm;
return;
}
collisionVolume = new CollisionVolume();
collisionVolume.buildVolume(model, cellSize);
}
@Override
public BoundingVolume getModelBound() {
return model.getModelBound();
}
}
Show details
Hide details
Change log
r8
by ve...@freemail.hu on Oct 15, 2008
Diff
Comment fixes
Go to:
...com/vlengine/app/AppContext.java
.../vlengine/awt/AWTMouseInput.java
...vlengine/awt/CanvasMainGame.java
.../com/vlengine/awt/VLECanvas.java
...ine/bounding/BoundingSphere.java
...ine/bounding/BoundingVolume.java
...gine/bounding/CollisionTree.java
...ne/bounding/CollisionVolume.java
...vlengine/image/BitmapHeader.java
...rc/com/vlengine/image/Image.java
...engine/image/util/TGALoader.java
...vlengine/input/InputHandler.java
...lengine/input/InputListener.java
.../vlengine/input/InputSystem.java
...lengine/input/KeyBindingSet.java
...com/vlengine/input/KeyInput.java
...m/vlengine/input/MouseInput.java
.../intersection/CollisionData.java
...ne/intersection/PickResults.java
.../light/LightShadowGameState.java
.../vlengine/light/LightSorter.java
.../vlengine/light/ShadowUtils.java
.../com/vlengine/math/Matrix4f.java
...src/com/vlengine/math/Plane.java
...ngine/resource/FileResource.java
...ne/resource/ResourceCreator.java
...ine/resource/ResourceFinder.java
...ine/resource/ResourceFolder.java
...lengine/resource/TextureKey.java
...gine/resource/TextureReader.java
.../resource/md5/Md5AnimLoader.java
...engine/resource/model/Model.java
...esource/model/ModelMaterial.java
...ne/resource/model/ModelPack.java
...urce/model/ModelPackCreator.java
...esource/model/ModelPartPack.java
...ngine/resource/obj/ArraySet.java
...ngine/resource/obj/IndexSet.java
...gine/resource/obj/ObjLoader.java
...ngine/resource/obj/ObjModel.java
...gine/resource/obj/ObjMtlLib.java
...lengine/resource/obj/Tokens.java
...ource/util/TangentGenerator.java
...ngine/scene/AnalyticSkyDome.java
...m/vlengine/scene/CameraNode.java
...om/vlengine/scene/LightNode.java
.../com/vlengine/scene/LodMesh.java
...src/com/vlengine/scene/Mesh.java
...src/com/vlengine/scene/Node.java
...c/com/vlengine/scene/Skybox.java
Project members,
sign in
to write a code review
Older revisions
r3
by ve...@freemail.hu on Oct 8, 2008
Diff
Initial commit
All revisions of this file
File info
Size: 11480 bytes, 299 lines
View raw file
Powered by
Google Project Hosting