|
|
|
@ -1,8 +1,6 @@ |
|
|
|
|
package jme3tools.optimize; |
|
|
|
|
|
|
|
|
|
import com.jme3.font.BitmapText; |
|
|
|
|
import com.jme3.material.Material; |
|
|
|
|
import com.jme3.math.FastMath; |
|
|
|
|
import com.jme3.math.Matrix4f; |
|
|
|
|
import com.jme3.math.Vector3f; |
|
|
|
|
import com.jme3.scene.Geometry; |
|
|
|
@ -17,10 +15,11 @@ import com.jme3.scene.VertexBuffer.Usage; |
|
|
|
|
import com.jme3.scene.mesh.IndexBuffer; |
|
|
|
|
import com.jme3.scene.mesh.VirtualIndexBuffer; |
|
|
|
|
import com.jme3.scene.mesh.WrappedIndexBuffer; |
|
|
|
|
import com.jme3.scene.shape.Quad; |
|
|
|
|
import com.jme3.util.BufferUtils; |
|
|
|
|
import com.jme3.util.IntMap.Entry; |
|
|
|
|
import java.nio.Buffer; |
|
|
|
|
import java.nio.FloatBuffer; |
|
|
|
|
import java.nio.ShortBuffer; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Collection; |
|
|
|
|
import java.util.HashMap; |
|
|
|
@ -30,43 +29,43 @@ import java.util.Map; |
|
|
|
|
|
|
|
|
|
public class GeometryBatchFactory { |
|
|
|
|
|
|
|
|
|
private static void doTransformVerts(FloatBuffer inBuf, int offset, FloatBuffer outBuf, Matrix4f transform){ |
|
|
|
|
private static void doTransformVerts(FloatBuffer inBuf, int offset, FloatBuffer outBuf, Matrix4f transform) { |
|
|
|
|
Vector3f pos = new Vector3f(); |
|
|
|
|
|
|
|
|
|
// offset is given in element units
|
|
|
|
|
// convert to be in component units
|
|
|
|
|
offset *= 3; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < inBuf.capacity()/3; i++){ |
|
|
|
|
pos.x = inBuf.get(i*3+0); |
|
|
|
|
pos.y = inBuf.get(i*3+1); |
|
|
|
|
pos.z = inBuf.get(i*3+2); |
|
|
|
|
for (int i = 0; i < inBuf.capacity() / 3; i++) { |
|
|
|
|
pos.x = inBuf.get(i * 3 + 0); |
|
|
|
|
pos.y = inBuf.get(i * 3 + 1); |
|
|
|
|
pos.z = inBuf.get(i * 3 + 2); |
|
|
|
|
|
|
|
|
|
transform.mult(pos, pos); |
|
|
|
|
|
|
|
|
|
outBuf.put(offset+i*3+0, pos.x); |
|
|
|
|
outBuf.put(offset+i*3+1, pos.y); |
|
|
|
|
outBuf.put(offset+i*3+2, pos.z); |
|
|
|
|
outBuf.put(offset + i * 3 + 0, pos.x); |
|
|
|
|
outBuf.put(offset + i * 3 + 1, pos.y); |
|
|
|
|
outBuf.put(offset + i * 3 + 2, pos.z); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void doTransformNorms(FloatBuffer inBuf, int offset, FloatBuffer outBuf, Matrix4f transform){ |
|
|
|
|
private static void doTransformNorms(FloatBuffer inBuf, int offset, FloatBuffer outBuf, Matrix4f transform) { |
|
|
|
|
Vector3f norm = new Vector3f(); |
|
|
|
|
|
|
|
|
|
// offset is given in element units
|
|
|
|
|
// convert to be in component units
|
|
|
|
|
offset *= 3; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < inBuf.capacity()/3; i++){ |
|
|
|
|
norm.x = inBuf.get(i*3+0); |
|
|
|
|
norm.y = inBuf.get(i*3+1); |
|
|
|
|
norm.z = inBuf.get(i*3+2); |
|
|
|
|
for (int i = 0; i < inBuf.capacity() / 3; i++) { |
|
|
|
|
norm.x = inBuf.get(i * 3 + 0); |
|
|
|
|
norm.y = inBuf.get(i * 3 + 1); |
|
|
|
|
norm.z = inBuf.get(i * 3 + 2); |
|
|
|
|
|
|
|
|
|
transform.multNormal(norm, norm); |
|
|
|
|
|
|
|
|
|
outBuf.put(offset+i*3+0, norm.x); |
|
|
|
|
outBuf.put(offset+i*3+1, norm.y); |
|
|
|
|
outBuf.put(offset+i*3+2, norm.z); |
|
|
|
|
outBuf.put(offset + i * 3 + 0, norm.x); |
|
|
|
|
outBuf.put(offset + i * 3 + 1, norm.y); |
|
|
|
|
outBuf.put(offset + i * 3 + 2, norm.z); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -77,23 +76,23 @@ public class GeometryBatchFactory { |
|
|
|
|
* @param geometries |
|
|
|
|
* @param outMesh |
|
|
|
|
*/ |
|
|
|
|
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh){ |
|
|
|
|
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) { |
|
|
|
|
int[] compsForBuf = new int[VertexBuffer.Type.values().length]; |
|
|
|
|
Format[] formatForBuf = new Format[compsForBuf.length]; |
|
|
|
|
|
|
|
|
|
int totalVerts = 0; |
|
|
|
|
int totalTris = 0; |
|
|
|
|
int totalTris = 0; |
|
|
|
|
int totalLodLevels = 0; |
|
|
|
|
|
|
|
|
|
Mode mode = null; |
|
|
|
|
for (Geometry geom : geometries){ |
|
|
|
|
for (Geometry geom : geometries) { |
|
|
|
|
totalVerts += geom.getVertexCount(); |
|
|
|
|
totalTris += geom.getTriangleCount(); |
|
|
|
|
totalTris += geom.getTriangleCount(); |
|
|
|
|
totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels()); |
|
|
|
|
|
|
|
|
|
Mode listMode; |
|
|
|
|
int components; |
|
|
|
|
switch (geom.getMesh().getMode()){ |
|
|
|
|
switch (geom.getMesh().getMode()) { |
|
|
|
|
case Points: |
|
|
|
|
listMode = Mode.Points; |
|
|
|
|
components = 1; |
|
|
|
@ -113,38 +112,39 @@ public class GeometryBatchFactory { |
|
|
|
|
default: |
|
|
|
|
throw new UnsupportedOperationException(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (Entry<VertexBuffer> entry : geom.getMesh().getBuffers()){ |
|
|
|
|
|
|
|
|
|
for (Entry<VertexBuffer> entry : geom.getMesh().getBuffers()) { |
|
|
|
|
compsForBuf[entry.getKey()] = entry.getValue().getNumComponents(); |
|
|
|
|
formatForBuf[entry.getKey()] = entry.getValue().getFormat(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mode != null && mode != listMode){ |
|
|
|
|
if (mode != null && mode != listMode) { |
|
|
|
|
throw new UnsupportedOperationException("Cannot combine different" |
|
|
|
|
+ " primitive types: " + mode + " != " + listMode); |
|
|
|
|
+ " primitive types: " + mode + " != " + listMode); |
|
|
|
|
} |
|
|
|
|
mode = listMode; |
|
|
|
|
compsForBuf[Type.Index.ordinal()] = components; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
outMesh.setMode(mode); |
|
|
|
|
if (totalVerts >= 65536){ |
|
|
|
|
if (totalVerts >= 65536) { |
|
|
|
|
// make sure we create an UnsignedInt buffer so
|
|
|
|
|
// we can fit all of the meshes
|
|
|
|
|
formatForBuf[Type.Index.ordinal()] = Format.UnsignedInt; |
|
|
|
|
}else{ |
|
|
|
|
} else { |
|
|
|
|
formatForBuf[Type.Index.ordinal()] = Format.UnsignedShort; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// generate output buffers based on retrieved info
|
|
|
|
|
for (int i = 0; i < compsForBuf.length; i++){ |
|
|
|
|
if (compsForBuf[i] == 0) |
|
|
|
|
for (int i = 0; i < compsForBuf.length; i++) { |
|
|
|
|
if (compsForBuf[i] == 0) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Buffer data; |
|
|
|
|
if (i == Type.Index.ordinal()){ |
|
|
|
|
if (i == Type.Index.ordinal()) { |
|
|
|
|
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris); |
|
|
|
|
}else{ |
|
|
|
|
} else { |
|
|
|
|
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -154,50 +154,51 @@ public class GeometryBatchFactory { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int globalVertIndex = 0; |
|
|
|
|
int globalTriIndex = 0; |
|
|
|
|
int globalTriIndex = 0; |
|
|
|
|
|
|
|
|
|
for (Geometry geom : geometries){ |
|
|
|
|
for (Geometry geom : geometries) { |
|
|
|
|
Mesh inMesh = geom.getMesh(); |
|
|
|
|
geom.computeWorldMatrix(); |
|
|
|
|
Matrix4f worldMatrix = geom.getWorldMatrix(); |
|
|
|
|
|
|
|
|
|
int geomVertCount = inMesh.getVertexCount(); |
|
|
|
|
int geomTriCount = inMesh.getTriangleCount(); |
|
|
|
|
int geomTriCount = inMesh.getTriangleCount(); |
|
|
|
|
|
|
|
|
|
for (int bufType = 0; bufType < compsForBuf.length; bufType++){ |
|
|
|
|
for (int bufType = 0; bufType < compsForBuf.length; bufType++) { |
|
|
|
|
VertexBuffer inBuf = inMesh.getBuffer(Type.values()[bufType]); |
|
|
|
|
VertexBuffer outBuf = outMesh.getBuffer(Type.values()[bufType]); |
|
|
|
|
|
|
|
|
|
if (outBuf == null) |
|
|
|
|
if (outBuf == null) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Type.Index.ordinal() == bufType){ |
|
|
|
|
if (Type.Index.ordinal() == bufType) { |
|
|
|
|
int components = compsForBuf[bufType]; |
|
|
|
|
|
|
|
|
|
IndexBuffer inIdx = inMesh.getIndexBuffer(); |
|
|
|
|
if (inIdx == null){ |
|
|
|
|
if (inIdx == null) { |
|
|
|
|
inIdx = new VirtualIndexBuffer(geomVertCount, inMesh.getMode()); |
|
|
|
|
}else if (inMesh.getMode() != mode){ |
|
|
|
|
} else if (inMesh.getMode() != mode) { |
|
|
|
|
inIdx = new WrappedIndexBuffer(inMesh); |
|
|
|
|
} |
|
|
|
|
IndexBuffer outIdx = outMesh.getIndexBuffer(); |
|
|
|
|
|
|
|
|
|
for (int tri = 0; tri < geomTriCount; tri++){ |
|
|
|
|
for (int comp = 0; comp < components; comp++){ |
|
|
|
|
int idx = inIdx.get(tri*components+comp) + globalVertIndex; |
|
|
|
|
for (int tri = 0; tri < geomTriCount; tri++) { |
|
|
|
|
for (int comp = 0; comp < components; comp++) { |
|
|
|
|
int idx = inIdx.get(tri * components + comp) + globalVertIndex; |
|
|
|
|
outIdx.put((globalTriIndex + tri) * components + comp, idx); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}else if (Type.Position.ordinal() == bufType){ |
|
|
|
|
} else if (Type.Position.ordinal() == bufType) { |
|
|
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData(); |
|
|
|
|
FloatBuffer outPos = (FloatBuffer) outBuf.getData(); |
|
|
|
|
doTransformVerts(inPos, globalVertIndex, outPos, worldMatrix); |
|
|
|
|
}else if (Type.Normal.ordinal() == bufType || Type.Tangent.ordinal() == bufType){ |
|
|
|
|
} else if (Type.Normal.ordinal() == bufType || Type.Tangent.ordinal() == bufType) { |
|
|
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData(); |
|
|
|
|
FloatBuffer outPos = (FloatBuffer) outBuf.getData(); |
|
|
|
|
doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix); |
|
|
|
|
}else{ |
|
|
|
|
for (int vert = 0; vert < geomVertCount; vert++){ |
|
|
|
|
} else { |
|
|
|
|
for (int vert = 0; vert < geomVertCount; vert++) { |
|
|
|
|
int curGlobalVertIndex = globalVertIndex + vert; |
|
|
|
|
inBuf.copyElement(vert, outBuf, curGlobalVertIndex); |
|
|
|
|
} |
|
|
|
@ -205,23 +206,76 @@ public class GeometryBatchFactory { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
globalVertIndex += geomVertCount; |
|
|
|
|
globalTriIndex += geomTriCount; |
|
|
|
|
globalTriIndex += geomTriCount; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void makeLods(Collection<Geometry> geometries, Mesh outMesh) { |
|
|
|
|
int lodLevels = 0; |
|
|
|
|
int[] lodSize = null; |
|
|
|
|
int index = 0; |
|
|
|
|
for (Geometry g : geometries) { |
|
|
|
|
if (lodLevels == 0) { |
|
|
|
|
lodLevels = g.getMesh().getNumLodLevels(); |
|
|
|
|
} |
|
|
|
|
if (lodSize == null) { |
|
|
|
|
lodSize = new int[lodLevels]; |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < lodLevels; i++) { |
|
|
|
|
lodSize[i] += g.getMesh().getLodLevel(i).getData().capacity(); |
|
|
|
|
//if( i == 0) System.out.println(index + " " +lodSize[i]);
|
|
|
|
|
} |
|
|
|
|
index++; |
|
|
|
|
} |
|
|
|
|
int[][] lodData = new int[lodLevels][]; |
|
|
|
|
for (int i = 0; i < lodLevels; i++) { |
|
|
|
|
lodData[i] = new int[lodSize[i]]; |
|
|
|
|
} |
|
|
|
|
VertexBuffer[] lods = new VertexBuffer[lodLevels]; |
|
|
|
|
int bufferPos[] = new int[lodLevels]; |
|
|
|
|
//int index = 0;
|
|
|
|
|
int numOfVertices = 0; |
|
|
|
|
int curGeom = 0; |
|
|
|
|
for (Geometry g : geometries) { |
|
|
|
|
if (numOfVertices == 0) { |
|
|
|
|
numOfVertices = g.getVertexCount(); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < lodLevels; i++) { |
|
|
|
|
ShortBuffer buffer = (ShortBuffer) g.getMesh().getLodLevel(i).getData(); |
|
|
|
|
buffer.rewind(); |
|
|
|
|
//System.out.println("buffer: " + buffer.capacity() + " limit: " + lodSize[i] + " " + index);
|
|
|
|
|
for (int j = 0; j < buffer.capacity(); j++) { |
|
|
|
|
lodData[i][bufferPos[i] + j] = buffer.get() + numOfVertices * curGeom; |
|
|
|
|
//bufferPos[i]++;
|
|
|
|
|
} |
|
|
|
|
bufferPos[i] += buffer.capacity(); |
|
|
|
|
} |
|
|
|
|
curGeom++; |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < lodLevels; i++) { |
|
|
|
|
lods[i] = new VertexBuffer(Type.Index); |
|
|
|
|
lods[i].setupData(Usage.Dynamic, 1, Format.UnsignedInt, BufferUtils.createIntBuffer(lodData[i])); |
|
|
|
|
} |
|
|
|
|
System.out.println(lods.length); |
|
|
|
|
outMesh.setLodLevels(lods); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static List<Geometry> makeBatches(Collection<Geometry> geometries) { |
|
|
|
|
return makeBatches(geometries, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Batches a collection of Geometries so that all with the same material get combined. |
|
|
|
|
* @param geometries The Geometries to combine |
|
|
|
|
* @return A List of newly created Geometries, each with a distinct material |
|
|
|
|
*/ |
|
|
|
|
public static List<Geometry> makeBatches(Collection<Geometry> geometries){ |
|
|
|
|
public static List<Geometry> makeBatches(Collection<Geometry> geometries, boolean useLods) { |
|
|
|
|
ArrayList<Geometry> retVal = new ArrayList<Geometry>(); |
|
|
|
|
HashMap<Material, List<Geometry>> matToGeom = new HashMap<Material, List<Geometry>>(); |
|
|
|
|
|
|
|
|
|
for (Geometry geom : geometries){ |
|
|
|
|
for (Geometry geom : geometries) { |
|
|
|
|
List<Geometry> outList = matToGeom.get(geom.getMaterial()); |
|
|
|
|
if (outList == null){ |
|
|
|
|
if (outList == null) { |
|
|
|
|
outList = new ArrayList<Geometry>(); |
|
|
|
|
matToGeom.put(geom.getMaterial(), outList); |
|
|
|
|
} |
|
|
|
@ -229,11 +283,15 @@ public class GeometryBatchFactory { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int batchNum = 0; |
|
|
|
|
for (Map.Entry<Material, List<Geometry>> entry : matToGeom.entrySet()){ |
|
|
|
|
for (Map.Entry<Material, List<Geometry>> entry : matToGeom.entrySet()) { |
|
|
|
|
Material mat = entry.getKey(); |
|
|
|
|
List<Geometry> geomsForMat = entry.getValue(); |
|
|
|
|
Mesh mesh = new Mesh(); |
|
|
|
|
mergeGeometries(geomsForMat, mesh); |
|
|
|
|
// lods
|
|
|
|
|
if (useLods) { |
|
|
|
|
makeLods(geomsForMat, mesh); |
|
|
|
|
} |
|
|
|
|
mesh.updateCounts(); |
|
|
|
|
mesh.updateBound(); |
|
|
|
|
|
|
|
|
@ -245,14 +303,14 @@ public class GeometryBatchFactory { |
|
|
|
|
return retVal; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void gatherGeoms(Spatial scene, List<Geometry> geoms){ |
|
|
|
|
if (scene instanceof Node){ |
|
|
|
|
private static void gatherGeoms(Spatial scene, List<Geometry> geoms) { |
|
|
|
|
if (scene instanceof Node) { |
|
|
|
|
Node node = (Node) scene; |
|
|
|
|
for (Spatial child : node.getChildren()){ |
|
|
|
|
for (Spatial child : node.getChildren()) { |
|
|
|
|
gatherGeoms(child, geoms); |
|
|
|
|
} |
|
|
|
|
}else if (scene instanceof Geometry){ |
|
|
|
|
geoms.add((Geometry)scene); |
|
|
|
|
} else if (scene instanceof Geometry) { |
|
|
|
|
geoms.add((Geometry) scene); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -263,12 +321,25 @@ public class GeometryBatchFactory { |
|
|
|
|
* @param scene The scene to optimize |
|
|
|
|
* @return The newly created optimized geometries attached to a node |
|
|
|
|
*/ |
|
|
|
|
public static Node optimize(Node scene){ |
|
|
|
|
public static Spatial optimize(Node scene) { |
|
|
|
|
return optimize(scene, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Optimizes a scene by combining Geometry with the same material. |
|
|
|
|
* All Geometries found in the scene are detached from their parent and |
|
|
|
|
* a new Node containing the optimized Geometries is attached. |
|
|
|
|
* @param scene The scene to optimize |
|
|
|
|
* @param useLods true if you want the resulting geometry to keep lod information |
|
|
|
|
* @return The newly created optimized geometries attached to a node |
|
|
|
|
*/ |
|
|
|
|
public static Node optimize(Node scene, boolean useLods) { |
|
|
|
|
ArrayList<Geometry> geoms = new ArrayList<Geometry>(); |
|
|
|
|
|
|
|
|
|
gatherGeoms(scene, geoms); |
|
|
|
|
|
|
|
|
|
List<Geometry> batchedGeoms = makeBatches(geoms); |
|
|
|
|
for (Geometry geom : batchedGeoms){ |
|
|
|
|
List<Geometry> batchedGeoms = makeBatches(geoms, useLods); |
|
|
|
|
for (Geometry geom : batchedGeoms) { |
|
|
|
|
scene.attachChild(geom); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -280,22 +351,24 @@ public class GeometryBatchFactory { |
|
|
|
|
return scene; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void printMesh(Mesh mesh){ |
|
|
|
|
for (int bufType = 0; bufType < Type.values().length; bufType++){ |
|
|
|
|
public static void printMesh(Mesh mesh) { |
|
|
|
|
for (int bufType = 0; bufType < Type.values().length; bufType++) { |
|
|
|
|
VertexBuffer outBuf = mesh.getBuffer(Type.values()[bufType]); |
|
|
|
|
if (outBuf == null) |
|
|
|
|
if (outBuf == null) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
System.out.println(outBuf.getBufferType() + ": "); |
|
|
|
|
for (int vert = 0; vert < outBuf.getNumElements(); vert++){ |
|
|
|
|
for (int vert = 0; vert < outBuf.getNumElements(); vert++) { |
|
|
|
|
String str = "["; |
|
|
|
|
for (int comp = 0; comp < outBuf.getNumComponents(); comp++){ |
|
|
|
|
for (int comp = 0; comp < outBuf.getNumComponents(); comp++) { |
|
|
|
|
Object val = outBuf.getElementComponent(vert, comp); |
|
|
|
|
outBuf.setElementComponent(vert, comp, val); |
|
|
|
|
val = outBuf.getElementComponent(vert, comp); |
|
|
|
|
str += val; |
|
|
|
|
if (comp != outBuf.getNumComponents()-1) |
|
|
|
|
if (comp != outBuf.getNumComponents() - 1) { |
|
|
|
|
str += ", "; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
str += "]"; |
|
|
|
|
System.out.println(str); |
|
|
|
@ -304,20 +377,20 @@ public class GeometryBatchFactory { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void main(String[] args){ |
|
|
|
|
public static void main(String[] args) { |
|
|
|
|
Mesh mesh = new Mesh(); |
|
|
|
|
mesh.setBuffer(Type.Position, 3, new float[]{ |
|
|
|
|
0, 0, 0, |
|
|
|
|
1, 0, 0, |
|
|
|
|
1, 1, 0, |
|
|
|
|
0, 1, 0 |
|
|
|
|
}); |
|
|
|
|
0, 0, 0, |
|
|
|
|
1, 0, 0, |
|
|
|
|
1, 1, 0, |
|
|
|
|
0, 1, 0 |
|
|
|
|
}); |
|
|
|
|
mesh.setBuffer(Type.Index, 2, new short[]{ |
|
|
|
|
0, 1, |
|
|
|
|
1, 2, |
|
|
|
|
2, 3, |
|
|
|
|
3, 0 |
|
|
|
|
}); |
|
|
|
|
0, 1, |
|
|
|
|
1, 2, |
|
|
|
|
2, 3, |
|
|
|
|
3, 0 |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Geometry g1 = new Geometry("g1", mesh); |
|
|
|
|
|
|
|
|
|