modules/graphics/src/main/java/com/sun/prism/impl/BaseMesh.java
Print this page
*** 155,166 ****
return buildNativeGeometry(vertexBuffer,
numberOfVertices * VERTEX_SIZE_VB, indexBufferShort, nFaces * 3);
}
}
! private float[] tangents;
! private float[] bitangents;
private float[] vertexBuffer;
private int[] indexBuffer;
private short[] indexBufferShort;
private int indexBufferSize;
private int numberOfVertices;
--- 155,168 ----
return buildNativeGeometry(vertexBuffer,
numberOfVertices * VERTEX_SIZE_VB, indexBufferShort, nFaces * 3);
}
}
! private boolean[] dirtyVertices;
! private float[] cachedNormals;
! private float[] cachedTangents;
! private float[] cachedBitangents;
private float[] vertexBuffer;
private int[] indexBuffer;
private short[] indexBufferShort;
private int indexBufferSize;
private int numberOfVertices;
*** 268,277 ****
--- 270,318 ----
return buildNativeGeometry(vertexBuffer,
numberOfVertices * VERTEX_SIZE_VB, indexBufferShort, nFaces * 3);
}
}
+ private void convertNormalsToQuats(MeshTempState instance, int numberOfVertices,
+ float[] normals, float[] tangents, float[] bitangents,
+ float[] vertexBuffer, boolean[] dirtys) {
+
+ Vec3f normal = instance.vec3f1;
+ Vec3f tangent = instance.vec3f2;
+ Vec3f bitangent = instance.vec3f3;
+ for (int i = 0, vbIndex = 0; i < numberOfVertices; i++, vbIndex += VERTEX_SIZE_VB) {
+ // Note: If dirtys isn't null, dirtys.length == numberOfVertices is true
+ if (dirtys == null || dirtys[i]) {
+ int index = i * NORMAL_SIZE;
+
+ normal.x = normals[index];
+ normal.y = normals[index + 1];
+ normal.z = normals[index + 2];
+ normal.normalize();
+
+ // tangent and bitangent have been normalized.
+ tangent.x = tangents[index];
+ tangent.y = tangents[index + 1];
+ tangent.z = tangents[index + 2];
+ bitangent.x = bitangents[index];
+ bitangent.y = bitangents[index + 1];
+ bitangent.z = bitangents[index + 2];
+
+ instance.triNormals[0].set(normal);
+ instance.triNormals[1].set(tangent);
+ instance.triNormals[2].set(bitangent);
+ MeshUtil.fixTSpace(instance.triNormals);
+ buildVSQuat(instance.triNormals, instance.quat);
+
+ vertexBuffer[vbIndex + 5] = instance.quat.x;
+ vertexBuffer[vbIndex + 6] = instance.quat.y;
+ vertexBuffer[vbIndex + 7] = instance.quat.z;
+ vertexBuffer[vbIndex + 8] = instance.quat.w;
+ }
+ }
+ }
+
// Build PointNormalTexCoordGeometry
private boolean doBuildPNTGeometry(float[] points, float[] normals,
float[] texCoords, int[] faces) {
if (point2vbMap == null) {
*** 305,322 ****
Integer mf2vb;
BaseMesh.MeshGeomComp2VB mp2vb;
BaseMesh.MeshGeomComp2VB mn2vb;
BaseMesh.MeshGeomComp2VB mt2vb;
// Allocate an initial size, may grow as we process the faces array.
! tangents = new float[numPoints * NORMAL_SIZE];
! bitangents = new float[numPoints * NORMAL_SIZE];
vertexBuffer = new float[numPoints * VERTEX_SIZE_VB];
indexBuffer = new int[numFaces * 3];
int ibCount = 0;
int vbCount = 0;
MeshTempState instance = MeshTempState.getInstance();
for (int faceCount = 0; faceCount < numFaces; faceCount++) {
int faceIndex = faceCount * faceIndexSize;
for (int i = 0; i < 3; i++) {
int vertexIndex = faceIndex + (i * vertexIndexSize);
--- 346,372 ----
Integer mf2vb;
BaseMesh.MeshGeomComp2VB mp2vb;
BaseMesh.MeshGeomComp2VB mn2vb;
BaseMesh.MeshGeomComp2VB mt2vb;
// Allocate an initial size, may grow as we process the faces array.
! cachedNormals = new float[numPoints * NORMAL_SIZE];
! cachedTangents = new float[numPoints * NORMAL_SIZE];
! cachedBitangents = new float[numPoints * NORMAL_SIZE];
vertexBuffer = new float[numPoints * VERTEX_SIZE_VB];
indexBuffer = new int[numFaces * 3];
int ibCount = 0;
int vbCount = 0;
MeshTempState instance = MeshTempState.getInstance();
+ for (int i = 0; i < 3; i++) {
+ if (instance.triPoints[i] == null) {
+ instance.triPoints[i] = new Vec3f();
+ }
+ if (instance.triTexCoords[i] == null) {
+ instance.triTexCoords[i] = new Vec2f();
+ }
+ }
for (int faceCount = 0; faceCount < numFaces; faceCount++) {
int faceIndex = faceCount * faceIndexSize;
for (int i = 0; i < 3; i++) {
int vertexIndex = faceIndex + (i * vertexIndexSize);
*** 329,345 ****
if (vertexBuffer.length <= vbCount) {
final int incrementedSize = vbCount + 20; // Let's increment by 20
float[] temp = new float[incrementedSize * VERTEX_SIZE_VB];
System.arraycopy(vertexBuffer, 0, temp, 0, vertexBuffer.length);
vertexBuffer = temp;
! // Enlarge tangents and bitangents too
temp = new float[incrementedSize * 3];
! System.arraycopy(tangents, 0, temp, 0, tangents.length);
! tangents = temp;
temp = new float[incrementedSize * 3];
! System.arraycopy(bitangents, 0, temp, 0, bitangents.length);
! bitangents = temp;
}
int pointOffset = faces[pointIndex] * POINT_SIZE;
int normalOffset = faces[normalIndex] * NORMAL_SIZE;
int texCoordOffset = faces[texCoordIndex] * TEXCOORD_SIZE;
--- 379,398 ----
if (vertexBuffer.length <= vbCount) {
final int incrementedSize = vbCount + 20; // Let's increment by 20
float[] temp = new float[incrementedSize * VERTEX_SIZE_VB];
System.arraycopy(vertexBuffer, 0, temp, 0, vertexBuffer.length);
vertexBuffer = temp;
! // Enlarge cachedNormals, cachedTangents and cachedBitangents too
! temp = new float[incrementedSize * 3];
! System.arraycopy(cachedNormals, 0, temp, 0, cachedNormals.length);
! cachedNormals = temp;
temp = new float[incrementedSize * 3];
! System.arraycopy(cachedTangents, 0, temp, 0, cachedTangents.length);
! cachedTangents = temp;
temp = new float[incrementedSize * 3];
! System.arraycopy(cachedBitangents, 0, temp, 0, cachedBitangents.length);
! cachedBitangents = temp;
}
int pointOffset = faces[pointIndex] * POINT_SIZE;
int normalOffset = faces[normalIndex] * NORMAL_SIZE;
int texCoordOffset = faces[texCoordIndex] * TEXCOORD_SIZE;
*** 351,365 ****
vertexBuffer[vbCount] = points[pointOffset];
vertexBuffer[vbCount + 1] = points[pointOffset + 1];
vertexBuffer[vbCount + 2] = points[pointOffset + 2];
vertexBuffer[vbCount + 3] = texCoords[texCoordOffset];
vertexBuffer[vbCount + 4] = texCoords[texCoordOffset + 1];
! // Temporarily store the normal in the quaterion slot
! vertexBuffer[vbCount + 5] = normals[normalOffset];
! vertexBuffer[vbCount + 6] = normals[normalOffset + 1];
! vertexBuffer[vbCount + 7] = normals[normalOffset + 2];
! vertexBuffer[vbCount + 8] = 0;
vbCount += VERTEX_SIZE_VB;
mp2vb = point2vbMap.get(pointOffset);
if (mp2vb == null) {
--- 404,418 ----
vertexBuffer[vbCount] = points[pointOffset];
vertexBuffer[vbCount + 1] = points[pointOffset + 1];
vertexBuffer[vbCount + 2] = points[pointOffset + 2];
vertexBuffer[vbCount + 3] = texCoords[texCoordOffset];
vertexBuffer[vbCount + 4] = texCoords[texCoordOffset + 1];
! // Store the normal in the cachedNormals array
! int index = instance.triVerts[i] * NORMAL_SIZE;
! cachedNormals[index] = normals[normalOffset];
! cachedNormals[index + 1] = normals[normalOffset + 1];
! cachedNormals[index + 2] = normals[normalOffset + 2];
vbCount += VERTEX_SIZE_VB;
mp2vb = point2vbMap.get(pointOffset);
if (mp2vb == null) {
*** 396,414 ****
}
// This is the best time to compute the tangent and bitangent for each
// of the vertex. Go thro. the 3 vertices of a triangle
for (int i = 0; i < 3; i++) {
- if (instance.triPoints[i] == null) {
- instance.triPoints[i] = new Vec3f();
- }
instance.triPoints[i].x = points[instance.triPointIndex[i]];
instance.triPoints[i].y = points[instance.triPointIndex[i] + 1];
instance.triPoints[i].z = points[instance.triPointIndex[i] + 2];
- if (instance.triTexCoords[i] == null) {
- instance.triTexCoords[i] = new Vec2f();
- }
instance.triTexCoords[i].x = texCoords[instance.triTexCoordIndex[i]];
instance.triTexCoords[i].y = texCoords[instance.triTexCoordIndex[i] + 1];
}
MeshUtil.computeTBNNormalized(instance.triPoints[0], instance.triPoints[1],
--- 449,461 ----
*** 416,466 ****
instance.triTexCoords[1], instance.triTexCoords[2],
instance.triNormals);
for (int i = 0; i < 3; i++) {
int index = instance.triVerts[i] * NORMAL_SIZE;
! tangents[index] = instance.triNormals[1].x;
! tangents[index + 1] = instance.triNormals[1].y;
! tangents[index + 2] = instance.triNormals[1].z;
! bitangents[index] = instance.triNormals[2].x;
! bitangents[index + 1] = instance.triNormals[2].y;
! bitangents[index + 2] = instance.triNormals[2].z;
}
}
numberOfVertices = vbCount / VERTEX_SIZE_VB;
! Vec3f normal = instance.vec3f1;
! Vec3f tangent = instance.vec3f2;
! Vec3f bitangent = instance.vec3f3;
! for (int i = 0, vbIndex = 0; i < numberOfVertices; i++, vbIndex += VERTEX_SIZE_VB) {
! normal.x = vertexBuffer[vbIndex + 5];
! normal.y = vertexBuffer[vbIndex + 6];
! normal.z = vertexBuffer[vbIndex + 7];
! normal.normalize();
!
! int index = i * NORMAL_SIZE;
! // tangent and bitangent have been normalized.
! tangent.x = tangents[index];
! tangent.y = tangents[index + 1];
! tangent.z = tangents[index + 2];
! bitangent.x = bitangents[index];
! bitangent.y = bitangents[index + 1];
! bitangent.z = bitangents[index + 2];
!
! instance.triNormals[0].set(normal);
! instance.triNormals[1].set(tangent);
! instance.triNormals[2].set(bitangent);
! MeshUtil.fixTSpace(instance.triNormals);
! buildVSQuat(instance.triNormals, instance.quat);
!
! vertexBuffer[vbIndex + 5] = instance.quat.x;
! vertexBuffer[vbIndex + 6] = instance.quat.y;
! vertexBuffer[vbIndex + 7] = instance.quat.z;
! vertexBuffer[vbIndex + 8] = instance.quat.w;
! }
indexBufferSize = numFaces * 3;
if (numberOfVertices > 0x10000) { // > 64K
return buildNativeGeometry(vertexBuffer,
--- 463,486 ----
instance.triTexCoords[1], instance.triTexCoords[2],
instance.triNormals);
for (int i = 0; i < 3; i++) {
int index = instance.triVerts[i] * NORMAL_SIZE;
! cachedTangents[index] = instance.triNormals[1].x;
! cachedTangents[index + 1] = instance.triNormals[1].y;
! cachedTangents[index + 2] = instance.triNormals[1].z;
! cachedBitangents[index] = instance.triNormals[2].x;
! cachedBitangents[index + 1] = instance.triNormals[2].y;
! cachedBitangents[index + 2] = instance.triNormals[2].z;
}
}
numberOfVertices = vbCount / VERTEX_SIZE_VB;
! convertNormalsToQuats(instance, numberOfVertices,
! cachedNormals, cachedTangents, cachedBitangents, vertexBuffer, null);
indexBufferSize = numFaces * 3;
if (numberOfVertices > 0x10000) { // > 64K
return buildNativeGeometry(vertexBuffer,
*** 484,493 ****
--- 504,521 ----
// Update PointNormalTexCoordGeometry
private boolean updatePNTGeometry(float[] points, int[] pointsFromAndLengthIndices,
float[] normals, int[] normalsFromAndLengthIndices,
float[] texCoords, int[] texCoordsFromAndLengthIndices) {
+
+ if (dirtyVertices == null) {
+ // Create a dirty array of size equal to number of vertices in vertexBuffer.
+ dirtyVertices = new boolean[numberOfVertices];
+ }
+ // Clear dirty array before use.
+ Arrays.fill(dirtyVertices, false);
+
// Find out the list of modified points
int startPoint = pointsFromAndLengthIndices[0] / POINT_SIZE;
int numPoints = (pointsFromAndLengthIndices[1] / POINT_SIZE);
if ((pointsFromAndLengthIndices[1] % POINT_SIZE) > 0) {
numPoints++;
*** 506,522 ****
--- 534,552 ----
for (int j = 0; j < validLocs; j++) {
int vbIndex = locs[j] * VERTEX_SIZE_VB;
vertexBuffer[vbIndex] = points[pointOffset];
vertexBuffer[vbIndex + 1] = points[pointOffset + 1];
vertexBuffer[vbIndex + 2] = points[pointOffset + 2];
+ dirtyVertices[locs[j]] = true;
}
} else {
int loc = mp2vb.getLoc();
int vbIndex = loc * VERTEX_SIZE_VB;
vertexBuffer[vbIndex] = points[pointOffset];
vertexBuffer[vbIndex + 1] = points[pointOffset + 1];
vertexBuffer[vbIndex + 2] = points[pointOffset + 2];
+ dirtyVertices[loc] = true;
}
}
}
}
*** 539,554 ****
--- 569,586 ----
if (locs != null) {
for (int j = 0; j < validLocs; j++) {
int vbIndex = (locs[j] * VERTEX_SIZE_VB) + POINT_SIZE_VB;
vertexBuffer[vbIndex] = texCoords[texCoordOffset];
vertexBuffer[vbIndex + 1] = texCoords[texCoordOffset + 1];
+ dirtyVertices[locs[j]] = true;
}
} else {
int loc = mt2vb.getLoc();
int vbIndex = (loc * VERTEX_SIZE_VB) + POINT_SIZE_VB;
vertexBuffer[vbIndex] = texCoords[texCoordOffset];
vertexBuffer[vbIndex + 1] = texCoords[texCoordOffset + 1];
+ dirtyVertices[loc] = true;
}
}
}
}
*** 569,624 ****
if (mn2vb != null) {
int[] locs = mn2vb.getLocs();
int validLocs = mn2vb.getValidLocs();
if (locs != null) {
for (int j = 0; j < validLocs; j++) {
! int vbIndex = (locs[j] * VERTEX_SIZE_VB)
! + POINT_SIZE_VB + TEXCOORD_SIZE_VB;
!
! instance.triNormals[0].x = normals[normalOffset];
! instance.triNormals[0].y = normals[normalOffset + 1];
! instance.triNormals[0].z = normals[normalOffset + 2];
! instance.triNormals[0].normalize();
! instance.triNormals[1].x = tangents[normalOffset];
! instance.triNormals[1].y = tangents[normalOffset + 1];
! instance.triNormals[1].z = tangents[normalOffset + 2];
! instance.triNormals[2].x = bitangents[normalOffset];
! instance.triNormals[2].y = bitangents[normalOffset + 1];
! instance.triNormals[2].z = bitangents[normalOffset + 2];
! MeshUtil.fixTSpace(instance.triNormals);
! buildVSQuat(instance.triNormals, instance.quat);
! vertexBuffer[vbIndex] = instance.quat.x;
! vertexBuffer[vbIndex + 1] = instance.quat.y;
! vertexBuffer[vbIndex + 2] = instance.quat.z;
! vertexBuffer[vbIndex + 3] = instance.quat.w;
}
} else {
int loc = mn2vb.getLoc();
! int vbIndex = (loc * VERTEX_SIZE_VB)
! + POINT_SIZE_VB + TEXCOORD_SIZE_VB;
! instance.triNormals[0].x = normals[normalOffset];
! instance.triNormals[0].y = normals[normalOffset + 1];
! instance.triNormals[0].z = normals[normalOffset + 2];
! instance.triNormals[0].normalize();
! instance.triNormals[1].x = tangents[normalOffset];
! instance.triNormals[1].y = tangents[normalOffset + 1];
! instance.triNormals[1].z = tangents[normalOffset + 2];
! instance.triNormals[2].x = bitangents[normalOffset];
! instance.triNormals[2].y = bitangents[normalOffset + 1];
! instance.triNormals[2].z = bitangents[normalOffset + 2];
! MeshUtil.fixTSpace(instance.triNormals);
! buildVSQuat(instance.triNormals, instance.quat);
! vertexBuffer[vbIndex] = instance.quat.x;
! vertexBuffer[vbIndex + 1] = instance.quat.y;
! vertexBuffer[vbIndex + 2] = instance.quat.z;
! vertexBuffer[vbIndex + 3] = instance.quat.w;
}
}
}
}
if (indexBuffer != null) {
return buildNativeGeometry(vertexBuffer,
numberOfVertices * VERTEX_SIZE_VB, indexBuffer, indexBufferSize);
} else {
return buildNativeGeometry(vertexBuffer,
--- 601,675 ----
if (mn2vb != null) {
int[] locs = mn2vb.getLocs();
int validLocs = mn2vb.getValidLocs();
if (locs != null) {
for (int j = 0; j < validLocs; j++) {
! int index = locs[j] * NORMAL_SIZE;
! cachedNormals[index] = normals[normalOffset];
! cachedNormals[index + 1] = normals[normalOffset + 1];
! cachedNormals[index + 2] = normals[normalOffset + 2];
! dirtyVertices[locs[j]] = true;
}
} else {
int loc = mn2vb.getLoc();
! int index = loc * NORMAL_SIZE;
! cachedNormals[index] = normals[normalOffset];
! cachedNormals[index + 1] = normals[normalOffset + 1];
! cachedNormals[index + 2] = normals[normalOffset + 2];
! dirtyVertices[loc] = true;
! }
! }
! }
! }
! // Prepare process all dirty vertices
! MeshTempState instance = MeshTempState.getInstance();
! for (int i = 0; i < 3; i++) {
! if (instance.triPoints[i] == null) {
! instance.triPoints[i] = new Vec3f();
! }
! if (instance.triTexCoords[i] == null) {
! instance.triTexCoords[i] = new Vec2f();
}
}
+ // Every 3 vertices form a triangle
+ for (int j = 0; j < numberOfVertices; j += 3) {
+ // Only process the triangle that has one of more dirty vertices
+ if (dirtyVertices[j] || dirtyVertices[j+1] || dirtyVertices[j+2]) {
+ int vbIndex = j * VERTEX_SIZE_VB;
+ // Go thro. the 3 vertices of a triangle
+ for (int i = 0; i < 3; i++) {
+ instance.triPoints[i].x = vertexBuffer[vbIndex];
+ instance.triPoints[i].y = vertexBuffer[vbIndex + 1];
+ instance.triPoints[i].z = vertexBuffer[vbIndex + 2];
+ instance.triTexCoords[i].x = vertexBuffer[vbIndex + POINT_SIZE_VB];
+ instance.triTexCoords[i].y = vertexBuffer[vbIndex + POINT_SIZE_VB + 1];
+ vbIndex += VERTEX_SIZE_VB;
+ }
+
+ MeshUtil.computeTBNNormalized(instance.triPoints[0], instance.triPoints[1],
+ instance.triPoints[2], instance.triTexCoords[0],
+ instance.triTexCoords[1], instance.triTexCoords[2],
+ instance.triNormals);
+
+ int index = j * NORMAL_SIZE;
+ for (int i = 0; i < 3; i++) {
+ cachedTangents[index] = instance.triNormals[1].x;
+ cachedTangents[index + 1] = instance.triNormals[1].y;
+ cachedTangents[index + 2] = instance.triNormals[1].z;
+ cachedBitangents[index] = instance.triNormals[2].x;
+ cachedBitangents[index + 1] = instance.triNormals[2].y;
+ cachedBitangents[index + 2] = instance.triNormals[2].z;
+ index += NORMAL_SIZE;
+ }
+
}
}
+ convertNormalsToQuats(instance, numberOfVertices,
+ cachedNormals, cachedTangents, cachedBitangents, vertexBuffer, dirtyVertices);
+
if (indexBuffer != null) {
return buildNativeGeometry(vertexBuffer,
numberOfVertices * VERTEX_SIZE_VB, indexBuffer, indexBufferSize);
} else {
return buildNativeGeometry(vertexBuffer,