|
@@ -29,11 +29,11 @@
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
*/
|
|
|
-
|
|
|
package com.jme3.scene.plugins.ogre;
|
|
|
|
|
|
import com.jme3.animation.AnimControl;
|
|
|
import com.jme3.animation.BoneAnimation;
|
|
|
+import com.jme3.animation.SkeletonControl;
|
|
|
import com.jme3.asset.AssetInfo;
|
|
|
import com.jme3.asset.AssetKey;
|
|
|
import com.jme3.asset.AssetLoader;
|
|
@@ -81,15 +81,12 @@ import static com.jme3.util.xml.SAXUtil.*;
|
|
|
public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
|
|
|
private static final Logger logger = Logger.getLogger(MeshLoader.class.getName());
|
|
|
-
|
|
|
public static boolean AUTO_INTERLEAVE = true;
|
|
|
public static boolean HARDWARE_SKINNING = false;
|
|
|
-
|
|
|
private String meshName;
|
|
|
private String folderName;
|
|
|
private AssetManager assetManager;
|
|
|
private MaterialList materialList;
|
|
|
-
|
|
|
private ShortBuffer sb;
|
|
|
private IntBuffer ib;
|
|
|
private FloatBuffer fb;
|
|
@@ -105,16 +102,14 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
private boolean bigindices = false;
|
|
|
private int vertCount;
|
|
|
private int triCount;
|
|
|
-
|
|
|
private List<Geometry> geoms = new ArrayList<Geometry>();
|
|
|
private List<Boolean> usesSharedGeom = new ArrayList<Boolean>();
|
|
|
private IntMap<List<VertexBuffer>> lodLevels = new IntMap<List<VertexBuffer>>();
|
|
|
private AnimData animData;
|
|
|
-
|
|
|
private ByteBuffer indicesData;
|
|
|
private FloatBuffer weightsFloatData;
|
|
|
|
|
|
- public MeshLoader(){
|
|
|
+ public MeshLoader() {
|
|
|
super();
|
|
|
}
|
|
|
|
|
@@ -150,44 +145,44 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
public void endDocument() {
|
|
|
}
|
|
|
|
|
|
- private void pushFace(String v1, String v2, String v3) throws SAXException{
|
|
|
+ private void pushFace(String v1, String v2, String v3) throws SAXException {
|
|
|
int i1 = parseInt(v1);
|
|
|
|
|
|
// TODO: fan/strip support
|
|
|
int i2 = parseInt(v2);
|
|
|
int i3 = parseInt(v3);
|
|
|
- if (ib != null){
|
|
|
+ if (ib != null) {
|
|
|
ib.put(i1).put(i2).put(i3);
|
|
|
- }else{
|
|
|
- sb.put((short)i1).put((short)i2).put((short)i3);
|
|
|
+ } else {
|
|
|
+ sb.put((short) i1).put((short) i2).put((short) i3);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void startFaces(String count) throws SAXException{
|
|
|
+ private void startFaces(String count) throws SAXException {
|
|
|
int numFaces = parseInt(count);
|
|
|
int numIndices;
|
|
|
|
|
|
- if (mesh.getMode() == Mesh.Mode.Triangles){
|
|
|
+ if (mesh.getMode() == Mesh.Mode.Triangles) {
|
|
|
//mesh.setTriangleCount(numFaces);
|
|
|
numIndices = numFaces * 3;
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
throw new SAXException("Triangle strip or fan not supported!");
|
|
|
}
|
|
|
|
|
|
int numVerts;
|
|
|
- if (usesSharedGeom.size() > 0 && usesSharedGeom.get(geoms.size()-1)){
|
|
|
+ if (usesSharedGeom.size() > 0 && usesSharedGeom.get(geoms.size() - 1)) {
|
|
|
// sharedgeom.getMesh().updateCounts();
|
|
|
numVerts = sharedmesh.getVertexCount();
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
// mesh.updateCounts();
|
|
|
numVerts = mesh.getVertexCount();
|
|
|
}
|
|
|
vb = new VertexBuffer(VertexBuffer.Type.Index);
|
|
|
- if (!bigindices){
|
|
|
+ if (!bigindices) {
|
|
|
sb = BufferUtils.createShortBuffer(numIndices);
|
|
|
ib = null;
|
|
|
vb.setupData(Usage.Static, 3, Format.UnsignedShort, sb);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
ib = BufferUtils.createIntBuffer(numIndices);
|
|
|
sb = null;
|
|
|
vb.setupData(Usage.Static, 3, Format.UnsignedInt, ib);
|
|
@@ -195,77 +190,81 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
mesh.setBuffer(vb);
|
|
|
}
|
|
|
|
|
|
- private void applyMaterial(Geometry geom, String matName){
|
|
|
+ private void applyMaterial(Geometry geom, String matName) {
|
|
|
Material mat = null;
|
|
|
- if (matName.endsWith(".j3m")){
|
|
|
+ if (matName.endsWith(".j3m")) {
|
|
|
// load as native jme3 material instance
|
|
|
mat = assetManager.loadMaterial(matName);
|
|
|
- }else{
|
|
|
- if (materialList != null){
|
|
|
+ } else {
|
|
|
+ if (materialList != null) {
|
|
|
mat = materialList.get(matName);
|
|
|
}
|
|
|
- if (mat == null){
|
|
|
+ if (mat == null) {
|
|
|
logger.log(Level.WARNING, "Material {0} not found. Applying default material", matName);
|
|
|
mat = (Material) assetManager.loadAsset(new AssetKey("Common/Materials/RedColor.j3m"));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- if (mat == null)
|
|
|
+
|
|
|
+ if (mat == null) {
|
|
|
throw new RuntimeException("Cannot locate material named " + matName);
|
|
|
+ }
|
|
|
|
|
|
- if (mat.isTransparent())
|
|
|
+ if (mat.isTransparent()) {
|
|
|
geom.setQueueBucket(Bucket.Transparent);
|
|
|
+ }
|
|
|
// else
|
|
|
// geom.setShadowMode(ShadowMode.CastAndReceive);
|
|
|
-
|
|
|
+
|
|
|
// if (mat.isReceivesShadows())
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
geom.setMaterial(mat);
|
|
|
}
|
|
|
|
|
|
- private void startMesh(String matName, String usesharedvertices, String use32bitIndices, String opType) throws SAXException{
|
|
|
+ private void startMesh(String matName, String usesharedvertices, String use32bitIndices, String opType) throws SAXException {
|
|
|
mesh = new Mesh();
|
|
|
- if (opType == null || opType.equals("triangle_list")){
|
|
|
+ if (opType == null || opType.equals("triangle_list")) {
|
|
|
mesh.setMode(Mesh.Mode.Triangles);
|
|
|
- }else if (opType.equals("triangle_strip")){
|
|
|
+ } else if (opType.equals("triangle_strip")) {
|
|
|
mesh.setMode(Mesh.Mode.TriangleStrip);
|
|
|
- }else if (opType.equals("triangle_fan")){
|
|
|
+ } else if (opType.equals("triangle_fan")) {
|
|
|
mesh.setMode(Mesh.Mode.TriangleFan);
|
|
|
}
|
|
|
|
|
|
bigindices = parseBool(use32bitIndices, false);
|
|
|
boolean sharedverts = parseBool(usesharedvertices, false);
|
|
|
- if (sharedverts){
|
|
|
+ if (sharedverts) {
|
|
|
usesSharedGeom.add(true);
|
|
|
// import vertexbuffers from shared geom
|
|
|
IntMap<VertexBuffer> sharedBufs = sharedmesh.getBuffers();
|
|
|
- for (Entry<VertexBuffer> entry : sharedBufs){
|
|
|
- mesh.setBuffer(entry.getValue());
|
|
|
+ for (Entry<VertexBuffer> entry : sharedBufs) {
|
|
|
+ mesh.setBuffer(entry.getValue());
|
|
|
}
|
|
|
// this mesh is shared!
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
usesSharedGeom.add(false);
|
|
|
}
|
|
|
|
|
|
- if (meshName == null)
|
|
|
- geom = new Geometry("OgreSubmesh-"+(++geomIdx), mesh);
|
|
|
- else
|
|
|
- geom = new Geometry(meshName+"-geom-"+(++geomIdx), mesh);
|
|
|
+ if (meshName == null) {
|
|
|
+ geom = new Geometry("OgreSubmesh-" + (++geomIdx), mesh);
|
|
|
+ } else {
|
|
|
+ geom = new Geometry(meshName + "-geom-" + (++geomIdx), mesh);
|
|
|
+ }
|
|
|
|
|
|
applyMaterial(geom, matName);
|
|
|
geoms.add(geom);
|
|
|
}
|
|
|
|
|
|
- private void startSharedGeom(String vertexcount) throws SAXException{
|
|
|
+ private void startSharedGeom(String vertexcount) throws SAXException {
|
|
|
sharedmesh = new Mesh();
|
|
|
vertCount = parseInt(vertexcount);
|
|
|
// sharedmesh.setVertexCount(vertCount);
|
|
|
|
|
|
- if (meshName == null)
|
|
|
+ if (meshName == null) {
|
|
|
sharedgeom = new Geometry("Ogre-SharedGeom", sharedmesh);
|
|
|
- else
|
|
|
- sharedgeom = new Geometry(meshName+"-sharedgeom", sharedmesh);
|
|
|
+ } else {
|
|
|
+ sharedgeom = new Geometry(meshName + "-sharedgeom", sharedmesh);
|
|
|
+ }
|
|
|
|
|
|
sharedgeom.setCullHint(CullHint.Always);
|
|
|
geoms.add(sharedgeom);
|
|
@@ -275,7 +274,7 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
mesh = sharedmesh;
|
|
|
}
|
|
|
|
|
|
- private void startGeometry(String vertexcount) throws SAXException{
|
|
|
+ private void startGeometry(String vertexcount) throws SAXException {
|
|
|
vertCount = parseInt(vertexcount);
|
|
|
// mesh.setVertexCount(vertCount);
|
|
|
}
|
|
@@ -284,51 +283,51 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
* Normalizes weights if needed and finds largest amount of weights used
|
|
|
* for all vertices in the buffer.
|
|
|
*/
|
|
|
- private void endBoneAssigns(){
|
|
|
- if (mesh != sharedmesh && usesSharedGeom.get(geoms.size() - 1)){
|
|
|
+ private void endBoneAssigns() {
|
|
|
+ if (mesh != sharedmesh && usesSharedGeom.get(geoms.size() - 1)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//int vertCount = mesh.getVertexCount();
|
|
|
int maxWeightsPerVert = 0;
|
|
|
weightsFloatData.rewind();
|
|
|
- for (int v = 0; v < vertCount; v++){
|
|
|
+ for (int v = 0; v < vertCount; v++) {
|
|
|
float w0 = weightsFloatData.get(),
|
|
|
- w1 = weightsFloatData.get(),
|
|
|
- w2 = weightsFloatData.get(),
|
|
|
- w3 = weightsFloatData.get();
|
|
|
+ w1 = weightsFloatData.get(),
|
|
|
+ w2 = weightsFloatData.get(),
|
|
|
+ w3 = weightsFloatData.get();
|
|
|
|
|
|
- if (w3 != 0){
|
|
|
+ if (w3 != 0) {
|
|
|
maxWeightsPerVert = Math.max(maxWeightsPerVert, 4);
|
|
|
- }else if (w2 != 0){
|
|
|
+ } else if (w2 != 0) {
|
|
|
maxWeightsPerVert = Math.max(maxWeightsPerVert, 3);
|
|
|
- }else if (w1 != 0){
|
|
|
+ } else if (w1 != 0) {
|
|
|
maxWeightsPerVert = Math.max(maxWeightsPerVert, 2);
|
|
|
- }else if (w0 != 0){
|
|
|
+ } else if (w0 != 0) {
|
|
|
maxWeightsPerVert = Math.max(maxWeightsPerVert, 1);
|
|
|
}
|
|
|
|
|
|
float sum = w0 + w1 + w2 + w3;
|
|
|
- if (sum != 1f){
|
|
|
- weightsFloatData.position(weightsFloatData.position()-4);
|
|
|
+ if (sum != 1f) {
|
|
|
+ weightsFloatData.position(weightsFloatData.position() - 4);
|
|
|
// compute new vals based on sum
|
|
|
float sumToB = 1f / sum;
|
|
|
- weightsFloatData.put( w0 * sumToB );
|
|
|
- weightsFloatData.put( w1 * sumToB );
|
|
|
- weightsFloatData.put( w2 * sumToB );
|
|
|
- weightsFloatData.put( w3 * sumToB );
|
|
|
+ weightsFloatData.put(w0 * sumToB);
|
|
|
+ weightsFloatData.put(w1 * sumToB);
|
|
|
+ weightsFloatData.put(w2 * sumToB);
|
|
|
+ weightsFloatData.put(w3 * sumToB);
|
|
|
}
|
|
|
}
|
|
|
weightsFloatData.rewind();
|
|
|
|
|
|
weightsFloatData = null;
|
|
|
indicesData = null;
|
|
|
-
|
|
|
+
|
|
|
mesh.setMaxNumWeights(maxWeightsPerVert);
|
|
|
}
|
|
|
|
|
|
- private void startBoneAssigns(){
|
|
|
- if (mesh != sharedmesh && usesSharedGeom.get(geoms.size() - 1)){
|
|
|
+ private void startBoneAssigns() {
|
|
|
+ if (mesh != sharedmesh && usesSharedGeom.get(geoms.size() - 1)) {
|
|
|
// will use bone assignments from shared mesh (?)
|
|
|
return;
|
|
|
}
|
|
@@ -338,53 +337,53 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
// each vertex has
|
|
|
// - 4 bone weights
|
|
|
// - 4 bone indices
|
|
|
- if (HARDWARE_SKINNING){
|
|
|
+ if (HARDWARE_SKINNING) {
|
|
|
weightsFloatData = BufferUtils.createFloatBuffer(vertCount * 4);
|
|
|
indicesData = BufferUtils.createByteBuffer(vertCount * 4);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
// create array-backed buffers if software skinning for access speed
|
|
|
weightsFloatData = FloatBuffer.allocate(vertCount * 4);
|
|
|
indicesData = ByteBuffer.allocate(vertCount * 4);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
VertexBuffer weights = new VertexBuffer(Type.BoneWeight);
|
|
|
VertexBuffer indices = new VertexBuffer(Type.BoneIndex);
|
|
|
|
|
|
Usage usage = HARDWARE_SKINNING ? Usage.Static : Usage.CpuOnly;
|
|
|
weights.setupData(usage, 4, Format.Float, weightsFloatData);
|
|
|
indices.setupData(usage, 4, Format.UnsignedByte, indicesData);
|
|
|
-
|
|
|
+
|
|
|
mesh.setBuffer(weights);
|
|
|
mesh.setBuffer(indices);
|
|
|
}
|
|
|
|
|
|
- private void startVertexBuffer(Attributes attribs) throws SAXException{
|
|
|
- if (parseBool(attribs.getValue("positions"), false)){
|
|
|
+ private void startVertexBuffer(Attributes attribs) throws SAXException {
|
|
|
+ if (parseBool(attribs.getValue("positions"), false)) {
|
|
|
vb = new VertexBuffer(Type.Position);
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * 3);
|
|
|
vb.setupData(Usage.Static, 3, Format.Float, fb);
|
|
|
mesh.setBuffer(vb);
|
|
|
}
|
|
|
- if (parseBool(attribs.getValue("normals"), false)){
|
|
|
+ if (parseBool(attribs.getValue("normals"), false)) {
|
|
|
vb = new VertexBuffer(Type.Normal);
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * 3);
|
|
|
vb.setupData(Usage.Static, 3, Format.Float, fb);
|
|
|
mesh.setBuffer(vb);
|
|
|
}
|
|
|
- if (parseBool(attribs.getValue("colours_diffuse"), false)){
|
|
|
+ if (parseBool(attribs.getValue("colours_diffuse"), false)) {
|
|
|
vb = new VertexBuffer(Type.Color);
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * 4);
|
|
|
vb.setupData(Usage.Static, 4, Format.Float, fb);
|
|
|
mesh.setBuffer(vb);
|
|
|
}
|
|
|
- if (parseBool(attribs.getValue("tangents"), false)){
|
|
|
+ if (parseBool(attribs.getValue("tangents"), false)) {
|
|
|
int dimensions = parseInt(attribs.getValue("tangent_dimensions"), 3);
|
|
|
vb = new VertexBuffer(Type.Tangent);
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * dimensions);
|
|
|
vb.setupData(Usage.Static, dimensions, Format.Float, fb);
|
|
|
mesh.setBuffer(vb);
|
|
|
}
|
|
|
- if (parseBool(attribs.getValue("binormals"), false)){
|
|
|
+ if (parseBool(attribs.getValue("binormals"), false)) {
|
|
|
vb = new VertexBuffer(Type.Binormal);
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * 3);
|
|
|
vb.setupData(Usage.Static, 3, Format.Float, fb);
|
|
@@ -392,17 +391,19 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
}
|
|
|
|
|
|
int texCoords = parseInt(attribs.getValue("texture_coords"), 0);
|
|
|
- for (int i = 0; i < texCoords; i++){
|
|
|
+ for (int i = 0; i < texCoords; i++) {
|
|
|
int dims = parseInt(attribs.getValue("texture_coord_dimensions_" + i), 2);
|
|
|
- if (dims < 1 || dims > 4)
|
|
|
+ if (dims < 1 || dims > 4) {
|
|
|
throw new SAXException("Texture coord dimensions must be 1 <= dims <= 4");
|
|
|
+ }
|
|
|
|
|
|
- if (i >= 2)
|
|
|
+ if (i >= 2) {
|
|
|
throw new SAXException("More than 2 texture coordinates not supported");
|
|
|
+ }
|
|
|
|
|
|
- if (i == 0){
|
|
|
+ if (i == 0) {
|
|
|
vb = new VertexBuffer(Type.TexCoord);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
vb = new VertexBuffer(Type.TexCoord2);
|
|
|
}
|
|
|
fb = BufferUtils.createFloatBuffer(vertCount * dims);
|
|
@@ -411,51 +412,47 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void startVertex(){
|
|
|
+ private void startVertex() {
|
|
|
texCoordIdx = 0;
|
|
|
}
|
|
|
|
|
|
- private void pushAttrib(Type type, Attributes attribs) throws SAXException{
|
|
|
+ private void pushAttrib(Type type, Attributes attribs) throws SAXException {
|
|
|
try {
|
|
|
FloatBuffer buf = (FloatBuffer) mesh.getBuffer(type).getData();
|
|
|
- buf.put(parseFloat(attribs.getValue("x")))
|
|
|
- .put(parseFloat(attribs.getValue("y")))
|
|
|
- .put(parseFloat(attribs.getValue("z")));
|
|
|
- } catch (Exception ex){
|
|
|
- throw new SAXException("Failed to push attrib", ex);
|
|
|
+ buf.put(parseFloat(attribs.getValue("x"))).put(parseFloat(attribs.getValue("y"))).put(parseFloat(attribs.getValue("z")));
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw new SAXException("Failed to push attrib", ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void pushTangent(Attributes attribs) throws SAXException{
|
|
|
+ private void pushTangent(Attributes attribs) throws SAXException {
|
|
|
try {
|
|
|
VertexBuffer tangentBuf = mesh.getBuffer(Type.Tangent);
|
|
|
FloatBuffer buf = (FloatBuffer) tangentBuf.getData();
|
|
|
- buf.put(parseFloat(attribs.getValue("x")))
|
|
|
- .put(parseFloat(attribs.getValue("y")))
|
|
|
- .put(parseFloat(attribs.getValue("z")));
|
|
|
- if (tangentBuf.getNumComponents() == 4){
|
|
|
+ buf.put(parseFloat(attribs.getValue("x"))).put(parseFloat(attribs.getValue("y"))).put(parseFloat(attribs.getValue("z")));
|
|
|
+ if (tangentBuf.getNumComponents() == 4) {
|
|
|
buf.put(parseFloat(attribs.getValue("w")));
|
|
|
}
|
|
|
- } catch (Exception ex){
|
|
|
- throw new SAXException("Failed to push attrib", ex);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw new SAXException("Failed to push attrib", ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void pushTexCoord(Attributes attribs) throws SAXException{
|
|
|
- if (texCoordIdx >= 2)
|
|
|
+ private void pushTexCoord(Attributes attribs) throws SAXException {
|
|
|
+ if (texCoordIdx >= 2) {
|
|
|
return; // TODO: More than 2 texcoords
|
|
|
-
|
|
|
+ }
|
|
|
Type type = texCoordIdx == 0 ? Type.TexCoord : Type.TexCoord2;
|
|
|
-
|
|
|
+
|
|
|
VertexBuffer tcvb = mesh.getBuffer(type);
|
|
|
FloatBuffer buf = (FloatBuffer) tcvb.getData();
|
|
|
|
|
|
buf.put(parseFloat(attribs.getValue("u")));
|
|
|
- if (tcvb.getNumComponents() >= 2){
|
|
|
+ if (tcvb.getNumComponents() >= 2) {
|
|
|
buf.put(parseFloat(attribs.getValue("v")));
|
|
|
- if (tcvb.getNumComponents() >= 3){
|
|
|
+ if (tcvb.getNumComponents() >= 3) {
|
|
|
buf.put(parseFloat(attribs.getValue("w")));
|
|
|
- if (tcvb.getNumComponents() == 4){
|
|
|
+ if (tcvb.getNumComponents() == 4) {
|
|
|
buf.put(parseFloat(attribs.getValue("x")));
|
|
|
}
|
|
|
}
|
|
@@ -464,36 +461,38 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
texCoordIdx++;
|
|
|
}
|
|
|
|
|
|
- private void pushColor(Attributes attribs) throws SAXException{
|
|
|
+ private void pushColor(Attributes attribs) throws SAXException {
|
|
|
FloatBuffer buf = (FloatBuffer) mesh.getBuffer(Type.Color).getData();
|
|
|
String value = parseString(attribs.getValue("value"));
|
|
|
String[] vals = value.split(" ");
|
|
|
- if (vals.length != 3 && vals.length != 4)
|
|
|
+ if (vals.length != 3 && vals.length != 4) {
|
|
|
throw new SAXException("Color value must contain 3 or 4 components");
|
|
|
+ }
|
|
|
|
|
|
ColorRGBA color = new ColorRGBA();
|
|
|
color.r = parseFloat(vals[0]);
|
|
|
color.g = parseFloat(vals[1]);
|
|
|
color.b = parseFloat(vals[2]);
|
|
|
- if (vals.length == 3)
|
|
|
+ if (vals.length == 3) {
|
|
|
color.a = 1f;
|
|
|
- else
|
|
|
+ } else {
|
|
|
color.a = parseFloat(vals[3]);
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
buf.put(color.r).put(color.g).put(color.b).put(color.a);
|
|
|
}
|
|
|
|
|
|
- private void startLodFaceList(String submeshindex, String numfaces){
|
|
|
+ private void startLodFaceList(String submeshindex, String numfaces) {
|
|
|
int index = Integer.parseInt(submeshindex);
|
|
|
int faceCount = Integer.parseInt(numfaces);
|
|
|
-
|
|
|
+
|
|
|
vb = new VertexBuffer(VertexBuffer.Type.Index);
|
|
|
sb = BufferUtils.createShortBuffer(faceCount * 3);
|
|
|
ib = null;
|
|
|
vb.setupData(Usage.Static, 3, Format.UnsignedShort, sb);
|
|
|
|
|
|
List<VertexBuffer> levels = lodLevels.get(index);
|
|
|
- if (levels == null){
|
|
|
+ if (levels == null) {
|
|
|
levels = new ArrayList<VertexBuffer>();
|
|
|
Mesh submesh = geoms.get(index).getMesh();
|
|
|
levels.add(submesh.getBuffer(Type.Index));
|
|
@@ -503,13 +502,13 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
levels.add(vb);
|
|
|
}
|
|
|
|
|
|
- private void startLevelOfDetail(String numlevels){
|
|
|
+ private void startLevelOfDetail(String numlevels) {
|
|
|
// numLevels = Integer.parseInt(numlevels);
|
|
|
}
|
|
|
|
|
|
- private void endLevelOfDetail(){
|
|
|
+ private void endLevelOfDetail() {
|
|
|
// set the lod data for each mesh
|
|
|
- for (Entry<List<VertexBuffer>> entry : lodLevels){
|
|
|
+ for (Entry<List<VertexBuffer>> entry : lodLevels) {
|
|
|
Mesh m = geoms.get(entry.getKey()).getMesh();
|
|
|
List<VertexBuffer> levels = entry.getValue();
|
|
|
VertexBuffer[] levelArray = new VertexBuffer[levels.size()];
|
|
@@ -518,11 +517,11 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void startLodGenerated(String depthsqr){
|
|
|
+ private void startLodGenerated(String depthsqr) {
|
|
|
// dist = Float.parseFloat(depthsqr);
|
|
|
}
|
|
|
|
|
|
- private void pushBoneAssign(String vertIndex, String boneIndex, String weight) throws SAXException{
|
|
|
+ private void pushBoneAssign(String vertIndex, String boneIndex, String weight) throws SAXException {
|
|
|
int vert = parseInt(vertIndex);
|
|
|
float w = parseFloat(weight);
|
|
|
byte bone = (byte) parseInt(boneIndex);
|
|
@@ -532,95 +531,101 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
|
|
|
int i;
|
|
|
// see which weights are unused for a given bone
|
|
|
- for (i = vert * 4; i < vert * 4 + 4; i++){
|
|
|
+ for (i = vert * 4; i < vert * 4 + 4; i++) {
|
|
|
float v = weightsFloatData.get(i);
|
|
|
- if (v == 0)
|
|
|
+ if (v == 0) {
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
weightsFloatData.put(i, w);
|
|
|
indicesData.put(i, bone);
|
|
|
}
|
|
|
|
|
|
- private void startSkeleton(String name){
|
|
|
+ private void startSkeleton(String name) {
|
|
|
animData = (AnimData) assetManager.loadAsset(folderName + name + ".xml");
|
|
|
//TODO:workaround for meshxml / mesh.xml
|
|
|
- if(animData==null)
|
|
|
+ if (animData == null) {
|
|
|
animData = (AnimData) assetManager.loadAsset(folderName + name + "xml");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private void startSubmeshName(String indexStr, String nameStr){
|
|
|
+ private void startSubmeshName(String indexStr, String nameStr) {
|
|
|
int index = Integer.parseInt(indexStr);
|
|
|
geoms.get(index).setName(nameStr);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void startElement(String uri, String localName, String qName, Attributes attribs) throws SAXException{
|
|
|
- if (ignoreUntilEnd != null)
|
|
|
+ public void startElement(String uri, String localName, String qName, Attributes attribs) throws SAXException {
|
|
|
+ if (ignoreUntilEnd != null) {
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
- if (qName.equals("texcoord")){
|
|
|
+ if (qName.equals("texcoord")) {
|
|
|
pushTexCoord(attribs);
|
|
|
- }else if (qName.equals("vertexboneassignment")){
|
|
|
+ } else if (qName.equals("vertexboneassignment")) {
|
|
|
pushBoneAssign(attribs.getValue("vertexindex"),
|
|
|
- attribs.getValue("boneindex"),
|
|
|
- attribs.getValue("weight"));
|
|
|
- }else if (qName.equals("face")){
|
|
|
+ attribs.getValue("boneindex"),
|
|
|
+ attribs.getValue("weight"));
|
|
|
+ } else if (qName.equals("face")) {
|
|
|
pushFace(attribs.getValue("v1"),
|
|
|
- attribs.getValue("v2"),
|
|
|
- attribs.getValue("v3"));
|
|
|
- }else if (qName.equals("position")){
|
|
|
+ attribs.getValue("v2"),
|
|
|
+ attribs.getValue("v3"));
|
|
|
+ } else if (qName.equals("position")) {
|
|
|
pushAttrib(Type.Position, attribs);
|
|
|
- }else if (qName.equals("normal")){
|
|
|
+ } else if (qName.equals("normal")) {
|
|
|
pushAttrib(Type.Normal, attribs);
|
|
|
- }else if (qName.equals("tangent")){
|
|
|
+ } else if (qName.equals("tangent")) {
|
|
|
pushTangent(attribs);
|
|
|
- }else if (qName.equals("binormal")){
|
|
|
+ } else if (qName.equals("binormal")) {
|
|
|
pushAttrib(Type.Binormal, attribs);
|
|
|
- }else if (qName.equals("colour_diffuse")){
|
|
|
+ } else if (qName.equals("colour_diffuse")) {
|
|
|
pushColor(attribs);
|
|
|
- }else if (qName.equals("vertex")){
|
|
|
- startVertex();
|
|
|
- }else if (qName.equals("faces")){
|
|
|
+ } else if (qName.equals("vertex")) {
|
|
|
+ startVertex();
|
|
|
+ } else if (qName.equals("faces")) {
|
|
|
startFaces(attribs.getValue("count"));
|
|
|
- }else if (qName.equals("geometry")){
|
|
|
+ } else if (qName.equals("geometry")) {
|
|
|
String count = attribs.getValue("vertexcount");
|
|
|
- if (count == null)
|
|
|
+ if (count == null) {
|
|
|
count = attribs.getValue("count");
|
|
|
+ }
|
|
|
|
|
|
startGeometry(count);
|
|
|
- }else if (qName.equals("vertexbuffer")){
|
|
|
+ } else if (qName.equals("vertexbuffer")) {
|
|
|
startVertexBuffer(attribs);
|
|
|
- }else if (qName.equals("lodfacelist")){
|
|
|
+ } else if (qName.equals("lodfacelist")) {
|
|
|
startLodFaceList(attribs.getValue("submeshindex"),
|
|
|
- attribs.getValue("numfaces"));
|
|
|
- }else if (qName.equals("lodgenerated")){
|
|
|
+ attribs.getValue("numfaces"));
|
|
|
+ } else if (qName.equals("lodgenerated")) {
|
|
|
startLodGenerated(attribs.getValue("fromdepthsquared"));
|
|
|
- }else if (qName.equals("levelofdetail")){
|
|
|
+ } else if (qName.equals("levelofdetail")) {
|
|
|
startLevelOfDetail(attribs.getValue("numlevels"));
|
|
|
- }else if (qName.equals("boneassignments")){
|
|
|
+ } else if (qName.equals("boneassignments")) {
|
|
|
startBoneAssigns();
|
|
|
- }else if (qName.equals("submesh")){
|
|
|
+ } else if (qName.equals("submesh")) {
|
|
|
startMesh(attribs.getValue("material"),
|
|
|
- attribs.getValue("usesharedvertices"),
|
|
|
- attribs.getValue("use32bitindexes"),
|
|
|
- attribs.getValue("operationtype"));
|
|
|
- }else if (qName.equals("sharedgeometry")){
|
|
|
+ attribs.getValue("usesharedvertices"),
|
|
|
+ attribs.getValue("use32bitindexes"),
|
|
|
+ attribs.getValue("operationtype"));
|
|
|
+ } else if (qName.equals("sharedgeometry")) {
|
|
|
String count = attribs.getValue("vertexcount");
|
|
|
- if (count == null)
|
|
|
+ if (count == null) {
|
|
|
count = attribs.getValue("count");
|
|
|
+ }
|
|
|
|
|
|
- if (count != null && !count.equals("0"))
|
|
|
+ if (count != null && !count.equals("0")) {
|
|
|
startSharedGeom(count);
|
|
|
- }else if (qName.equals("submeshes")){
|
|
|
+ }
|
|
|
+ } else if (qName.equals("submeshes")) {
|
|
|
// ok
|
|
|
- }else if (qName.equals("skeletonlink")){
|
|
|
+ } else if (qName.equals("skeletonlink")) {
|
|
|
startSkeleton(attribs.getValue("name"));
|
|
|
- }else if (qName.equals("submeshname")){
|
|
|
+ } else if (qName.equals("submeshname")) {
|
|
|
startSubmeshName(attribs.getValue("index"), attribs.getValue("name"));
|
|
|
- }else if (qName.equals("mesh")){
|
|
|
+ } else if (qName.equals("mesh")) {
|
|
|
// ok
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
logger.log(Level.WARNING, "Unknown tag: {0}. Ignoring.", qName);
|
|
|
ignoreUntilEnd = qName;
|
|
|
}
|
|
@@ -628,56 +633,59 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
|
|
|
@Override
|
|
|
public void endElement(String uri, String name, String qName) {
|
|
|
- if (ignoreUntilEnd != null){
|
|
|
- if (ignoreUntilEnd.equals(qName))
|
|
|
+ if (ignoreUntilEnd != null) {
|
|
|
+ if (ignoreUntilEnd.equals(qName)) {
|
|
|
ignoreUntilEnd = null;
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (qName.equals("submesh")){
|
|
|
+ if (qName.equals("submesh")) {
|
|
|
bigindices = false;
|
|
|
geom = null;
|
|
|
mesh = null;
|
|
|
- }else if (qName.equals("submeshes")){
|
|
|
+ } else if (qName.equals("submeshes")) {
|
|
|
// IMPORTANT: restore sharedgeoemtry, for use with shared boneweights
|
|
|
geom = sharedgeom;
|
|
|
mesh = sharedmesh;
|
|
|
- }else if (qName.equals("faces")){
|
|
|
- if (ib != null)
|
|
|
+ } else if (qName.equals("faces")) {
|
|
|
+ if (ib != null) {
|
|
|
ib.flip();
|
|
|
- else
|
|
|
+ } else {
|
|
|
sb.flip();
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
vb = null;
|
|
|
ib = null;
|
|
|
sb = null;
|
|
|
- }else if (qName.equals("vertexbuffer")){
|
|
|
+ } else if (qName.equals("vertexbuffer")) {
|
|
|
fb = null;
|
|
|
vb = null;
|
|
|
- }else if (qName.equals("geometry")
|
|
|
- || qName.equals("sharedgeometry")){
|
|
|
+ } else if (qName.equals("geometry")
|
|
|
+ || qName.equals("sharedgeometry")) {
|
|
|
// finish writing to buffers
|
|
|
IntMap<VertexBuffer> bufs = mesh.getBuffers();
|
|
|
- for (Entry<VertexBuffer> entry : bufs){
|
|
|
+ for (Entry<VertexBuffer> entry : bufs) {
|
|
|
Buffer data = entry.getValue().getData();
|
|
|
- if (data.position() != 0)
|
|
|
+ if (data.position() != 0) {
|
|
|
data.flip();
|
|
|
+ }
|
|
|
}
|
|
|
mesh.updateBound();
|
|
|
mesh.setStatic();
|
|
|
|
|
|
- if (qName.equals("sharedgeometry")){
|
|
|
+ if (qName.equals("sharedgeometry")) {
|
|
|
geom = null;
|
|
|
mesh = null;
|
|
|
}
|
|
|
- }else if (qName.equals("lodfacelist")){
|
|
|
+ } else if (qName.equals("lodfacelist")) {
|
|
|
sb.flip();
|
|
|
vb = null;
|
|
|
sb = null;
|
|
|
- }else if (qName.equals("levelofdetail")){
|
|
|
+ } else if (qName.equals("levelofdetail")) {
|
|
|
endLevelOfDetail();
|
|
|
- }else if (qName.equals("boneassignments")){
|
|
|
+ } else if (qName.equals("boneassignments")) {
|
|
|
endBoneAssigns();
|
|
|
}
|
|
|
}
|
|
@@ -686,9 +694,9 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
public void characters(char ch[], int start, int length) {
|
|
|
}
|
|
|
|
|
|
- private void createBindPose(Mesh mesh){
|
|
|
+ private void createBindPose(Mesh mesh) {
|
|
|
VertexBuffer pos = mesh.getBuffer(Type.Position);
|
|
|
- if (pos == null || mesh.getBuffer(Type.BoneIndex) == null){
|
|
|
+ if (pos == null || mesh.getBuffer(Type.BoneIndex) == null) {
|
|
|
// ignore, this mesh doesn't have positional data
|
|
|
// or it doesn't have bone-vertex assignments, so its not animated
|
|
|
return;
|
|
@@ -696,9 +704,9 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
|
|
|
VertexBuffer bindPos = new VertexBuffer(Type.BindPosePosition);
|
|
|
bindPos.setupData(Usage.CpuOnly,
|
|
|
- 3,
|
|
|
- Format.Float,
|
|
|
- BufferUtils.clone(pos.getData()));
|
|
|
+ 3,
|
|
|
+ Format.Float,
|
|
|
+ BufferUtils.clone(pos.getData()));
|
|
|
mesh.setBuffer(bindPos);
|
|
|
|
|
|
// XXX: note that this method also sets stream mode
|
|
@@ -706,111 +714,118 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
pos.setUsage(Usage.Stream);
|
|
|
|
|
|
VertexBuffer norm = mesh.getBuffer(Type.Normal);
|
|
|
- if (norm != null){
|
|
|
+ if (norm != null) {
|
|
|
VertexBuffer bindNorm = new VertexBuffer(Type.BindPoseNormal);
|
|
|
bindNorm.setupData(Usage.CpuOnly,
|
|
|
- 3,
|
|
|
- Format.Float,
|
|
|
- BufferUtils.clone(norm.getData()));
|
|
|
+ 3,
|
|
|
+ Format.Float,
|
|
|
+ BufferUtils.clone(norm.getData()));
|
|
|
mesh.setBuffer(bindNorm);
|
|
|
norm.setUsage(Usage.Stream);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private Node compileModel(){
|
|
|
+ private Node compileModel() {
|
|
|
String nodeName;
|
|
|
- if (meshName == null)
|
|
|
- nodeName = "OgreMesh"+(++nodeIdx);
|
|
|
- else
|
|
|
- nodeName = meshName+"-ogremesh";
|
|
|
+ if (meshName == null) {
|
|
|
+ nodeName = "OgreMesh" + (++nodeIdx);
|
|
|
+ } else {
|
|
|
+ nodeName = meshName + "-ogremesh";
|
|
|
+ }
|
|
|
|
|
|
Node model = new Node(nodeName);
|
|
|
- if (animData != null){
|
|
|
+ if (animData != null) {
|
|
|
ArrayList<Mesh> newMeshes = new ArrayList<Mesh>(geoms.size());
|
|
|
|
|
|
// generate bind pose for mesh and add to skin-list
|
|
|
// ONLY if not using shared geometry
|
|
|
// This includes the shared geoemtry itself actually
|
|
|
- for (int i = 0; i < geoms.size(); i++){
|
|
|
+ for (int i = 0; i < geoms.size(); i++) {
|
|
|
Geometry g = geoms.get(i);
|
|
|
Mesh m = geoms.get(i).getMesh();
|
|
|
boolean useShared = usesSharedGeom.get(i);
|
|
|
// create bind pose
|
|
|
- if (!useShared){
|
|
|
+ if (!useShared) {
|
|
|
createBindPose(m);
|
|
|
newMeshes.add(m);
|
|
|
- }else{
|
|
|
- VertexBuffer bindPos = sharedmesh.getBuffer(Type.BindPosePosition);
|
|
|
+ } else {
|
|
|
+ VertexBuffer bindPos = sharedmesh.getBuffer(Type.BindPosePosition);
|
|
|
VertexBuffer bindNorm = sharedmesh.getBuffer(Type.BindPoseNormal);
|
|
|
VertexBuffer boneIndex = sharedmesh.getBuffer(Type.BoneIndex);
|
|
|
VertexBuffer boneWeight = sharedmesh.getBuffer(Type.BoneWeight);
|
|
|
-
|
|
|
- if (bindPos != null)
|
|
|
+
|
|
|
+ if (bindPos != null) {
|
|
|
m.setBuffer(bindPos);
|
|
|
+ }
|
|
|
|
|
|
- if (bindNorm != null)
|
|
|
+ if (bindNorm != null) {
|
|
|
m.setBuffer(bindNorm);
|
|
|
+ }
|
|
|
|
|
|
- if (boneIndex != null)
|
|
|
+ if (boneIndex != null) {
|
|
|
m.setBuffer(boneIndex);
|
|
|
+ }
|
|
|
|
|
|
- if (boneWeight != null)
|
|
|
+ if (boneWeight != null) {
|
|
|
m.setBuffer(boneWeight);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
Mesh[] meshes = new Mesh[newMeshes.size()];
|
|
|
- for (int i = 0; i < meshes.length; i++)
|
|
|
+ for (int i = 0; i < meshes.length; i++) {
|
|
|
meshes[i] = newMeshes.get(i);
|
|
|
+ }
|
|
|
|
|
|
HashMap<String, BoneAnimation> anims = new HashMap<String, BoneAnimation>();
|
|
|
ArrayList<BoneAnimation> animList = animData.anims;
|
|
|
- for (int i = 0; i < animList.size(); i++){
|
|
|
+ for (int i = 0; i < animList.size(); i++) {
|
|
|
BoneAnimation anim = animList.get(i);
|
|
|
anims.put(anim.getName(), anim);
|
|
|
}
|
|
|
|
|
|
- AnimControl ctrl = new AnimControl(model,
|
|
|
- meshes,
|
|
|
- animData.skeleton);
|
|
|
+ //AnimControl ctrl = new AnimControl(model, meshes, animData.skeleton);
|
|
|
+ AnimControl ctrl = new AnimControl(animData.skeleton);
|
|
|
ctrl.setAnimations(anims);
|
|
|
model.addControl(ctrl);
|
|
|
+ SkeletonControl skeletonControl = new SkeletonControl(model, meshes, animData.skeleton);
|
|
|
+ model.addControl(skeletonControl);
|
|
|
}
|
|
|
|
|
|
- for (int i = 0; i < geoms.size(); i++){
|
|
|
+ for (int i = 0; i < geoms.size(); i++) {
|
|
|
Geometry g = geoms.get(i);
|
|
|
Mesh m = g.getMesh();
|
|
|
- if (sharedmesh != null && usesSharedGeom.get(i)){
|
|
|
+ if (sharedmesh != null && usesSharedGeom.get(i)) {
|
|
|
m.setBound(sharedmesh.getBound().clone());
|
|
|
}
|
|
|
model.attachChild(geoms.get(i));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return model;
|
|
|
}
|
|
|
|
|
|
public Object load(AssetInfo info) throws IOException {
|
|
|
- try{
|
|
|
+ try {
|
|
|
AssetKey key = info.getKey();
|
|
|
meshName = key.getName();
|
|
|
folderName = key.getFolder();
|
|
|
String ext = key.getExtension();
|
|
|
meshName = meshName.substring(0, meshName.length() - ext.length() - 1);
|
|
|
- if (folderName != null && folderName.length() > 0){
|
|
|
+ if (folderName != null && folderName.length() > 0) {
|
|
|
meshName = meshName.substring(folderName.length());
|
|
|
}
|
|
|
assetManager = info.getManager();
|
|
|
|
|
|
- OgreMeshKey meshKey = null;
|
|
|
- if (key instanceof OgreMeshKey){
|
|
|
+ OgreMeshKey meshKey = null;
|
|
|
+ if (key instanceof OgreMeshKey) {
|
|
|
meshKey = (OgreMeshKey) key;
|
|
|
materialList = meshKey.getMaterialList();
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
try {
|
|
|
materialList = (MaterialList) assetManager.loadAsset(folderName + meshName + ".material");
|
|
|
} catch (AssetNotFoundException e) {
|
|
|
logger.log(Level.WARNING, "Cannot locate {0}{1}.material for model {2}{3}.{4}", new Object[]{folderName, meshName, folderName, meshName, ext});
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
|
@@ -821,12 +836,11 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
|
|
|
r.close();
|
|
|
|
|
|
return compileModel();
|
|
|
- }catch (SAXException ex){
|
|
|
+ } catch (SAXException ex) {
|
|
|
IOException ioEx = new IOException("Error while parsing Ogre3D mesh.xml");
|
|
|
ioEx.initCause(ex);
|
|
|
throw ioEx;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
}
|