use of java.nio.FloatBuffer in project jmonkeyengine by jMonkeyEngine.
the class Matrix3f method toFloatBuffer.
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains
* the matrix data.
*
* @return matrix data as a FloatBuffer.
*/
public FloatBuffer toFloatBuffer() {
FloatBuffer fb = BufferUtils.createFloatBuffer(9);
fb.put(m00).put(m01).put(m02);
fb.put(m10).put(m11).put(m12);
fb.put(m20).put(m21).put(m22);
fb.rewind();
return fb;
}
use of java.nio.FloatBuffer in project jmonkeyengine by jMonkeyEngine.
the class Matrix4f method toFloatBuffer.
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains the
* matrix data.
*
* @param columnMajor
* if true, this buffer should be filled with column major data,
* otherwise it will be filled row major.
* @return matrix data as a FloatBuffer. The position is set to 0 for
* convenience.
*/
public FloatBuffer toFloatBuffer(boolean columnMajor) {
FloatBuffer fb = BufferUtils.createFloatBuffer(16);
fillFloatBuffer(fb, columnMajor);
fb.rewind();
return fb;
}
use of java.nio.FloatBuffer in project jmonkeyengine by jMonkeyEngine.
the class FbxMesh method createGeometries.
private List<Geometry> createGeometries() throws IOException {
Mesh mesh = new Mesh();
mesh.setMode(Mode.Triangles);
// Moreover quads should be triangulated (this increases number of vertices)
if (indices != null) {
iCount = indices.length;
srcVertexCount = vertices.length / 3;
// Indices contains negative numbers to define polygon last index
// Check indices strides to be sure we have triangles or quads
vCount = 0;
// Count number of vertices to be produced
int polyVertCount = 0;
for (int i = 0; i < iCount; ++i) {
int index = indices[i];
polyVertCount++;
if (index < 0) {
if (polyVertCount == 3) {
// A triangle
vCount += 3;
} else if (polyVertCount == 4) {
// A quad produce two triangles
vCount += 6;
} else {
throw new AssetLoadException("Unsupported PolygonVertexIndex stride");
}
polyVertCount = 0;
}
}
// Unroll index array into vertex mapping
vertexMap = new ArrayList<>(vCount);
indexMap = new ArrayList<>(vCount);
polyVertCount = 0;
for (int i = 0; i < iCount; ++i) {
int index = indices[i];
polyVertCount++;
if (index < 0) {
int lastIndex = -(index + 1);
if (polyVertCount == 3) {
vertexMap.add(indices[i - 2]);
vertexMap.add(indices[i - 1]);
vertexMap.add(lastIndex);
indexMap.add(i - 2);
indexMap.add(i - 1);
indexMap.add(i - 0);
} else if (polyVertCount == 4) {
vertexMap.add(indices[i - 3]);
vertexMap.add(indices[i - 2]);
vertexMap.add(indices[i - 1]);
vertexMap.add(indices[i - 3]);
vertexMap.add(indices[i - 1]);
vertexMap.add(lastIndex);
indexMap.add(i - 3);
indexMap.add(i - 2);
indexMap.add(i - 1);
indexMap.add(i - 3);
indexMap.add(i - 1);
indexMap.add(i - 0);
}
polyVertCount = 0;
}
}
// Build reverse vertex mapping
reverseVertexMap = new ArrayList<>(srcVertexCount);
for (int i = 0; i < srcVertexCount; ++i) reverseVertexMap.add(new ArrayList<Integer>());
for (int i = 0; i < vCount; ++i) {
int index = vertexMap.get(i);
reverseVertexMap.get(index).add(i);
}
} else {
// Stub for no vertex indexing (direct mapping)
iCount = vCount = srcVertexCount;
vertexMap = new ArrayList<>(vCount);
indexMap = new ArrayList<>(vCount);
reverseVertexMap = new ArrayList<>(vCount);
for (int i = 0; i < vCount; ++i) {
vertexMap.set(i, i);
indexMap.set(i, i);
List<Integer> l = new ArrayList<Integer>(1);
l.add(i);
reverseVertexMap.add(l);
}
}
if (vertices != null) {
// Unroll vertices data array
FloatBuffer posBuf = BufferUtils.createFloatBuffer(vCount * 3);
mesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
int srcCount = vertices.length / 3;
for (int i = 0; i < vCount; ++i) {
int index = vertexMap.get(i);
if (index > srcCount)
throw new AssetLoadException("Invalid vertex mapping. Unexpected lookup vertex " + index + " from " + srcCount);
// XXX Why we should scale by unit size?
float x = (float) vertices[3 * index + 0] / scene.unitSize * scene.xAxis;
float y = (float) vertices[3 * index + 1] / scene.unitSize * scene.yAxis;
float z = (float) vertices[3 * index + 2] / scene.unitSize * scene.zAxis;
posBuf.put(x).put(y).put(z);
}
}
if (normals != null) {
// Unroll normals data array
FloatBuffer normBuf = BufferUtils.createFloatBuffer(vCount * 3);
mesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
List<Integer> mapping = null;
if (normalsMapping.equals("ByVertice"))
mapping = vertexMap;
else if (normalsMapping.equals("ByPolygonVertex"))
mapping = indexMap;
else
throw new IOException("Unknown normals mapping type: " + normalsMapping);
int srcCount = normals.length / 3;
for (int i = 0; i < vCount; ++i) {
int index = mapping.get(i);
if (index > srcCount)
throw new AssetLoadException("Invalid normal mapping. Unexpected lookup normal " + index + " from " + srcCount);
float x = (float) normals[3 * index + 0] * scene.xAxis;
float y = (float) normals[3 * index + 1] * scene.yAxis;
float z = (float) normals[3 * index + 2] * scene.zAxis;
normBuf.put(x).put(y).put(z);
}
}
if (tangents != null) {
// Unroll normals data array
FloatBuffer tanBuf = BufferUtils.createFloatBuffer(vCount * 4);
mesh.setBuffer(VertexBuffer.Type.Tangent, 4, tanBuf);
List<Integer> mapping = null;
if (tangentsMapping.equals("ByVertice"))
mapping = vertexMap;
else if (tangentsMapping.equals("ByPolygonVertex"))
mapping = indexMap;
else
throw new IOException("Unknown tangents mapping type: " + tangentsMapping);
int srcCount = tangents.length / 3;
for (int i = 0; i < vCount; ++i) {
int index = mapping.get(i);
if (index > srcCount)
throw new AssetLoadException("Invalid tangent mapping. Unexpected lookup tangent " + index + " from " + srcCount);
float x = (float) tangents[3 * index + 0] * scene.xAxis;
float y = (float) tangents[3 * index + 1] * scene.yAxis;
float z = (float) tangents[3 * index + 2] * scene.zAxis;
tanBuf.put(x).put(y).put(z).put(-1.0f);
}
}
if (binormals != null) {
// Unroll normals data array
FloatBuffer binormBuf = BufferUtils.createFloatBuffer(vCount * 3);
mesh.setBuffer(VertexBuffer.Type.Binormal, 3, binormBuf);
List<Integer> mapping = null;
if (binormalsMapping.equals("ByVertice"))
mapping = vertexMap;
else if (binormalsMapping.equals("ByPolygonVertex"))
mapping = indexMap;
else
throw new IOException("Unknown binormals mapping type: " + binormalsMapping);
int srcCount = binormals.length / 3;
for (int i = 0; i < vCount; ++i) {
int index = mapping.get(i);
if (index > srcCount)
throw new AssetLoadException("Invalid binormal mapping. Unexpected lookup binormal " + index + " from " + srcCount);
float x = (float) binormals[3 * index + 0] * scene.xAxis;
float y = (float) binormals[3 * index + 1] * scene.yAxis;
float z = (float) binormals[3 * index + 2] * scene.zAxis;
binormBuf.put(x).put(y).put(z);
}
}
for (int uvLayer = 0; uvLayer < uvs.size(); ++uvLayer) {
double[] uv = uvs.get(uvLayer);
int[] uvIndex = uvIndexes.size() > uvLayer ? uvIndexes.get(uvLayer) : null;
List<Integer> unIndexMap = vertexMap;
if (uvIndex != null) {
int uvIndexSrcCount = uvIndex.length;
if (uvIndexSrcCount != iCount)
throw new AssetLoadException("Invalid number of texcoord index data " + uvIndexSrcCount + " expected " + iCount);
// Unroll UV index array
unIndexMap = new ArrayList<>(vCount);
int polyVertCount = 0;
for (int i = 0; i < iCount; ++i) {
int index = indices[i];
polyVertCount++;
if (index < 0) {
if (polyVertCount == 3) {
unIndexMap.add(uvIndex[i - 2]);
unIndexMap.add(uvIndex[i - 1]);
unIndexMap.add(uvIndex[i - 0]);
} else if (polyVertCount == 4) {
unIndexMap.add(uvIndex[i - 3]);
unIndexMap.add(uvIndex[i - 2]);
unIndexMap.add(uvIndex[i - 1]);
unIndexMap.add(uvIndex[i - 3]);
unIndexMap.add(uvIndex[i - 1]);
unIndexMap.add(uvIndex[i - 0]);
}
polyVertCount = 0;
}
}
}
// Unroll UV data array
FloatBuffer tcBuf = BufferUtils.createFloatBuffer(vCount * 2);
VertexBuffer.Type type = VertexBuffer.Type.TexCoord;
switch(uvLayer) {
case 1:
type = VertexBuffer.Type.TexCoord2;
break;
case 2:
type = VertexBuffer.Type.TexCoord3;
break;
case 3:
type = VertexBuffer.Type.TexCoord4;
break;
case 4:
type = VertexBuffer.Type.TexCoord5;
break;
case 5:
type = VertexBuffer.Type.TexCoord6;
break;
case 6:
type = VertexBuffer.Type.TexCoord7;
break;
case 7:
type = VertexBuffer.Type.TexCoord8;
break;
}
mesh.setBuffer(type, 2, tcBuf);
int srcCount = uv.length / 2;
for (int i = 0; i < vCount; ++i) {
int index = unIndexMap.get(i);
if (index > srcCount)
throw new AssetLoadException("Invalid texcoord mapping. Unexpected lookup texcoord " + index + " from " + srcCount);
float u = (index >= 0) ? (float) uv[2 * index + 0] : 0;
float v = (index >= 0) ? (float) uv[2 * index + 1] : 0;
tcBuf.put(u).put(v);
}
}
List<Geometry> geometries = new ArrayList<Geometry>();
if (materialsReference.equals("IndexToDirect") && materialsMapping.equals("ByPolygon")) {
IntMap<List<Integer>> indexBuffers = new IntMap<>();
for (int polygon = 0; polygon < materials.length; ++polygon) {
int material = materials[polygon];
List<Integer> list = indexBuffers.get(material);
if (list == null) {
list = new ArrayList<>();
indexBuffers.put(material, list);
}
list.add(polygon * 3 + 0);
list.add(polygon * 3 + 1);
list.add(polygon * 3 + 2);
}
Iterator<Entry<List<Integer>>> iterator = indexBuffers.iterator();
while (iterator.hasNext()) {
Entry<List<Integer>> e = iterator.next();
int materialId = e.getKey();
List<Integer> indexes = e.getValue();
Mesh newMesh = mesh.clone();
newMesh.setBuffer(VertexBuffer.Type.Index, 3, toArray(indexes.toArray(new Integer[indexes.size()])));
newMesh.setStatic();
newMesh.updateBound();
newMesh.updateCounts();
Geometry geom = new Geometry();
geom.setMesh(newMesh);
geometries.add(geom);
geom.setUserData("FBXMaterial", materialId);
}
} else {
mesh.setStatic();
mesh.updateBound();
mesh.updateCounts();
Geometry geom = new Geometry();
geom.setMesh(mesh);
geometries.add(geom);
}
return geometries;
}
use of java.nio.FloatBuffer in project jmonkeyengine by jMonkeyEngine.
the class IrUtils method convertIrMeshToJmeMesh.
/**
* Convert IrMesh to jME3 mesh.
*/
public static Mesh convertIrMeshToJmeMesh(IrMesh mesh) {
Map<IrVertex, Integer> vertexToVertexIndex = new HashMap<IrVertex, Integer>();
List<IrVertex> vertices = new ArrayList<IrVertex>();
List<Integer> indexes = new ArrayList<Integer>();
int vertexIndex = 0;
for (IrPolygon polygon : mesh.polygons) {
if (polygon.vertices.length != 3) {
throw new UnsupportedOperationException("IrMesh must be triangulated first");
}
for (IrVertex vertex : polygon.vertices) {
// Is this vertex already indexed?
Integer existingIndex = vertexToVertexIndex.get(vertex);
if (existingIndex == null) {
// Not indexed yet, allocate index.
indexes.add(vertexIndex);
vertexToVertexIndex.put(vertex, vertexIndex);
vertices.add(vertex);
vertexIndex++;
} else {
// Index already allocated for this vertex, reuse it.
indexes.add(existingIndex);
}
}
}
Mesh jmeMesh = new Mesh();
jmeMesh.setMode(Mesh.Mode.Triangles);
FloatBuffer posBuf = null;
FloatBuffer normBuf = null;
FloatBuffer tangBuf = null;
FloatBuffer uv0Buf = null;
FloatBuffer uv1Buf = null;
ByteBuffer colorBuf = null;
ByteBuffer boneIndices = null;
FloatBuffer boneWeights = null;
IndexBuffer indexBuf = null;
IrVertex inspectionVertex = vertices.get(0);
if (inspectionVertex.pos != null) {
posBuf = BufferUtils.createVector3Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
}
if (inspectionVertex.norm != null) {
normBuf = BufferUtils.createVector3Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
}
if (inspectionVertex.tang4d != null) {
tangBuf = BufferUtils.createFloatBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.Tangent, 4, tangBuf);
}
if (inspectionVertex.tang != null || inspectionVertex.bitang != null) {
throw new IllegalStateException("Mesh is using 3D tangents, must be converted to 4D tangents first.");
}
if (inspectionVertex.uv0 != null) {
uv0Buf = BufferUtils.createVector2Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, uv0Buf);
}
if (inspectionVertex.uv1 != null) {
uv1Buf = BufferUtils.createVector2Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, uv1Buf);
}
if (inspectionVertex.color != null) {
colorBuf = BufferUtils.createByteBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.Color, 4, colorBuf);
jmeMesh.getBuffer(VertexBuffer.Type.Color).setNormalized(true);
}
if (inspectionVertex.boneWeightsIndices != null) {
boneIndices = BufferUtils.createByteBuffer(vertices.size() * 4);
boneWeights = BufferUtils.createFloatBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.BoneIndex, 4, boneIndices);
jmeMesh.setBuffer(VertexBuffer.Type.BoneWeight, 4, boneWeights);
//creating empty buffers for HW skinning
//the buffers will be setup if ever used.
VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight);
VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex);
//setting usage to cpuOnly so that the buffer is not send empty to the GPU
indicesHW.setUsage(VertexBuffer.Usage.CpuOnly);
weightsHW.setUsage(VertexBuffer.Usage.CpuOnly);
jmeMesh.setBuffer(weightsHW);
jmeMesh.setBuffer(indicesHW);
}
if (vertices.size() >= 65536) {
// too many verticies: use intbuffer instead of shortbuffer
IntBuffer ib = BufferUtils.createIntBuffer(indexes.size());
jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, ib);
indexBuf = new IndexIntBuffer(ib);
} else {
ShortBuffer sb = BufferUtils.createShortBuffer(indexes.size());
jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, sb);
indexBuf = new IndexShortBuffer(sb);
}
jmeMesh.setStatic();
int maxBonesPerVertex = -1;
for (IrVertex vertex : vertices) {
if (posBuf != null) {
posBuf.put(vertex.pos.x).put(vertex.pos.y).put(vertex.pos.z);
}
if (normBuf != null) {
normBuf.put(vertex.norm.x).put(vertex.norm.y).put(vertex.norm.z);
}
if (tangBuf != null) {
tangBuf.put(vertex.tang4d.x).put(vertex.tang4d.y).put(vertex.tang4d.z).put(vertex.tang4d.w);
}
if (uv0Buf != null) {
uv0Buf.put(vertex.uv0.x).put(vertex.uv0.y);
}
if (uv1Buf != null) {
uv1Buf.put(vertex.uv1.x).put(vertex.uv1.y);
}
if (colorBuf != null) {
colorBuf.putInt(vertex.color.asIntABGR());
}
if (boneIndices != null) {
if (vertex.boneWeightsIndices != null) {
if (vertex.boneWeightsIndices.length > 4) {
throw new UnsupportedOperationException("Mesh uses more than 4 weights per bone. " + "Call trimBoneWeights() to allieviate this");
}
for (int i = 0; i < vertex.boneWeightsIndices.length; i++) {
boneIndices.put((byte) (vertex.boneWeightsIndices[i].boneIndex & 0xFF));
boneWeights.put(vertex.boneWeightsIndices[i].boneWeight);
}
for (int i = 0; i < 4 - vertex.boneWeightsIndices.length; i++) {
boneIndices.put((byte) 0);
boneWeights.put(0f);
}
} else {
boneIndices.putInt(0);
boneWeights.put(0f).put(0f).put(0f).put(0f);
}
maxBonesPerVertex = Math.max(maxBonesPerVertex, vertex.boneWeightsIndices.length);
}
}
for (int i = 0; i < indexes.size(); i++) {
indexBuf.put(i, indexes.get(i));
}
jmeMesh.updateCounts();
jmeMesh.updateBound();
if (boneIndices != null) {
jmeMesh.setMaxNumWeights(maxBonesPerVertex);
jmeMesh.prepareForAnim(true);
jmeMesh.generateBindPose(true);
}
return jmeMesh;
}
use of java.nio.FloatBuffer in project jmonkeyengine by jMonkeyEngine.
the class DOMInputCapsule method readFloatBuffer.
/**
* reads from currentElem if name is null
*/
public FloatBuffer readFloatBuffer(String name, FloatBuffer defVal) throws IOException {
try {
Element tmpEl;
if (name != null) {
tmpEl = findChildElement(currentElem, name);
} else {
tmpEl = currentElem;
}
if (tmpEl == null) {
return defVal;
}
String sizeString = tmpEl.getAttribute("size");
String[] strings = parseTokens(tmpEl.getAttribute("data"));
if (sizeString.length() > 0) {
int requiredSize = Integer.parseInt(sizeString);
if (strings.length != requiredSize)
throw new IOException("Wrong number of float buffers for '" + name + "'. size says " + requiredSize + ", data contains " + strings.length);
}
FloatBuffer tmp = BufferUtils.createFloatBuffer(strings.length);
for (String s : strings) tmp.put(Float.parseFloat(s));
tmp.flip();
return tmp;
} catch (IOException ioe) {
throw ioe;
} catch (NumberFormatException nfe) {
IOException io = new IOException(nfe.toString());
io.initCause(nfe);
throw io;
} catch (DOMException de) {
IOException io = new IOException(de.toString());
io.initCause(de);
throw io;
}
}
Aggregations