1717import org .terasology .engine .entitySystem .entity .EntityManager ;
1818import org .terasology .engine .entitySystem .entity .EntityRef ;
1919import org .terasology .engine .entitySystem .entity .lifecycleEvents .OnActivatedComponent ;
20- import org .terasology .engine .entitySystem .event .ReceiveEvent ;
2120import org .terasology .engine .entitySystem .systems .BaseComponentSystem ;
2221import org .terasology .engine .entitySystem .systems .RegisterMode ;
2322import org .terasology .engine .entitySystem .systems .RegisterSystem ;
3736import org .terasology .engine .rendering .world .WorldRenderer ;
3837import org .terasology .engine .utilities .Assets ;
3938import org .terasology .gestalt .assets .management .AssetManager ;
39+ import org .terasology .gestalt .entitysystem .event .ReceiveEvent ;
4040import org .terasology .joml .geom .AABBf ;
4141import org .terasology .joml .geom .AABBfc ;
4242import org .terasology .nui .Color ;
4343
4444import java .nio .FloatBuffer ;
45- import java .util .List ;
4645import java .util .Random ;
4746
4847/**
@@ -130,94 +129,68 @@ private void updateSkeletalMeshOfEntity(EntityRef entity, float delta) {
130129 return ;
131130 }
132131
133- if (skeletalMeshComp .animation == null && skeletalMeshComp .animationPool != null ) {
134- skeletalMeshComp .animation = randomAnimationData (skeletalMeshComp , random );
135- }
136-
137132 if (skeletalMeshComp .animation == null ) {
138133 return ;
139134 }
140135
141136 if (skeletalMeshComp .animation .getFrameCount () < 1 ) {
142137 return ;
143138 }
144- skeletalMeshComp .animationTime += delta * skeletalMeshComp .animationRate ;
145- float animationDuration = getDurationOfAnimation (skeletalMeshComp );
146- while (skeletalMeshComp .animationTime >= animationDuration ) {
147- MeshAnimation newAnimation ;
148- if (!skeletalMeshComp .loop ) {
149- newAnimation = null ;
150- } else if (skeletalMeshComp .animationPool != null && !skeletalMeshComp .animationPool .isEmpty ()) {
151- newAnimation = randomAnimationData (skeletalMeshComp , random );
152- } else {
153- newAnimation = skeletalMeshComp .animation ;
154- }
155139
156- if (newAnimation == null ) {
157- MeshAnimation finishedAnimation = skeletalMeshComp .animation ;
158- skeletalMeshComp .animationTime = animationDuration ;
159- MeshAnimationFrame frame = skeletalMeshComp .animation .getFrame (skeletalMeshComp .animation .getFrameCount () - 1 );
160- updateSkeleton (skeletalMeshComp , frame , frame , 1.0f );
161- // Set animation to null so that AnimEndEvent fires only once
162- skeletalMeshComp .animation = null ;
163- entity .saveComponent (skeletalMeshComp );
164- entity .send (new AnimEndEvent (finishedAnimation ));
165- return ;
140+ if (skeletalMeshComp .rootBone != null ) {
141+ LocationComponent locationComponent = skeletalMeshComp .rootBone .getComponent (LocationComponent .class );
142+ if (locationComponent != null ) {
143+ locationComponent .setLocalPosition (skeletalMeshComp .localOffset );
144+ locationComponent .setLocalScale (skeletalMeshComp .localScale );
145+ locationComponent .setLocalRotation (skeletalMeshComp .localRotation );
166146 }
167- skeletalMeshComp .animationTime -= animationDuration ;
168- if (skeletalMeshComp .animationTime < 0 ) {
169- // In case the float calculation wasn't exact:
170- skeletalMeshComp .animationTime = 0 ;
147+ }
148+
149+ float animationDuration = skeletalMeshComp .animation .getDuration ();
150+ if (skeletalMeshComp .currentTime >= animationDuration ) {
151+ skeletalMeshComp .currentTime -= animationDuration ;
152+ if (skeletalMeshComp .currentTime < 0 ) {
153+ skeletalMeshComp .currentTime = 0 ;
171154 }
172- skeletalMeshComp .animation = newAnimation ;
173- animationDuration = getDurationOfAnimation (skeletalMeshComp );
174155 }
175- float framePos = skeletalMeshComp . animationTime / skeletalMeshComp . animation . getTimePerFrame ();
176- int frameAId = ( int ) framePos ;
177- int frameBId = frameAId + 1 ;
178- if ( frameBId >= skeletalMeshComp . animation . getFrameCount ()) {
179- // In case the float calcuation wasn't exact:
180- frameBId = skeletalMeshComp . animation . getFrameCount () - 1 ;
156+
157+ float framePos = skeletalMeshComp . currentTime / skeletalMeshComp . animation . getTimePerFrame () ;
158+ int currentFrame = ( int ) framePos ;
159+ int nextFrame = currentFrame + 1 ;
160+ if ( nextFrame >= skeletalMeshComp . animation . getFrameCount ()) {
161+ nextFrame = 0 ;
181162 }
182- MeshAnimationFrame frameA = skeletalMeshComp .animation .getFrame (frameAId );
183- MeshAnimationFrame frameB = skeletalMeshComp .animation .getFrame (frameBId );
184- updateSkeleton (skeletalMeshComp , frameA , frameB , framePos - frameAId );
163+ float frameDelta = framePos - currentFrame ;
164+ MeshAnimationFrame animatedFrame1 = skeletalMeshComp .animation .getFrame (currentFrame );
165+ MeshAnimationFrame animatedFrame2 = skeletalMeshComp .animation .getFrame (nextFrame );
166+ updateFrame (skeletalMeshComp , animatedFrame1 , animatedFrame2 , frameDelta );
185167 entity .saveComponent (skeletalMeshComp );
186168 }
187169
188- private float getDurationOfAnimation (SkinnedMeshComponent skeletalMeshComp ) {
189- return skeletalMeshComp .animation .getTimePerFrame () * (skeletalMeshComp .animation .getFrameCount () - 1 );
190- }
170+ private void updateFrame (SkinnedMeshComponent skeletalMeshComp , MeshAnimationFrame frameA , MeshAnimationFrame frameB ,
171+ float interpolationVal ) {
191172
192- private static MeshAnimation randomAnimationData (SkinnedMeshComponent skeletalMeshComp , Random random ) {
193- List <MeshAnimation > animationPool = skeletalMeshComp .animationPool ;
194- if (animationPool == null ) {
195- return null ;
196- }
197- if (animationPool .isEmpty ()) {
198- return null ;
199- }
200- return animationPool .get (random .nextInt (animationPool .size ()));
201- }
202173
203- private void updateSkeleton (SkinnedMeshComponent skeletalMeshComp , MeshAnimationFrame frameA , MeshAnimationFrame frameB ,
204- float interpolationVal ) {
205174 for (int i = 0 ; i < skeletalMeshComp .animation .getBoneCount (); ++i ) {
206175 String boneName = skeletalMeshComp .animation .getBoneName (i );
207176 EntityRef boneEntity = skeletalMeshComp .boneEntities .get (boneName );
208177 if (boneEntity == null ) {
209178 continue ;
210179 }
180+
211181 LocationComponent boneLoc = boneEntity .getComponent (LocationComponent .class );
212- if (boneLoc != null ) {
213- Vector3f newPos = frameA .getPosition (i ).lerp (frameB .getPosition (i ), interpolationVal , new Vector3f ());
214- boneLoc .setLocalPosition (newPos );
215- Quaternionf newRot = frameA .getRotation (i ).slerp (frameB .getRotation (i ), interpolationVal , new Quaternionf ());
216- newRot .normalize ();
217- boneLoc .setLocalRotation (newRot );
218- boneLoc .setLocalScale (frameA .getBoneScale (i ).lerp (frameB .getBoneScale (i ), interpolationVal , new Vector3f ()).x );
219- boneEntity .saveComponent (boneLoc );
182+ if (boneLoc == null ) {
183+ continue ;
220184 }
185+
186+ Vector3f newPos = frameA .getPosition (i ).lerp (frameB .getPosition (i ), interpolationVal , new Vector3f ());
187+ boneLoc .setLocalPosition (newPos );
188+ Quaternionf newRot = frameA .getRotation (i ).slerp (frameB .getRotation (i ), interpolationVal , new Quaternionf ());
189+ newRot .normalize ();
190+ boneLoc .setLocalRotation (newRot );
191+ boneLoc .setLocalScale (frameA .getBoneScale (i ).lerp (frameB .getBoneScale (i ), interpolationVal , new Vector3f ()).x );
192+ boneEntity .saveComponent (boneLoc );
193+
221194 }
222195 }
223196
@@ -257,10 +230,10 @@ public void renderOpaque() {
257230 aabb = aabb .transform (new Matrix4f ().translationRotateScale (worldPos , worldRot , worldScale ), new AABBf ());
258231
259232 //Scale bounding box for skeletalMesh.
260- Vector3f scale = skeletalMesh .scale ;
233+ float scale = skeletalMesh .localScale ;
261234
262235 Vector3f aabbCenter = aabb .center (new Vector3f ());
263- Vector3f scaledExtents = aabb .extent (new Vector3f ()).mul (scale . x () , scale . y () , scale . z () );
236+ Vector3f scaledExtents = aabb .extent (new Vector3f ()).mul (scale , scale , scale );
264237 aabb = new AABBf (aabbCenter , aabbCenter ).expand (scaledExtents );
265238
266239 if (!worldRenderer .getActiveCamera ().hasInSight (aabb )) {
@@ -279,7 +252,6 @@ public void renderOpaque() {
279252 Vector3f worldPositionCameraSpace = new Vector3f ();
280253 worldPos .sub (cameraPosition , worldPositionCameraSpace );
281254
282- worldPositionCameraSpace .y += skeletalMesh .heightOffset ;
283255 Matrix4f matrixCameraSpace = new Matrix4f ().translationRotateScale (worldPositionCameraSpace , worldRot , worldScale );
284256
285257 Matrix4f modelViewMatrix = worldRenderer .getActiveCamera ().getViewMatrix ().mul (matrixCameraSpace , new Matrix4f ());
@@ -292,25 +264,21 @@ public void renderOpaque() {
292264 skeletalMesh .material .setFloat ("sunlight" , worldRenderer .getMainLightIntensityAt (worldPos ), true );
293265 skeletalMesh .material .setFloat ("blockLight" , worldRenderer .getBlockLightIntensityAt (worldPos ), true );
294266
295- Matrix4f [] boneTransforms = new Matrix4f [ skeletalMesh . mesh . bones (). size ()] ;
267+ Matrix4f boneTransform = new Matrix4f () ;
296268 for (Bone bone : skeletalMesh .mesh .bones ()) {
297269 EntityRef boneEntity = skeletalMesh .boneEntities .get (bone .getName ());
298270 if (boneEntity == null ) {
299271 boneEntity = EntityRef .NULL ;
300272 }
301273 LocationComponent boneLocation = boneEntity .getComponent (LocationComponent .class );
274+ boneTransform .identity ();
302275 if (boneLocation != null ) {
303- Matrix4f boneTransform = new Matrix4f ();
304276 boneLocation .getRelativeTransform (boneTransform , entity );
305277 boneTransform .mul (bone .getInverseBindMatrix ());
306- boneTransforms [bone .getIndex ()] = boneTransform ;
307278 } else {
308279 logger .warn ("Unable to resolve bone \" {}\" " , bone .getName ());
309- boneTransforms [bone .getIndex ()] = new Matrix4f ();
310280 }
311- }
312- for (int i = 0 ; i < boneTransforms .length ; i ++) {
313- skeletalMesh .material .setMatrix4 ("boneTransforms[" + i + "]" , boneTransforms [i ], true );
281+ skeletalMesh .material .setMatrix4 ("boneTransforms[" + bone .getIndex () + "]" , boneTransform , true );
314282 }
315283 skeletalMesh .mesh .render ();
316284 }
@@ -327,11 +295,7 @@ public void renderOverlay() {
327295
328296 Vector3f cameraPosition = worldRenderer .getActiveCamera ().getPosition ();
329297
330- Matrix4f relMat = new Matrix4f ();
331- Matrix4f relFinal = new Matrix4f ();
332298 Matrix4f entityTransform = new Matrix4f ();
333-
334- Matrix4f result = new Matrix4f ();
335299 Vector3f currentPos = new Vector3f ();
336300
337301 int index = 0 ;
@@ -349,10 +313,6 @@ public void renderOverlay() {
349313 // position is referenced around (0,0,0) (worldposition - cameraposition)
350314 Vector3f worldPositionCameraSpace = cameraPosition .negate (new Vector3f ());
351315
352- // same heightOffset is applied to worldPositionCameraSpace from #renderOpaque()
353- // TODO: resolve repeated logic for transformation applied to bones
354- worldPositionCameraSpace .y += skeletalMesh .heightOffset ;
355-
356316 Matrix4f matrixCameraSpace = new Matrix4f ().translationRotateScale (worldPositionCameraSpace , new Quaternionf (), 1.0f );
357317 Matrix4f modelViewMatrix = new Matrix4f (worldRenderer .getActiveCamera ().getViewMatrix ()).mul (matrixCameraSpace );
358318 material .setMatrix4 ("projectionMatrix" , worldRenderer .getActiveCamera ().getProjectionMatrix ());
@@ -370,27 +330,10 @@ public void renderOverlay() {
370330 LocationComponent locCompA = boneEntity .getComponent (LocationComponent .class );
371331 LocationComponent locCompB = boneParentEntity .getComponent (LocationComponent .class );
372332
373- // need to calculate the relative transformation from the entity to the start of the bone
374- locCompA .getRelativeTransform (relMat .identity (), entity );
375- // entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
376- result .set (entityTransform )
377- .mul (relFinal .identity ()
378- .scale (skeletalMesh .scale )
379- .translate (skeletalMesh .translate )
380- .mul (relMat ))
381- .transformPosition (currentPos .zero ()); // get the position of the start of the bone
333+ locCompA .getWorldPosition (currentPos );
382334 meshData .position .put (currentPos ); // the start of the bone
383335
384- // need to calculate the relative transformation from the entity to the connecting bone
385- locCompB .getRelativeTransform (relMat .identity (), entity );
386- // entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
387- result .set (entityTransform )
388- .mul (relFinal
389- .identity ()
390- .scale (skeletalMesh .scale )
391- .translate (skeletalMesh .translate )
392- .mul (relMat ))
393- .transformPosition (currentPos .zero ()); // get the position to the connecting bone
336+ locCompB .getWorldPosition (currentPos );
394337 meshData .position .put (currentPos ); // the end of the bone
395338
396339 meshData .color0 .put (Color .white );
0 commit comments