more utils
This commit is contained in:
parent
c08c972bce
commit
e871fefb02
|
@ -29,7 +29,7 @@
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.lwjgl.util.model.renderer;
|
package org.lwjgl.util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $Id$
|
* $Id$
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 Shaven Puppy Ltd
|
||||||
|
* 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 'Shaven Puppy' 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 org.lwjgl.util;
|
||||||
|
|
||||||
|
import org.lwjgl.Sys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* A hires timer. This measures time in seconds as floating point values.
|
||||||
|
* All Timers created are updated simultaneously by calling the static method
|
||||||
|
* tick(). This ensures that within a single iteration of a game loop that
|
||||||
|
* all timers are updated consistently with each other.
|
||||||
|
*
|
||||||
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public class Timer {
|
||||||
|
|
||||||
|
// Record the timer resolution on classload
|
||||||
|
private static final long resolution = Sys.getTimerResolution();
|
||||||
|
|
||||||
|
// Globally keeps track of time for all instances of Timer
|
||||||
|
private static long currentTime;
|
||||||
|
|
||||||
|
// When the timer was started
|
||||||
|
private long startTime;
|
||||||
|
|
||||||
|
// The last time recorded by getTime()
|
||||||
|
private long lastTime;
|
||||||
|
|
||||||
|
// Whether the timer is paused
|
||||||
|
private boolean paused;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a timer. The timer will be reset to 0.0 and resumed immediately.
|
||||||
|
*/
|
||||||
|
public Timer() {
|
||||||
|
reset();
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the time in seconds, as a float
|
||||||
|
*/
|
||||||
|
public float getTime() {
|
||||||
|
if (!paused)
|
||||||
|
lastTime = currentTime - startTime;
|
||||||
|
|
||||||
|
return (float) ((double) lastTime / (double) resolution);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return whether this timer is paused
|
||||||
|
*/
|
||||||
|
public boolean isPaused() {
|
||||||
|
return paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause the timer. Whilst paused the time will not change for this timer
|
||||||
|
* when tick() is called.
|
||||||
|
*
|
||||||
|
* @see #resume()
|
||||||
|
*/
|
||||||
|
public void pause() {
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the timer. Equivalent to set(0.0f);
|
||||||
|
* @see #set()
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
set(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume the timer.
|
||||||
|
* @see #pause()
|
||||||
|
*/
|
||||||
|
public void resume() {
|
||||||
|
paused = false;
|
||||||
|
startTime = currentTime - lastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the time of this timer
|
||||||
|
* @param newTime the new time, in seconds
|
||||||
|
*/
|
||||||
|
public void set(float newTime) {
|
||||||
|
long newTimeInTicks = (long) ((double) newTime * (double) resolution);
|
||||||
|
startTime = currentTime - newTimeInTicks;
|
||||||
|
lastTime = newTimeInTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next time update from the system's hires timer. This method should
|
||||||
|
* be called once per main loop iteration; all timers are updated simultaneously
|
||||||
|
* from it.
|
||||||
|
*/
|
||||||
|
public static void tick() {
|
||||||
|
currentTime = Sys.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug output.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return "Timer[Time=" + getTime() + ", Paused=" + paused + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,10 +49,11 @@ public class BoneFrame extends Frame {
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
* @param time
|
* @param time
|
||||||
|
* @param action
|
||||||
* @param bone[]
|
* @param bone[]
|
||||||
*/
|
*/
|
||||||
public BoneFrame(float time, Matrix4f[] bone) {
|
public BoneFrame(float time, String action, Matrix4f[] bone) {
|
||||||
super(time);
|
super(time, action);
|
||||||
this.bone = bone;
|
this.bone = bone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,8 @@ public class BonedModel extends Model {
|
||||||
* @param animation
|
* @param animation
|
||||||
* @param vertex
|
* @param vertex
|
||||||
*/
|
*/
|
||||||
public BonedModel(String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation, BonedVertex[] vertex) {
|
public BonedModel(String name, String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation, BonedVertex[] vertex) {
|
||||||
super(material, triangle, skin, color, animation);
|
super(name, material, triangle, skin, color, animation);
|
||||||
this.vertex = vertex;
|
this.vertex = vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,19 +39,24 @@ import java.io.Serializable;
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public abstract class Frame implements Serializable {
|
public abstract class Frame implements Serializable, Comparable {
|
||||||
|
|
||||||
public static final long serialVersionUID = 1L;
|
public static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** Frame time */
|
/** Frame time */
|
||||||
private final float time;
|
private final float time;
|
||||||
|
|
||||||
|
/** User-defined action to occur after this frame has been used. May be null */
|
||||||
|
private final String action;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
* @param time
|
* @param time
|
||||||
|
* @param action
|
||||||
*/
|
*/
|
||||||
public Frame(float time) {
|
public Frame(float time, String action) {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,4 +65,35 @@ public abstract class Frame implements Serializable {
|
||||||
public final float getTime() {
|
public final float getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
if (o == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (! (o instanceof Frame)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Frame f = (Frame) o;
|
||||||
|
if (f.time == time) {
|
||||||
|
return 0;
|
||||||
|
} else if (f.time > time) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user-defined animation action. This can be processed by whatever
|
||||||
|
* is animating the model to perform some special action after the frame is
|
||||||
|
* used. For example, you could use "stop" to stop the animation, or "rewind"
|
||||||
|
* to repeat the animation ad infinitum.
|
||||||
|
* @return String, or null, for no action
|
||||||
|
*/
|
||||||
|
public final String getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,11 @@ public class MeshFrame extends Frame {
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
* @param time
|
* @param time
|
||||||
|
* @param action
|
||||||
* @param bone[]
|
* @param bone[]
|
||||||
*/
|
*/
|
||||||
public MeshFrame(float time, Vertex[] vertex) {
|
public MeshFrame(float time, String action, Vertex[] vertex) {
|
||||||
super(time);
|
super(time, action);
|
||||||
this.vertex = vertex;
|
this.vertex = vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,8 @@ public class MeshedModel extends Model {
|
||||||
* @param color[]
|
* @param color[]
|
||||||
* @param animation
|
* @param animation
|
||||||
*/
|
*/
|
||||||
public MeshedModel(String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation) {
|
public MeshedModel(String name, String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation) {
|
||||||
super(material, triangle, skin, color, animation);
|
super(name, material, triangle, skin, color, animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ public abstract class Model implements Serializable {
|
||||||
|
|
||||||
public static final long serialVersionUID = 1L;
|
public static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** Model name */
|
||||||
|
private final String name;
|
||||||
|
|
||||||
/** Material */
|
/** Material */
|
||||||
private final String material;
|
private final String material;
|
||||||
|
|
||||||
|
@ -69,13 +72,15 @@ public abstract class Model implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
|
* @param name
|
||||||
* @param material
|
* @param material
|
||||||
* @param triangle
|
* @param triangle
|
||||||
* @param skin[]
|
* @param skin[]
|
||||||
* @param color[]
|
* @param color[]
|
||||||
* @param animation
|
* @param animation
|
||||||
*/
|
*/
|
||||||
public Model(String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation) {
|
public Model(String name, String material, Triangle[] triangle, Vector2f[] skin, Color[] color, Map animation) {
|
||||||
|
this.name = name;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
this.triangle = triangle;
|
this.triangle = triangle;
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
|
@ -88,8 +93,8 @@ public abstract class Model implements Serializable {
|
||||||
* @param name The name of the animation
|
* @param name The name of the animation
|
||||||
* @return the Frames of an animation (or null, if no such animation exists)
|
* @return the Frames of an animation (or null, if no such animation exists)
|
||||||
*/
|
*/
|
||||||
public final BoneFrame[] getAnimation(String name) {
|
public final Frame[] getAnimation(String name) {
|
||||||
return (BoneFrame[]) animation.get(name);
|
return (Frame[]) animation.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,5 +125,17 @@ public abstract class Model implements Serializable {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return "Model["+name+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the name.
|
||||||
|
*/
|
||||||
|
public final String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,9 @@
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.lwjgl.util.model.loader;
|
package org.lwjgl.util.model.loaders;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -60,7 +61,7 @@ import org.w3c.dom.Element;
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public class Loader {
|
public class XMLLoader {
|
||||||
|
|
||||||
/** The source document */
|
/** The source document */
|
||||||
private final Document src;
|
private final Document src;
|
||||||
|
@ -74,7 +75,7 @@ public class Loader {
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
*/
|
*/
|
||||||
public Loader(Document src) {
|
public XMLLoader(Document src) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +85,14 @@ public class Loader {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public Model load() throws Exception {
|
public Model load() throws Exception {
|
||||||
|
String name = XMLUtil.getString(src.getDocumentElement(), "name");
|
||||||
String material = XMLUtil.getString(src.getDocumentElement(), "material");
|
String material = XMLUtil.getString(src.getDocumentElement(), "material");
|
||||||
numVertices = XMLUtil.getInt(src.getDocumentElement(), "vertices");
|
numVertices = XMLUtil.getInt(src.getDocumentElement(), "vertices");
|
||||||
if (XMLUtil.getString(src.getDocumentElement(), "type").equals("boned")) {
|
if (XMLUtil.getString(src.getDocumentElement(), "type").equals("boned")) {
|
||||||
// It's a boned model
|
// It's a boned model
|
||||||
numBones = XMLUtil.getInt(src.getDocumentElement(), "bones", 0);
|
numBones = XMLUtil.getInt(src.getDocumentElement(), "bones", 0);
|
||||||
return new BonedModel(
|
return new BonedModel(
|
||||||
|
name,
|
||||||
material,
|
material,
|
||||||
loadTriangles(),
|
loadTriangles(),
|
||||||
loadSkin(),
|
loadSkin(),
|
||||||
|
@ -100,6 +103,7 @@ public class Loader {
|
||||||
} else if (XMLUtil.getString(src.getDocumentElement(), "type").equals("meshed")) {
|
} else if (XMLUtil.getString(src.getDocumentElement(), "type").equals("meshed")) {
|
||||||
// It's a mesh keyframe model
|
// It's a mesh keyframe model
|
||||||
return new MeshedModel(
|
return new MeshedModel(
|
||||||
|
name,
|
||||||
material,
|
material,
|
||||||
loadTriangles(),
|
loadTriangles(),
|
||||||
loadSkin(),
|
loadSkin(),
|
||||||
|
@ -371,6 +375,7 @@ public class Loader {
|
||||||
Element frameElement = (Element) i.next();
|
Element frameElement = (Element) i.next();
|
||||||
frames[frameCount++] = loadBoneFrame(frameElement);
|
frames[frameCount++] = loadBoneFrame(frameElement);
|
||||||
}
|
}
|
||||||
|
Arrays.sort(frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +393,7 @@ public class Loader {
|
||||||
Element frameElement = (Element) i.next();
|
Element frameElement = (Element) i.next();
|
||||||
frames[frameCount++] = loadMeshFrame(frameElement);
|
frames[frameCount++] = loadMeshFrame(frameElement);
|
||||||
}
|
}
|
||||||
|
Arrays.sort(frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +415,8 @@ public class Loader {
|
||||||
bones[boneCount++] = loadBone(boneElement);
|
bones[boneCount++] = loadBone(boneElement);
|
||||||
}
|
}
|
||||||
return new BoneFrame(
|
return new BoneFrame(
|
||||||
XMLUtil.getFloat(element, "time", 0.0f),
|
XMLUtil.getFloat(element, "time"),
|
||||||
|
XMLUtil.getString(element, "action", null),
|
||||||
bones
|
bones
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +439,8 @@ public class Loader {
|
||||||
vertices[vertexCount++] = loadMeshVertex(vertexElement);
|
vertices[vertexCount++] = loadMeshVertex(vertexElement);
|
||||||
}
|
}
|
||||||
return new MeshFrame(
|
return new MeshFrame(
|
||||||
XMLUtil.getFloat(element, "time", 0.0f),
|
XMLUtil.getFloat(element, "time"),
|
||||||
|
XMLUtil.getString(element, "action", null),
|
||||||
vertices
|
vertices
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.lwjgl.util.model.loader;
|
package org.lwjgl.util.model.loaders;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -31,11 +31,15 @@
|
||||||
*/
|
*/
|
||||||
package org.lwjgl.util.model.renderer;
|
package org.lwjgl.util.model.renderer;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.lwjgl.util.model.BoneFrame;
|
import org.lwjgl.util.Renderable;
|
||||||
import org.lwjgl.util.model.BonedModel;
|
import org.lwjgl.util.Timer;
|
||||||
|
import org.lwjgl.util.model.Frame;
|
||||||
|
import org.lwjgl.util.model.Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $Id$
|
* $Id$
|
||||||
|
@ -46,14 +50,35 @@ import org.lwjgl.util.model.BonedModel;
|
||||||
* Material lookups are performed by mapping the material name to a Renderable thing. You must
|
* Material lookups are performed by mapping the material name to a Renderable thing. You must
|
||||||
* suppy appropriate Renderables - typically something that binds a 2D texture and sets up some
|
* suppy appropriate Renderables - typically something that binds a 2D texture and sets up some
|
||||||
* GL state.
|
* GL state.
|
||||||
|
* <p>
|
||||||
|
* To animate things, you will need to call Timer.tick() every frame to update the timers in your
|
||||||
|
* Renderables. Then they'll just animate themselves. Hurrah!
|
||||||
*
|
*
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public class Renderer {
|
public class Renderer implements Renderable {
|
||||||
|
|
||||||
/** Material map: String name->Renderable */
|
/** Material map: String name->Renderable */
|
||||||
private final Map materials = new HashMap();
|
private static final Map materials = new HashMap();
|
||||||
|
|
||||||
|
/** The model we're rendering */
|
||||||
|
private Model model;
|
||||||
|
|
||||||
|
/** The current material */
|
||||||
|
private Renderable material;
|
||||||
|
|
||||||
|
/** The animation currently being animated */
|
||||||
|
private Frame[] frame;
|
||||||
|
|
||||||
|
/** The current time */
|
||||||
|
private final Timer timer = new Timer();
|
||||||
|
|
||||||
|
/** Last frame rendered */
|
||||||
|
private Frame lastFrame;
|
||||||
|
|
||||||
|
/** Visibility */
|
||||||
|
private boolean visible;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
|
@ -62,36 +87,135 @@ public class Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a Model
|
* @param model The model to set.
|
||||||
* @param model The model to render
|
|
||||||
* @param animation The name of the animation
|
|
||||||
* @param time The time for the animation
|
|
||||||
*/
|
*/
|
||||||
public void render(BonedModel model, String animation, float time) {
|
public void setModel(Model model) {
|
||||||
|
if (this.model == model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.model = model;
|
||||||
|
material = (Renderable) materials.get(model.getMaterial());
|
||||||
|
frame = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Model we're rendering with this Renderer
|
||||||
|
*/
|
||||||
|
public Model getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the animation
|
||||||
|
* @param animation
|
||||||
|
*/
|
||||||
|
public void setAnimation(String animation) {
|
||||||
|
if (model == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame = model.getAnimation(animation);
|
||||||
|
timer.reset();
|
||||||
|
lastFrame = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a Model
|
||||||
|
*/
|
||||||
|
public void render() {
|
||||||
|
|
||||||
|
// Don't do anything if there's no model or no animation
|
||||||
|
if (model == null || frame == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Set up GL state from the Model's material
|
// 1. Set up GL state from the Model's material
|
||||||
Renderable material = (Renderable) materials.get(model.getMaterial());
|
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
material.render();
|
material.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Get the animation
|
// 2. Work out what frame to show
|
||||||
BoneFrame[] frame = model.getAnimation(animation);
|
Frame frame = findFrame();
|
||||||
if (frame == null) {
|
if (frame != lastFrame) {
|
||||||
return;
|
lastFrame = frame;
|
||||||
|
processFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Work out what the nearest frame is to the specified time
|
// 3. Render the processed frame
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the nearest frame to the current time
|
||||||
|
* @return the Frame nearest the current time
|
||||||
|
*/
|
||||||
|
private Frame findFrame() {
|
||||||
|
float time = timer.getTime();
|
||||||
|
|
||||||
|
// Use a binary search to find the frame
|
||||||
|
int a = 0, b =
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a material
|
* Add a material
|
||||||
* @param name The material's name
|
* @param name The material's name
|
||||||
* @param renderable The renderable object
|
* @param renderable The renderable object
|
||||||
*/
|
*/
|
||||||
public void putMaterial(String name, Renderable renderable) {
|
public static void putMaterial(String name, Renderable renderable) {
|
||||||
materials.put(name, renderable);
|
materials.put(name, renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a material
|
||||||
|
* @param name The material's name
|
||||||
|
* @return a Renderable
|
||||||
|
*/
|
||||||
|
public static Renderable removeMaterial(String name) {
|
||||||
|
return (Renderable) materials.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this Renderer is visible
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isVisible() {
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the visibility of this Renderer
|
||||||
|
* @param visible
|
||||||
|
*/
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
this.visible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the animation is paused
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isPaused() {
|
||||||
|
return timer.isPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause the animation
|
||||||
|
*/
|
||||||
|
public void pause() {
|
||||||
|
timer.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind the animation
|
||||||
|
*/
|
||||||
|
public void rewind() {
|
||||||
|
timer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume a paused animation
|
||||||
|
*/
|
||||||
|
public void resume() {
|
||||||
|
timer.resume();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue