Răsfoiți Sursa

Model specification for animated models

Tankernn 8 ani în urmă
părinte
comite
67a631cedf

+ 11 - 6
src/main/java/eu/tankernn/gameEngine/animation/animatedModel/AnimatedModel.java

@@ -1,7 +1,7 @@
 package eu.tankernn.gameEngine.animation.animatedModel;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.lwjgl.util.vector.Matrix4f;
 
@@ -30,7 +30,7 @@ public class AnimatedModel extends TexturedModel {
 	private final int jointCount;
 
 	private final Animator animator;
-	private List<Animation> animations = new ArrayList<>();
+	private Map<String, Animation> animations = new HashMap<>();
 
 	/**
 	 * Creates a new entity capable of animation. The inverse bind transform for
@@ -62,6 +62,11 @@ public class AnimatedModel extends TexturedModel {
 		rootJoint.calcInverseBindTransform(new Matrix4f());
 	}
 
+	public AnimatedModel(AnimatedModel model) {
+		this(model.getModel(), model.getTexture(), new Joint(model.rootJoint), model.jointCount);
+		this.animations = new HashMap<>(model.animations);
+	}
+
 	/**
 	 * @return The root joint of the joint hierarchy. This joint has no parent,
 	 *         and every other joint in the skeleton is a descendant of this
@@ -92,12 +97,12 @@ public class AnimatedModel extends TexturedModel {
 		animator.doAnimation(animation);
 	}
 	
-	public void doAnimation(int animationId) {
+	public void doAnimation(String animationId) {
 		doAnimation(animations.get(animationId));
 	}
 	
-	public void registerAnimation(Animation animation) {
-		animations.add(animation);
+	public void registerAnimation(String key, Animation animation) {
+		animations.put(key, animation);
 	}
 
 	/**

+ 6 - 0
src/main/java/eu/tankernn/gameEngine/animation/animatedModel/Joint.java

@@ -59,6 +59,12 @@ public class Joint {
 		this.name = name;
 		this.localBindTransform = bindLocalTransform;
 	}
+	
+	public Joint(Joint joint) {
+		this(joint.index, joint.name, joint.localBindTransform);
+		for (Joint j : joint.children)
+			this.children.add(new Joint(j));
+	}
 
 	/**
 	 * Adds a child joint to this joint. Used during the creation of the joint

+ 2 - 2
src/main/java/eu/tankernn/gameEngine/entities/Player.java

@@ -68,14 +68,14 @@ public class Player extends Entity3D {
 	protected void checkInputs() {
 		if (Keyboard.isKeyDown(Keyboard.KEY_W) || (Mouse.isButtonDown(0) && Mouse.isButtonDown(1))) {
 			if (this.getModel() instanceof AnimatedModel)
-				((AnimatedModel) getModel()).doAnimation(0);
+				((AnimatedModel) getModel()).doAnimation("run");
 			this.currentSpeed = RUN_SPEED;
 		} else if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
 			this.currentSpeed = -RUN_SPEED;
 		} else {
 			this.currentSpeed = 0;
 			if (this.getModel() instanceof AnimatedModel)
-				((AnimatedModel) getModel()).doAnimation(null);
+				((AnimatedModel) getModel()).doAnimation("idle");
 		}
 		
 		if (Keyboard.isKeyDown(Keyboard.KEY_A)) {

+ 32 - 11
src/main/java/eu/tankernn/gameEngine/loader/Loader.java

@@ -23,6 +23,7 @@ import org.lwjgl.opengl.GL33;
 
 import eu.tankernn.gameEngine.animation.animatedModel.AnimatedModel;
 import eu.tankernn.gameEngine.animation.loaders.AnimatedModelLoader;
+import eu.tankernn.gameEngine.animation.loaders.AnimationLoader;
 import eu.tankernn.gameEngine.loader.models.AABB;
 import eu.tankernn.gameEngine.loader.models.TexturedModel;
 import eu.tankernn.gameEngine.loader.obj.ModelData;
@@ -230,18 +231,15 @@ public class Loader {
 			ModelTexture modelTexture;
 			
 			id = spec.getInt("id");
-			
-			InternalFile objFile = new InternalFile(optFilename(spec, "model", ".obj"));
+			InternalFile modelFile;
+			try {
+				modelFile = new InternalFile(optFilename(spec, "model", ".obj"));
+			} catch (FileNotFoundException e) {
+				modelFile = new InternalFile(optFilename(spec, "model", ".dae"));
+			}
 			
 			String[] textureFiles = {optFilename(spec, "texture", ".png"), optFilename(spec, "specular", "S.png"), optFilename(spec, "normal", "N.png")};
 			
-			if (cachedRawModels.containsKey(objFile))
-				model = cachedRawModels.get(objFile);
-			else {
-				model = loadOBJ(objFile);
-				cachedRawModels.put(objFile, model);
-			}
-			
 			Texture[] textures = Arrays.stream(textureFiles).map(fileName -> {
 				try {
 					InternalFile f = new InternalFile(fileName);
@@ -271,7 +269,26 @@ public class Loader {
 			
 			modelTexture.setHasTransparency(spec.optBoolean("transparency"));
 			
-			models.put(id, new TexturedModel(model, modelTexture));
+			if (cachedRawModels.containsKey(modelFile))
+				model = cachedRawModels.get(modelFile);
+			else {
+				if (modelFile.getName().endsWith(".obj")) {
+					model = loadOBJ(modelFile);
+					cachedRawModels.put(modelFile, model);
+					models.put(id, new TexturedModel(model, modelTexture));
+				} else if (modelFile.getName().endsWith(".dae")) {
+					AnimatedModel animatedModel = AnimatedModelLoader.loadEntity(modelFile, modelTexture);
+					JSONObject animations = spec.getJSONObject("animations");
+					for (Object key: animations.names().toList()) {
+						String name = (String) key;
+						animatedModel.registerAnimation(name, AnimationLoader.loadAnimation(new InternalFile(animations.getString(name))));
+					}
+					models.put(id, animatedModel);
+				} else {
+					throw new UnsupportedOperationException("Unsupported file format: " + modelFile.getExtension());
+				}
+			}
+			
 		}
 	}
 	
@@ -309,7 +326,11 @@ public class Loader {
 	}
 	
 	public TexturedModel getModel(int id) {
-		return models.get(id);
+		TexturedModel model = models.get(id);
+		if (model instanceof AnimatedModel)
+			return new AnimatedModel((AnimatedModel) model);
+		else
+			return model;
 	}
 	
 	public AABB getBoundingBox(int id) {

+ 5 - 0
src/main/java/eu/tankernn/gameEngine/util/InternalFile.java

@@ -114,4 +114,9 @@ public class InternalFile {
 		}
 	}
 
+	public String getExtension() {
+		String[] split = getName().split(".");
+		return split[split.length - 1];
+	}
+
 }