|
@@ -80,6 +80,9 @@ public class BatchNode extends Node implements Savable {
|
|
|
* used to store transformed vectors before proceeding to a bulk put into the FloatBuffer
|
|
|
*/
|
|
|
private float[] tmpFloat;
|
|
|
+ private float[] tmpFloatN;
|
|
|
+ private float[] tmpFloatT;
|
|
|
+
|
|
|
/**
|
|
|
* Construct a batchNode
|
|
|
*/
|
|
@@ -142,21 +145,23 @@ public class BatchNode extends Node implements Savable {
|
|
|
if (batch != null) {
|
|
|
Mesh mesh = batch.geometry.getMesh();
|
|
|
|
|
|
- FloatBuffer buf = (FloatBuffer) mesh.getBuffer(VertexBuffer.Type.Position).getData();
|
|
|
- doTransformVerts(buf, bg.startIndex, bg.startIndex + bg.getVertexCount(), buf, bg.cachedOffsetMat);
|
|
|
- mesh.getBuffer(VertexBuffer.Type.Position).updateData(buf);
|
|
|
-
|
|
|
- buf = (FloatBuffer) mesh.getBuffer(VertexBuffer.Type.Normal).getData();
|
|
|
- doTransformNorm(buf, bg.startIndex, bg.startIndex + bg.getVertexCount(), buf, bg.cachedOffsetMat);
|
|
|
- mesh.getBuffer(VertexBuffer.Type.Normal).updateData(buf);
|
|
|
-
|
|
|
+ VertexBuffer pvb = mesh.getBuffer(VertexBuffer.Type.Position);
|
|
|
+ FloatBuffer posBuf = (FloatBuffer) pvb.getData();
|
|
|
+ VertexBuffer nvb = mesh.getBuffer(VertexBuffer.Type.Normal);
|
|
|
+ FloatBuffer normBuf = (FloatBuffer) nvb.getData();
|
|
|
|
|
|
if (mesh.getBuffer(VertexBuffer.Type.Tangent) != null) {
|
|
|
|
|
|
- buf = (FloatBuffer) mesh.getBuffer(VertexBuffer.Type.Tangent).getData();
|
|
|
- doTransformNorm(buf, bg.startIndex, bg.startIndex + bg.getVertexCount(), buf, bg.cachedOffsetMat);
|
|
|
- mesh.getBuffer(VertexBuffer.Type.Tangent).updateData(buf);
|
|
|
+ VertexBuffer tvb = mesh.getBuffer(VertexBuffer.Type.Tangent);
|
|
|
+ FloatBuffer tanBuf = (FloatBuffer) tvb.getData();
|
|
|
+ doTransformsTangents(posBuf, normBuf, tanBuf, bg.startIndex, bg.startIndex + bg.getVertexCount(), bg.cachedOffsetMat);
|
|
|
+ tvb.updateData(tanBuf);
|
|
|
+ } else {
|
|
|
+ doTransforms(posBuf, normBuf, bg.startIndex, bg.startIndex + bg.getVertexCount(), bg.cachedOffsetMat);
|
|
|
}
|
|
|
+ pvb.updateData(posBuf);
|
|
|
+ nvb.updateData(normBuf);
|
|
|
+
|
|
|
|
|
|
batch.needMeshUpdate = true;
|
|
|
}
|
|
@@ -351,13 +356,16 @@ public class BatchNode extends Node implements Savable {
|
|
|
int totalVerts = 0;
|
|
|
int totalTris = 0;
|
|
|
int totalLodLevels = 0;
|
|
|
+ int maxVertCount = 0;
|
|
|
|
|
|
Mesh.Mode mode = null;
|
|
|
- for (Geometry geom : geometries) {
|
|
|
+ for (Geometry geom : geometries) {
|
|
|
totalVerts += geom.getVertexCount();
|
|
|
totalTris += geom.getTriangleCount();
|
|
|
totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
|
|
|
-
|
|
|
+ if (maxVertCount < geom.getVertexCount()) {
|
|
|
+ maxVertCount = geom.getVertexCount();
|
|
|
+ }
|
|
|
Mesh.Mode listMode;
|
|
|
int components;
|
|
|
switch (geom.getMesh().getMode()) {
|
|
@@ -403,8 +411,6 @@ public class BatchNode extends Node implements Savable {
|
|
|
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort;
|
|
|
}
|
|
|
|
|
|
- int maxElemCount = 0;
|
|
|
- int elements = 0;
|
|
|
// generate output buffers based on retrieved info
|
|
|
for (int i = 0; i < compsForBuf.length; i++) {
|
|
|
if (compsForBuf[i] == 0) {
|
|
@@ -413,16 +419,11 @@ public class BatchNode extends Node implements Savable {
|
|
|
|
|
|
Buffer data;
|
|
|
if (i == VertexBuffer.Type.Index.ordinal()) {
|
|
|
- data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
|
|
|
- elements = compsForBuf[i]* totalTris;
|
|
|
+ data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
|
|
|
} else {
|
|
|
- data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
|
|
|
- elements = compsForBuf[i]* totalVerts;
|
|
|
+ data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
|
|
|
}
|
|
|
|
|
|
- if(maxElemCount<elements){
|
|
|
- maxElemCount = elements;
|
|
|
- }
|
|
|
VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.values()[i]);
|
|
|
vb.setupData(VertexBuffer.Usage.Dynamic, compsForBuf[i], formatForBuf[i], data);
|
|
|
outMesh.setBuffer(vb);
|
|
@@ -430,17 +431,17 @@ public class BatchNode extends Node implements Savable {
|
|
|
|
|
|
int globalVertIndex = 0;
|
|
|
int globalTriIndex = 0;
|
|
|
-
|
|
|
+
|
|
|
for (Geometry geom : geometries) {
|
|
|
Mesh inMesh = geom.getMesh();
|
|
|
geom.batch(this, globalVertIndex);
|
|
|
|
|
|
- int geomVertCount = inMesh.getVertexCount();
|
|
|
+ int geomVertCount = inMesh.getVertexCount();
|
|
|
int geomTriCount = inMesh.getTriangleCount();
|
|
|
|
|
|
for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
|
|
|
VertexBuffer inBuf = inMesh.getBuffer(VertexBuffer.Type.values()[bufType]);
|
|
|
-
|
|
|
+
|
|
|
VertexBuffer outBuf = outMesh.getBuffer(VertexBuffer.Type.values()[bufType]);
|
|
|
|
|
|
if (outBuf == null) {
|
|
@@ -477,69 +478,127 @@ public class BatchNode extends Node implements Savable {
|
|
|
|
|
|
globalVertIndex += geomVertCount;
|
|
|
globalTriIndex += geomTriCount;
|
|
|
- }
|
|
|
- tmpFloat = new float[maxElemCount];
|
|
|
+ }
|
|
|
+ tmpFloat = new float[maxVertCount * 3];
|
|
|
+ tmpFloatN = new float[maxVertCount * 3];
|
|
|
+ tmpFloatT = new float[maxVertCount * 4];
|
|
|
}
|
|
|
-
|
|
|
|
|
|
- private void doTransformVerts(FloatBuffer inBuf, int start, int end, FloatBuffer outBuf, Matrix4f transform) {
|
|
|
+ private void doTransforms(FloatBuffer bufPos, FloatBuffer bufNorm, int start, int end, Matrix4f transform) {
|
|
|
TempVars vars = TempVars.get();
|
|
|
Vector3f pos = vars.vect1;
|
|
|
+ Vector3f norm = vars.vect2;
|
|
|
|
|
|
int length = (end - start) * 3;
|
|
|
|
|
|
// offset is given in element units
|
|
|
// convert to be in component units
|
|
|
int offset = start * 3;
|
|
|
-
|
|
|
- for (int i = start; i < end; i++) {
|
|
|
- int index = i * 3;
|
|
|
- pos.x = inBuf.get(index);
|
|
|
- pos.y = inBuf.get(index + 1);
|
|
|
- pos.z = inBuf.get(index + 2);
|
|
|
+ bufPos.position(offset);
|
|
|
+ bufNorm.position(offset);
|
|
|
+ bufPos.get(tmpFloat, 0, length);
|
|
|
+ bufNorm.get(tmpFloatN, 0, length);
|
|
|
+ int index = 0;
|
|
|
+ while (index < length) {
|
|
|
+ pos.x = tmpFloat[index];
|
|
|
+ norm.x = tmpFloatN[index++];
|
|
|
+ pos.y = tmpFloat[index];
|
|
|
+ norm.y = tmpFloatN[index++];
|
|
|
+ pos.z = tmpFloat[index];
|
|
|
+ norm.z = tmpFloatN[index];
|
|
|
|
|
|
transform.mult(pos, pos);
|
|
|
- index -= offset;
|
|
|
+ transform.multNormal(norm, norm);
|
|
|
+
|
|
|
+ index -= 2;
|
|
|
tmpFloat[index] = pos.x;
|
|
|
- tmpFloat[index + 1] = pos.y;
|
|
|
- tmpFloat[index + 2] = pos.z;
|
|
|
+ tmpFloatN[index++] = norm.x;
|
|
|
+ tmpFloat[index] = pos.y;
|
|
|
+ tmpFloatN[index++] = norm.y;
|
|
|
+ tmpFloat[index] = pos.z;
|
|
|
+ tmpFloatN[index++] = norm.z;
|
|
|
|
|
|
}
|
|
|
vars.release();
|
|
|
- outBuf.position(offset);
|
|
|
+ bufPos.position(offset);
|
|
|
//using bulk put as it's faster
|
|
|
- outBuf.put(tmpFloat, 0, length);
|
|
|
+ bufPos.put(tmpFloat, 0, length);
|
|
|
+ bufNorm.position(offset);
|
|
|
+ //using bulk put as it's faster
|
|
|
+ bufNorm.put(tmpFloatN, 0, length);
|
|
|
}
|
|
|
|
|
|
- private void doTransformNorm(FloatBuffer inBuf, int start, int end, FloatBuffer outBuf, Matrix4f transform) {
|
|
|
+ private void doTransformsTangents(FloatBuffer bufPos, FloatBuffer bufNorm, FloatBuffer bufTangents, int start, int end, Matrix4f transform) {
|
|
|
TempVars vars = TempVars.get();
|
|
|
Vector3f pos = vars.vect1;
|
|
|
- int length = (end - start) * 3;
|
|
|
+ Vector3f norm = vars.vect2;
|
|
|
+ Vector3f tan = vars.vect3;
|
|
|
|
|
|
+ int length = (end - start) * 3;
|
|
|
+ int tanLength = (end - start) * 4;
|
|
|
|
|
|
// offset is given in element units
|
|
|
// convert to be in component units
|
|
|
int offset = start * 3;
|
|
|
+ int tanOffset = start * 4;
|
|
|
+
|
|
|
+ bufPos.position(offset);
|
|
|
+ bufNorm.position(offset);
|
|
|
+ bufTangents.position(tanOffset);
|
|
|
+ bufPos.get(tmpFloat, 0, length);
|
|
|
+ bufNorm.get(tmpFloatN, 0, length);
|
|
|
+ bufTangents.get(tmpFloatT, 0, tanLength);
|
|
|
+
|
|
|
+ int index = 0;
|
|
|
+ int tanIndex = 0;
|
|
|
+ while (index < length) {
|
|
|
+ pos.x = tmpFloat[index];
|
|
|
+ norm.x = tmpFloatN[index++];
|
|
|
+ pos.y = tmpFloat[index];
|
|
|
+ norm.y = tmpFloatN[index++];
|
|
|
+ pos.z = tmpFloat[index];
|
|
|
+ norm.z = tmpFloatN[index];
|
|
|
+
|
|
|
+ tan.x = tmpFloatT[tanIndex++];
|
|
|
+ tan.y = tmpFloatT[tanIndex++];
|
|
|
+ tan.z = tmpFloatT[tanIndex++];
|
|
|
+
|
|
|
|
|
|
- for (int i = start; i < end; i++) {
|
|
|
- int index = i * 3;
|
|
|
- pos.x = inBuf.get(index);
|
|
|
- pos.y = inBuf.get(index + 1);
|
|
|
- pos.z = inBuf.get(index + 2);
|
|
|
+ transform.mult(pos, pos);
|
|
|
+ transform.multNormal(norm, norm);
|
|
|
+ transform.multNormal(tan, tan);
|
|
|
|
|
|
- transform.multNormal(pos, pos);
|
|
|
- index -= offset;
|
|
|
+ index -= 2;
|
|
|
+ tanIndex -= 3;
|
|
|
+
|
|
|
tmpFloat[index] = pos.x;
|
|
|
- tmpFloat[index + 1] = pos.y;
|
|
|
- tmpFloat[index + 2] = pos.z;
|
|
|
+ tmpFloatN[index++] = norm.x;
|
|
|
+ tmpFloat[index] = pos.y;
|
|
|
+ tmpFloatN[index++] = norm.y;
|
|
|
+ tmpFloat[index] = pos.z;
|
|
|
+ tmpFloatN[index++] = norm.z;
|
|
|
+
|
|
|
+ tmpFloatT[tanIndex++] = tan.x;
|
|
|
+ tmpFloatT[tanIndex++] = tan.y;
|
|
|
+ tmpFloatT[tanIndex++] = tan.z;
|
|
|
+
|
|
|
+ tanIndex++;
|
|
|
|
|
|
}
|
|
|
vars.release();
|
|
|
- outBuf.position(offset);
|
|
|
+ bufPos.position(offset);
|
|
|
+ //using bulk put as it's faster
|
|
|
+ bufPos.put(tmpFloat, 0, length);
|
|
|
+ bufNorm.position(offset);
|
|
|
+ //using bulk put as it's faster
|
|
|
+ bufNorm.put(tmpFloatN, 0, length);
|
|
|
+ bufTangents.position(tanOffset);
|
|
|
//using bulk put as it's faster
|
|
|
- outBuf.put(tmpFloat, 0, length);
|
|
|
+ bufTangents.put(tmpFloatT, 0, tanLength);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
private void doCopyBuffer(FloatBuffer inBuf, int offset, FloatBuffer outBuf) {
|
|
|
TempVars vars = TempVars.get();
|
|
|
Vector3f pos = vars.vect1;
|