Switch to using JME's serialization mechanism, which promises a degree
of version safety (meaning we won't necessarily have to recompile all the models when we add a new field) and should help avoid the frequent binary changes to which Java serialization is prone. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@71 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -21,17 +21,12 @@
|
||||
|
||||
package com.threerings.jme.model;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
@@ -58,6 +53,10 @@ import com.jme.scene.state.RenderState;
|
||||
import com.jme.scene.state.TextureState;
|
||||
import com.jme.scene.state.ZBufferState;
|
||||
import com.jme.system.DisplaySystem;
|
||||
import com.jme.util.export.JMEExporter;
|
||||
import com.jme.util.export.JMEImporter;
|
||||
import com.jme.util.export.InputCapsule;
|
||||
import com.jme.util.export.OutputCapsule;
|
||||
import com.jme.util.geom.BufferUtils;
|
||||
|
||||
import com.samskivert.util.PropertiesUtil;
|
||||
@@ -69,7 +68,7 @@ import com.threerings.jme.Log;
|
||||
* A {@link TriMesh} with a serialization mechanism tailored to stored models.
|
||||
*/
|
||||
public class ModelMesh extends TriMesh
|
||||
implements Externalizable, ModelSpatial
|
||||
implements ModelSpatial
|
||||
{
|
||||
/**
|
||||
* No-arg constructor for deserialization.
|
||||
@@ -127,37 +126,6 @@ public class ModelMesh extends TriMesh
|
||||
Boolean.parseBoolean(tprops.getProperty("translucent"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the buffers as {@link ByteBuffer}s, because we can't create byte
|
||||
* views of non-byte buffers. This method is where the model is
|
||||
* initialized after loading.
|
||||
*/
|
||||
public void reconstruct (
|
||||
ByteBuffer vertices, ByteBuffer normals, ByteBuffer colors,
|
||||
ByteBuffer textures, ByteBuffer indices)
|
||||
{
|
||||
reconstruct(
|
||||
vertices == null ? null : vertices.asFloatBuffer(),
|
||||
normals == null ? null : normals.asFloatBuffer(),
|
||||
colors == null ? null : colors.asFloatBuffer(),
|
||||
textures == null ? null : textures.asFloatBuffer(),
|
||||
indices == null ? null : indices.asIntBuffer());
|
||||
for (int ii = 1, nn = getTextureCount(); ii < nn; ii++) {
|
||||
setTextureBuffer(0, getTextureBuffer(0, 0), ii);
|
||||
}
|
||||
_vertexByteBuffer = vertices;
|
||||
_normalByteBuffer = normals;
|
||||
_colorByteBuffer = colors;
|
||||
_textureByteBuffer = textures;
|
||||
_indexByteBuffer = indices;
|
||||
|
||||
// store any buffers that will be manipulated on a per-instance basis
|
||||
storeOriginalBuffers();
|
||||
|
||||
// initialize the model if we're displaying
|
||||
setRenderStates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the vertices and the transform of the mesh so that the mesh's
|
||||
* position lies at the center of its bounding volume.
|
||||
@@ -209,27 +177,11 @@ public class ModelMesh extends TriMesh
|
||||
setTextureBuffer(0, getTextureBuffer(0, 0), ii);
|
||||
}
|
||||
|
||||
_vertexBufferSize = (vertices == null) ? 0 : vertices.capacity();
|
||||
_normalBufferSize = (normals == null) ? 0 : normals.capacity();
|
||||
_colorBufferSize = (colors == null) ? 0 : colors.capacity();
|
||||
_textureBufferSize = (textures == null) ? 0 : textures.capacity();
|
||||
_indexBufferSize = (indices == null) ? 0 : indices.capacity();
|
||||
}
|
||||
|
||||
@Override // documentation inherited
|
||||
public void reconstruct (
|
||||
FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors,
|
||||
FloatBuffer textures)
|
||||
{
|
||||
super.reconstruct(vertices, normals, colors, textures);
|
||||
for (int ii = 1, nn = getTextureCount(); ii < nn; ii++) {
|
||||
setTextureBuffer(0, getTextureBuffer(0, 0), ii);
|
||||
}
|
||||
// store any buffers that will be manipulated on a per-instance basis
|
||||
storeOriginalBuffers();
|
||||
|
||||
_vertexBufferSize = (vertices == null) ? 0 : vertices.capacity();
|
||||
_normalBufferSize = (normals == null) ? 0 : normals.capacity();
|
||||
_colorBufferSize = (colors == null) ? 0 : colors.capacity();
|
||||
_textureBufferSize = (textures == null) ? 0 : textures.capacity();
|
||||
// initialize the model if we're displaying
|
||||
setRenderStates();
|
||||
}
|
||||
|
||||
// documentation inherited from interface ModelSpatial
|
||||
@@ -331,56 +283,64 @@ public class ModelMesh extends TriMesh
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface Externalizable
|
||||
public void writeExternal (ObjectOutput out)
|
||||
@Override // documentation inherited
|
||||
public void read (JMEImporter im)
|
||||
throws IOException
|
||||
{
|
||||
out.writeUTF(getName());
|
||||
out.writeObject(getLocalTranslation());
|
||||
out.writeObject(getLocalRotation());
|
||||
out.writeObject(getLocalScale());
|
||||
out.writeObject(getBatch(0).getModelBound());
|
||||
out.writeInt(_vertexBufferSize);
|
||||
out.writeInt(_normalBufferSize);
|
||||
out.writeInt(_colorBufferSize);
|
||||
out.writeInt(_textureBufferSize);
|
||||
out.writeInt(_indexBufferSize);
|
||||
out.writeObject(_textureKey);
|
||||
out.writeObject(_textures);
|
||||
out.writeBoolean(_sphereMapped);
|
||||
out.writeInt(_filterMode);
|
||||
out.writeInt(_mipMapMode);
|
||||
out.writeObject(_emissiveMap);
|
||||
out.writeBoolean(_solid);
|
||||
out.writeBoolean(_transparent);
|
||||
out.writeFloat(_alphaThreshold);
|
||||
out.writeBoolean(_translucent);
|
||||
InputCapsule capsule = im.getCapsule(this);
|
||||
setName(capsule.readString("name", null));
|
||||
setLocalTranslation((Vector3f)capsule.readSavable(
|
||||
"localTranslation", null));
|
||||
setLocalRotation((Quaternion)capsule.readSavable(
|
||||
"localRotation", null));
|
||||
setLocalScale((Vector3f)capsule.readSavable(
|
||||
"localScale", null));
|
||||
TriangleBatch batch = (TriangleBatch)getBatch(0);
|
||||
batch.setModelBound((BoundingVolume)capsule.readSavable(
|
||||
"modelBound", null));
|
||||
_textureKey = capsule.readString("textureKey", null);
|
||||
_textures = capsule.readStringArray("textures", null);
|
||||
_sphereMapped = capsule.readBoolean("sphereMapped", false);
|
||||
_filterMode = capsule.readInt("filterMode", Texture.FM_LINEAR);
|
||||
_mipMapMode = capsule.readInt("mipMapMode", Texture.MM_LINEAR_LINEAR);
|
||||
_emissiveMap = capsule.readString("emissiveMap", null);
|
||||
_solid = capsule.readBoolean("solid", true);
|
||||
_transparent = capsule.readBoolean("transparent", false);
|
||||
_alphaThreshold = capsule.readFloat("alphaThreshold",
|
||||
DEFAULT_ALPHA_THRESHOLD);
|
||||
_translucent = capsule.readBoolean("translucent", false);
|
||||
|
||||
reconstruct(capsule.readFloatBuffer("vertexBuffer", null),
|
||||
capsule.readFloatBuffer("normalBuffer", null), null,
|
||||
capsule.readFloatBuffer("textureBuffer", null),
|
||||
capsule.readIntBuffer("indexBuffer", null));
|
||||
}
|
||||
|
||||
// documentation inherited from interface Externalizable
|
||||
public void readExternal (ObjectInput in)
|
||||
throws IOException, ClassNotFoundException
|
||||
@Override // documentation inherited
|
||||
public void write (JMEExporter ex)
|
||||
throws IOException
|
||||
{
|
||||
setName(in.readUTF());
|
||||
setLocalTranslation((Vector3f)in.readObject());
|
||||
setLocalRotation((Quaternion)in.readObject());
|
||||
setLocalScale((Vector3f)in.readObject());
|
||||
setModelBound((BoundingVolume)in.readObject());
|
||||
_vertexBufferSize = in.readInt();
|
||||
_normalBufferSize = in.readInt();
|
||||
_colorBufferSize = in.readInt();
|
||||
_textureBufferSize = in.readInt();
|
||||
_indexBufferSize = in.readInt();
|
||||
_textureKey = (String)in.readObject();
|
||||
_textures = (String[])in.readObject();
|
||||
_sphereMapped = in.readBoolean();
|
||||
_filterMode = in.readInt();
|
||||
_mipMapMode = in.readInt();
|
||||
_emissiveMap = (String)in.readObject();
|
||||
_solid = in.readBoolean();
|
||||
_transparent = in.readBoolean();
|
||||
_alphaThreshold = in.readFloat();
|
||||
_translucent = in.readBoolean();
|
||||
OutputCapsule capsule = ex.getCapsule(this);
|
||||
capsule.write(getName(), "name", null);
|
||||
capsule.write(getLocalTranslation(), "localTranslation", null);
|
||||
capsule.write(getLocalRotation(), "localRotation", null);
|
||||
capsule.write(getLocalScale(), "localScale", null);
|
||||
capsule.write(getBatch(0).getModelBound(), "modelBound", null);
|
||||
capsule.write(getVertexBuffer(0), "vertexBuffer", null);
|
||||
capsule.write(getNormalBuffer(0), "normalBuffer", null);
|
||||
capsule.write(getTextureBuffer(0, 0), "textureBuffer", null);
|
||||
capsule.write(getIndexBuffer(0), "indexBuffer", null);
|
||||
capsule.write(_textureKey, "textureKey", null);
|
||||
capsule.write(_textures, "textures", null);
|
||||
capsule.write(_sphereMapped, "sphereMapped", false);
|
||||
capsule.write(_filterMode, "filterMode", Texture.FM_LINEAR);
|
||||
capsule.write(_mipMapMode, "mipMapMode", Texture.MM_LINEAR_LINEAR);
|
||||
capsule.write(_emissiveMap, "emissiveMap", null);
|
||||
capsule.write(_solid, "solid", true);
|
||||
capsule.write(_transparent, "transparent", false);
|
||||
capsule.write(_alphaThreshold, "alphaThreshold",
|
||||
DEFAULT_ALPHA_THRESHOLD);
|
||||
capsule.write(_translucent, "translucent", false);
|
||||
}
|
||||
|
||||
// documentation inherited from interface ModelSpatial
|
||||
@@ -463,121 +423,6 @@ public class ModelMesh extends TriMesh
|
||||
// no-op
|
||||
}
|
||||
|
||||
// documentation inherited from interface ModelSpatial
|
||||
public void writeBuffers (FileChannel out)
|
||||
throws IOException
|
||||
{
|
||||
if (_vertexBufferSize > 0) {
|
||||
_vertexByteBuffer.rewind();
|
||||
convertOrder(_vertexByteBuffer, ByteOrder.LITTLE_ENDIAN);
|
||||
out.write(_vertexByteBuffer);
|
||||
convertOrder(_vertexByteBuffer, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_normalBufferSize > 0) {
|
||||
_normalByteBuffer.rewind();
|
||||
convertOrder(_normalByteBuffer, ByteOrder.LITTLE_ENDIAN);
|
||||
out.write(_normalByteBuffer);
|
||||
convertOrder(_normalByteBuffer, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_colorBufferSize > 0) {
|
||||
_colorByteBuffer.rewind();
|
||||
convertOrder(_colorByteBuffer, ByteOrder.LITTLE_ENDIAN);
|
||||
out.write(_colorByteBuffer);
|
||||
convertOrder(_colorByteBuffer, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_textureBufferSize > 0) {
|
||||
_textureByteBuffer.rewind();
|
||||
convertOrder(_textureByteBuffer, ByteOrder.LITTLE_ENDIAN);
|
||||
out.write(_textureByteBuffer);
|
||||
convertOrder(_textureByteBuffer, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_indexBufferSize > 0) {
|
||||
_indexByteBuffer.rewind();
|
||||
convertOrder(_indexByteBuffer, ByteOrder.LITTLE_ENDIAN);
|
||||
out.write(_indexByteBuffer);
|
||||
convertOrder(_indexByteBuffer, ByteOrder.nativeOrder());
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface ModelSpatial
|
||||
public void readBuffers (FileChannel in)
|
||||
throws IOException
|
||||
{
|
||||
ByteBuffer vbbuf = null, nbbuf = null, cbbuf = null, tbbuf = null,
|
||||
ibbuf = null;
|
||||
ByteOrder le = ByteOrder.LITTLE_ENDIAN;
|
||||
if (_vertexBufferSize > 0) {
|
||||
vbbuf = ByteBuffer.allocateDirect(_vertexBufferSize*4).order(le);
|
||||
in.read(vbbuf);
|
||||
vbbuf.rewind();
|
||||
convertOrder(vbbuf, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_normalBufferSize > 0) {
|
||||
nbbuf = ByteBuffer.allocateDirect(_normalBufferSize*4).order(le);
|
||||
in.read(nbbuf);
|
||||
nbbuf.rewind();
|
||||
convertOrder(nbbuf, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_colorBufferSize > 0) {
|
||||
cbbuf = ByteBuffer.allocateDirect(_colorBufferSize*4).order(le);
|
||||
in.read(cbbuf);
|
||||
cbbuf.rewind();
|
||||
convertOrder(cbbuf, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_textureBufferSize > 0) {
|
||||
tbbuf = ByteBuffer.allocateDirect(_textureBufferSize*4).order(le);
|
||||
in.read(tbbuf);
|
||||
tbbuf.rewind();
|
||||
convertOrder(tbbuf, ByteOrder.nativeOrder());
|
||||
}
|
||||
if (_indexBufferSize > 0) {
|
||||
ibbuf = ByteBuffer.allocateDirect(_indexBufferSize*4).order(le);
|
||||
in.read(ibbuf);
|
||||
ibbuf.rewind();
|
||||
convertOrder(ibbuf, ByteOrder.nativeOrder());
|
||||
}
|
||||
reconstruct(vbbuf, nbbuf, cbbuf, tbbuf, ibbuf);
|
||||
}
|
||||
|
||||
// documentation inherited from interface ModelSpatial
|
||||
public void sliceBuffers (MappedByteBuffer map)
|
||||
{
|
||||
ByteBuffer vbbuf = null, nbbuf = null, cbbuf = null, tbbuf = null,
|
||||
ibbuf = null;
|
||||
int total = 0;
|
||||
if (_vertexBufferSize > 0) {
|
||||
int npos = map.position() + _vertexBufferSize*4;
|
||||
map.limit(npos);
|
||||
vbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
map.position(npos);
|
||||
}
|
||||
if (_normalBufferSize > 0) {
|
||||
int npos = map.position() + _normalBufferSize*4;
|
||||
map.limit(npos);
|
||||
nbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
map.position(npos);
|
||||
}
|
||||
if (_colorBufferSize > 0) {
|
||||
int npos = map.position() + _colorBufferSize*4;
|
||||
map.limit(npos);
|
||||
cbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
map.position(npos);
|
||||
}
|
||||
if (_textureBufferSize > 0) {
|
||||
int npos = map.position() + _textureBufferSize*4;
|
||||
map.limit(npos);
|
||||
tbbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
map.position(npos);
|
||||
}
|
||||
if (_indexBufferSize > 0) {
|
||||
int npos = map.position() + _indexBufferSize*4;
|
||||
map.limit(npos);
|
||||
ibbuf = map.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
map.position(npos);
|
||||
}
|
||||
reconstruct(vbbuf, nbbuf, cbbuf, tbbuf, ibbuf);
|
||||
}
|
||||
|
||||
@Override // documentation inherited
|
||||
protected void setupBatchList ()
|
||||
{
|
||||
@@ -675,21 +520,6 @@ public class ModelMesh extends TriMesh
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imposes the specified order on the given buffer of 32 bit values.
|
||||
*/
|
||||
protected static void convertOrder (ByteBuffer buf, ByteOrder order)
|
||||
{
|
||||
if (buf.order() == order) {
|
||||
return;
|
||||
}
|
||||
IntBuffer obuf = buf.asIntBuffer(),
|
||||
nbuf = buf.order(order).asIntBuffer();
|
||||
while (obuf.hasRemaining()) {
|
||||
nbuf.put(obuf.get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the states shared between all models. Requires an active
|
||||
* display.
|
||||
@@ -879,14 +709,6 @@ public class ModelMesh extends TriMesh
|
||||
new RenderState[RenderState.RS_MAX_STATE];
|
||||
}
|
||||
|
||||
/** The sizes of the various buffers (zero for <code>null</code>). */
|
||||
protected int _vertexBufferSize, _normalBufferSize, _colorBufferSize,
|
||||
_textureBufferSize, _indexBufferSize;
|
||||
|
||||
/** The backing byte buffers for the various buffers. */
|
||||
protected ByteBuffer _vertexByteBuffer, _normalByteBuffer,
|
||||
_colorByteBuffer, _textureByteBuffer, _indexByteBuffer;
|
||||
|
||||
/** The type of bounding volume that this mesh should use. */
|
||||
protected int _boundingType;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user