Skip to content

Commit b09dd16

Browse files
committed
Fixed XML Parser & animation engine
1 parent 3939423 commit b09dd16

24 files changed

+283
-204
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ Android 3D Model Viewer
44
![codeship badge](https://codeship.com/projects/52cf9560-deb2-0134-4203-2aaddef843aa/status?branch=master)
55

66
This is a demo of OpenGL ES 2.0.
7-
It is basically an android application with a 3D renderer that can load Wavefront Obj, STL files & Collada files.
7+
It is basically an android application with a 3D engine that can load Wavefront OBJ, STL & DAE files.
88
The purpose of this application is to learn and share how to draw using OpenGL language.
99

10-
1110
* Wafefront format (OBJ): https://en.wikipedia.org/wiki/Wavefront_.obj_file
1211
* STereoLithography format (STL): https://en.wikipedia.org/wiki/STL_(file_format)
1312
* Collada format (DAE): https://en.wikipedia.org/wiki/COLLADA
1413

15-
News (08/12/2017)
14+
15+
News (17/12/2017)
1616
=================
1717

1818
* Support for collada files with skeletal animations :)
@@ -70,8 +70,7 @@ Features
7070
- rotate with 2 fingers to rotate camera
7171
- pinch & spread to zoom in/out the camera
7272
- skeletal animations
73-
- moving of objects (not yet!)
74-
- primitive collision detection (not yet!)
73+
7574

7675
Try it
7776
======
@@ -101,6 +100,8 @@ Screenshot
101100
![Screenshot5](screenshots/screenshot5.png)
102101
![Screenshot6](screenshots/screenshot6.png)
103102
![Screenshot7](screenshots/screenshot7.png)
103+
![cowboy.gif](screenshots/cowboy.gif)
104+
![stormtrooper.gif](screenshots/stormtrooper.gif)
104105

105106

106107
Final Notes
@@ -121,6 +122,11 @@ ChangeLog
121122

122123
(f) fixed, (i) improved, (n) new feature
123124

125+
- 2.0.2 (17/12/2017)
126+
- (f) Collada XML parser is now android's XmlPullParser
127+
- (f) Animation engine frame times improved
128+
- (n) Camera now moves smoothly
129+
124130
- 2.0.1 (08/12/2017)
125131
- (f) Multiple Collada parser fixes
126132
- (f) Camera now can look inside objects

app/build/outputs/apk/app-release.apk

1.27 KB
Binary file not shown.

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="org.andresoviedo.dddmodel2"
4-
android:versionCode="15"
5-
android:versionName="2.0.1" >
4+
android:versionCode="16"
5+
android:versionName="2.0.2" >
66

77
<uses-sdk
88
android:minSdkVersion="8"

app/src/main/java/org/andresoviedo/app/model3D/animation/Animation.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class Animation {
1515

1616
private final float length;//in seconds
1717
private final KeyFrame[] keyFrames;
18+
private boolean initialized;
1819

1920
/**
2021
* @param lengthInSeconds
@@ -28,6 +29,14 @@ public Animation(float lengthInSeconds, KeyFrame[] frames) {
2829
this.length = lengthInSeconds;
2930
}
3031

32+
public void setInitialized(boolean initialized){
33+
this.initialized = initialized;
34+
}
35+
36+
public boolean isInitialized(){
37+
return initialized;
38+
}
39+
3140
/**
3241
* @return The length of the animation in seconds.
3342
*/

app/src/main/java/org/andresoviedo/app/model3D/animation/Animator.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.andresoviedo.app.model3D.animation;
22

3+
import android.animation.Keyframe;
34
import android.opengl.Matrix;
45
import android.os.SystemClock;
56
import android.util.Log;
@@ -57,13 +58,50 @@ public void update(Object3DData obj) {
5758
AnimatedModel animatedModel = (AnimatedModel)obj;
5859
if (animatedModel.getAnimation() == null) return;
5960

61+
initAnimation(animatedModel);
62+
6063
increaseAnimationTime((AnimatedModel)obj);
6164
Map<String, float[]> currentPose = calculateCurrentAnimationPose(animatedModel);
6265
float parentTransform[] = new float[16];
6366
Matrix.setIdentityM(parentTransform,0);
6467
applyPoseToJoints(currentPose, (animatedModel).getRootJoint(), parentTransform);
6568
}
6669

70+
private void initAnimation(AnimatedModel animatedModel) {
71+
if (animatedModel.getAnimation().isInitialized()) {
72+
return;
73+
}
74+
KeyFrame[] keyFrames = animatedModel.getAnimation().getKeyFrames();
75+
Log.i("Animator", "Initializing " + animatedModel.getId() + ". " + keyFrames.length + " key frames...");
76+
for (int i = 0; i < keyFrames.length; i++) {
77+
int j = (i + 1) % keyFrames.length;
78+
KeyFrame keyFramePrevious = keyFrames[i];
79+
KeyFrame keyFrameNext = keyFrames[j];
80+
Map<String, JointTransform> jointTransforms = keyFramePrevious.getJointKeyFrames();
81+
for (Map.Entry<String, JointTransform> transform : jointTransforms.entrySet()) {
82+
String jointId = transform.getKey();
83+
if (keyFrameNext.getJointKeyFrames().containsKey(jointId)) {
84+
continue;
85+
}
86+
JointTransform keyFramePreviousTransform = keyFramePrevious.getJointKeyFrames().get(jointId);
87+
JointTransform keyFrameNextTransform = null;
88+
KeyFrame keyFrameNextNext = null;
89+
int k = (j + 1) % keyFrames.length;
90+
do {
91+
keyFrameNextNext = keyFrames[k];
92+
keyFrameNextTransform = keyFrameNextNext.getJointKeyFrames().get(jointId);
93+
k = (k + 1) % keyFrames.length;
94+
} while (keyFrameNextTransform == null);
95+
this.animationTime = keyFrameNext.getTimeStamp();
96+
float progression = calculateProgression(keyFramePrevious, keyFrameNextNext);
97+
JointTransform missingFrameTransform = JointTransform.interpolate(keyFramePreviousTransform, keyFrameNextTransform, progression);
98+
keyFrameNext.getJointKeyFrames().put(jointId, missingFrameTransform);
99+
}
100+
}
101+
animatedModel.getAnimation().setInitialized(true);
102+
Log.i("Animator", "Initialized " + animatedModel.getId() + ". " + keyFrames.length + " key frames");
103+
}
104+
67105
/**
68106
* Increases the current animation time which allows the animation to
69107
* progress. If the current animation has reached the end then the timer is

app/src/main/java/org/andresoviedo/app/model3D/entities/Camera.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public class Camera {
4545

4646
float[] matrix = new float[16];
4747
float[] buffer = new float[12 + 12 + 16 + 16];
48-
float[] buffer4x3 = new float[12];
48+
private long animationCounter;
49+
private Object[] lastAction;
4950
private boolean changed = false;
5051

5152
public Camera() {
@@ -74,6 +75,24 @@ public void setScene(SceneLoader scene) {
7475
this.scene = scene;
7576
}
7677

78+
public void animate(){
79+
if (lastAction == null || animationCounter == 0){
80+
lastAction = null;
81+
animationCounter = 100;
82+
return;
83+
}
84+
String method = (String) lastAction[0];
85+
if (method.equals("translate")){
86+
float dX = (Float) lastAction[1];
87+
float dY = (Float) lastAction[2];
88+
translateCameraImpl(dX*animationCounter/100, dY*animationCounter/100);
89+
} else if (method.equals("rotate")){
90+
float rotZ = (Float)lastAction[1];
91+
RotateImpl(rotZ/100*animationCounter);
92+
}
93+
animationCounter--;
94+
}
95+
7796
private void normalize() {
7897
float xLook = 0, yLook = 0, zLook = 0;
7998
float xRight = 0, yRight = 0, zRight = 0;
@@ -123,7 +142,12 @@ private void normalize() {
123142
zUp = zArriba + zPos;
124143
}
125144

126-
public void MoveCameraZ(float direction) {
145+
public void MoveCameraZ(float direction){
146+
if (direction == 0) return;
147+
MoveCameraZImpl(direction);
148+
lastAction = new Object[]{"zoom",direction};
149+
}
150+
public void MoveCameraZImpl(float direction) {
127151
// Moving the camera requires a little more then adding 1 to the z or
128152
// subracting 1.
129153
// First we need to get the direction at which we are looking.
@@ -400,6 +424,13 @@ void RotateByMouse(float mousePosX, float mousePosY, float midX, float midY) {
400424
* @param dY the Y component of the user 2D vector, that is, a value between [-1,1]
401425
*/
402426
public void translateCamera(float dX, float dY) {
427+
Log.d("Camera","translate:"+dX+","+dY);
428+
if (dX == 0 && dY == 0) return;
429+
translateCameraImpl(dX, dY);
430+
lastAction = new Object[]{"translate",dX, dY};
431+
}
432+
433+
public void translateCameraImpl(float dX, float dY) {
403434
float vlen;
404435

405436
// Translating the camera requires a directional vector to rotate
@@ -581,6 +612,12 @@ public String toString() {
581612
}
582613

583614
public void Rotate(float rotViewerZ) {
615+
if (rotViewerZ == 0) return;
616+
RotateImpl(rotViewerZ);
617+
lastAction = new Object[]{"rotate",rotViewerZ};
618+
}
619+
620+
public void RotateImpl(float rotViewerZ) {
584621
if (Float.isNaN(rotViewerZ)) {
585622
Log.w("Rot", "NaN");
586623
return;

0 commit comments

Comments
 (0)