package electrosphere.renderer.anim; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.PriorityQueue; import org.joml.Quaternionf; import org.joml.Vector3f; import org.lwjgl.PointerBuffer; import org.lwjgl.assimp.AIAnimation; import org.lwjgl.assimp.AIMeshAnim; import org.lwjgl.assimp.AIMeshKey; import org.lwjgl.assimp.AINodeAnim; import org.lwjgl.assimp.AIQuatKey; import org.lwjgl.assimp.AIVectorKey; /** * * @author satellite */ public class Animation { public static final String ANIMATION_MOVEMENT_STARTUP = "Armature|WalkStart"; public static final String ANIMATION_MOVEMENT_MOVE = "Armature|Walk"; public static final String ANIMATION_IDLE_1 = "Armature|Idle1"; AIAnimation animData; public String name; public int ID; ArrayList nodeChannelData; ArrayList meshChannelData; public ArrayList channels; public double duration = 0; public double timeCurrent = 0; public double ticksPerSecond; public Animation(AIAnimation animData, int ID){ // //Read in metadata // this.animData = animData; name = animData.mName().dataString(); this.duration = animData.mDuration(); this.ticksPerSecond = animData.mTicksPerSecond(); this.ID = ID; // //Print metadata // // System.out.println("Animation name: \"" + name + "\""); // System.out.println("ID:(" + ID + ")"); // System.out.println("Ticks per second: " + ticksPerSecond); // System.out.println("Anim sizeof: " + animData.sizeof()); // System.out.println("Duration: " + duration); // //Read in anim channels (bone modifications) // int channelCount = animData.mNumChannels(); channels = new ArrayList(); if(channelCount > 0){ // System.out.println("Channel count: " + channelCount); for(int i = 0; i < channelCount; i++){ AINodeAnim currentChannelData = AINodeAnim.create(animData.mChannels().get(i)); // System.out.println("Channel[" + (i + 1) + "]: " + currentChannelData.mNodeName().dataString()); //Create channel AnimChannel currentChannel = new AnimChannel(duration); currentChannel.positionFrame = new ArrayList(); currentChannel.rotationFrame = new ArrayList(); currentChannel.scaleFrame = new ArrayList(); currentChannel.nodeID = currentChannelData.mNodeName().dataString(); channels.add(currentChannel); //get channel data if(currentChannelData.mNumPositionKeys() > 0){ org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys(); // Iterator keyIterator = buff.iterator(); // while (keyIterator.hasNext()) { // AIVectorKey key = keyIterator.next(); // Keyframe currentFrame = new Keyframe(key.mTime()); // currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); // currentChannel.positionFrame.add(currentFrame); // } if(buff != null && buff.hasRemaining()){ // System.out.println("Position vectors: "); AIVectorKey key = buff.get(); Keyframe currentFrame = new Keyframe(key.mTime()); currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); currentChannel.positionFrame.add(currentFrame); // System.out.println(currentFrame.position); currentChannel.startingPosition = currentFrame.position; Keyframe previousFrame; while(buff.hasRemaining()){ previousFrame = currentFrame; key = buff.get(); currentFrame = new Keyframe(key.mTime()); currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); // System.out.println(currentFrame.position); //check if duplicate // Keyframe previousFrame = currentChannel.positionFrame.get(currentChannel.positionFrame.size() - 1); if( previousFrame.position.x == currentFrame.position.x && previousFrame.position.y == currentFrame.position.y && previousFrame.position.z == currentFrame.position.z ){ } else { currentChannel.positionFrame.add(currentFrame); } } } } if(currentChannelData.mNumRotationKeys() > 0){ org.lwjgl.assimp.AIQuatKey.Buffer buff = currentChannelData.mRotationKeys(); if(buff != null && buff.hasRemaining()){ AIQuatKey key = buff.get(); Keyframe currentFrame = new Keyframe(key.mTime()); currentFrame.rotation = new Quaternionf(); currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w()); // currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w()); currentChannel.rotationFrame.add(currentFrame); currentChannel.startingRotation = currentFrame.rotation; Keyframe previousFrame; while(buff.hasRemaining()){ previousFrame = currentFrame; key = buff.get(); currentFrame = new Keyframe(key.mTime()); currentFrame.rotation = new Quaternionf(); currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w()); // currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w()); //check for duplicate // Keyframe previousFrame = currentChannel.rotationFrame.get(currentChannel.rotationFrame.size() - 1); if( previousFrame.rotation.w == currentFrame.rotation.w && previousFrame.rotation.x == currentFrame.rotation.x && previousFrame.rotation.y == currentFrame.rotation.y && previousFrame.rotation.z == currentFrame.rotation.z ){ } else { currentChannel.rotationFrame.add(currentFrame); } } } // Iterator keyIterator = buff.iterator(); // while(keyIterator.hasNext()){ // AIQuatKey key = keyIterator.next(); // Keyframe currentFrame = new Keyframe(key.mTime()); // currentFrame.rotation = new Quaternionf(key.mValue().w(),key.mValue().x(),key.mValue().y(),key.mValue().z()); // currentChannel.rotationFrame.add(currentFrame); // } } if(currentChannelData.mNumScalingKeys() > 0){ org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mScalingKeys(); // Iterator keyIterator = buff.iterator(); // while (keyIterator.hasNext()) { // AIVectorKey key = keyIterator.next(); // Keyframe currentFrame = new Keyframe(key.mTime()); // currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); // currentChannel.scaleFrame.add(currentFrame); // } if(buff != null && buff.hasRemaining()){ AIVectorKey key = buff.get(); Keyframe currentFrame = new Keyframe(key.mTime()); currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); currentChannel.scaleFrame.add(currentFrame); Keyframe previousFrame; while(buff.hasRemaining()){ previousFrame = currentFrame; key = buff.get(); currentFrame = new Keyframe(key.mTime()); currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); if( currentFrame.scale.x == previousFrame.scale.x && currentFrame.scale.y == previousFrame.scale.y && currentFrame.scale.z == previousFrame.scale.z ){ } else { currentChannel.scaleFrame.add(currentFrame); } } } } // System.out.println("end times"); // for(int j = 0; j < currentChannelData.mNumPositionKeys(); j++){ // org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys(); // Iterator keyIterator = buff.iterator(); // AIVectorKey posKey = currentChannelData.mPositionKeys().get(i); // Keyframe currentFrame = new Keyframe(posKey.mTime()); // currentFrame.position = new Vector3f(posKey.mValue().x(),posKey.mValue().y(),posKey.mValue().z()); // } // for(int j = 0; j < currentChannelData.mNumRotationKeys(); j++){ // AIQuatKey rotKey = currentChannelData.mRotationKeys().get(i); // HashMap test = new HashMap(); // System.out.println(new Quaternionf(rotKey.mValue().w(),rotKey.mValue().x(),rotKey.mValue().y(),rotKey.mValue().z())); // } // for(int j = 0; j < currentChannelData.mNumScalingKeys(); j++){ // AIVectorKey scaleKey = currentChannelData.mScalingKeys().get(i); //// scaleKey.mValue(). // System.out.println(new Vector3f(scaleKey.mValue().x(),scaleKey.mValue().y(),scaleKey.mValue().z())); // } } } // int meshChannelCount = animData.mNumMeshChannels(); // meshChannelData = new ArrayList(); // if(meshChannelCount > 0){ // for(int i = 0; i < meshChannelCount; i++){ // AIMeshAnim test = AIMeshAnim.create(animData.mMeshChannels().get(i)); // } // } //gotta free things nodeChannelData = null; meshChannelData = null; } public void describeAnimation(){ System.out.println("====================="); System.out.println("Name: \"" + name + "\""); System.out.println("ID: " + ID); System.out.println("Duration: " + duration); System.out.println("Ticks per second: " + ticksPerSecond); Iterator channelIterator = channels.iterator(); while(channelIterator.hasNext()){ AnimChannel channelCurrent = channelIterator.next(); System.out.println("====================="); channelCurrent.describeChannel(); } System.out.println("====================="); } public void fullDescribeAnimation(){ System.out.println("====================="); System.out.println("Name: " + name); System.out.println("ID: " + ID); System.out.println("Duration: " + duration); System.out.println("Ticks per second: " + ticksPerSecond); Iterator channelIterator = channels.iterator(); while(channelIterator.hasNext()){ AnimChannel channelCurrent = channelIterator.next(); System.out.println("====================="); channelCurrent.fullDescribeChannel(); } System.out.println("====================="); } public boolean incrementTime(double time){ timeCurrent += time; if(timeCurrent > duration){ return true; } else { return false; } } public void setTime(double time){ timeCurrent = time; } }