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,