Kaynağa Gözat

Drastically sped up skeletal animation, optimized render array creation, replaced getVertex/getActualVertex with getVertex/getIndexedVertex to avoid conditionals in vertex access

Ivan Safrin 11 yıl önce
ebeveyn
işleme
38ae3d8a37

+ 2 - 1
CMakeLists.txt

@@ -17,7 +17,8 @@ ENDIF(NOT CMAKE_BUILD_TYPE)
 #ENDIF()
 
 IF(NUMBER_IS_SINGLE)
-add_definitions(-DPOLYCODE_NUMBER_IS_SINGLE)
+	add_definitions(-DPOLYCODE_NUMBER_IS_SINGLE)
+	MESSAGE("USING SINGLE PRECISION NUMBERS")
 ENDIF()
 
 # Options for what components to build

+ 4 - 0
Core/Contents/Include/PolyBone.h

@@ -138,6 +138,9 @@ namespace Polycode {
 			* @return Full base matrix.
 			*/						
 			Matrix4 getFullBaseMatrix() const;
+        
+            void rebuildFinalMatrix();
+            Matrix4 buildFinalMatrix() const;
 		
 			/**
 			* Id of the bone.
@@ -147,6 +150,7 @@ namespace Polycode {
 			Matrix4 boneMatrix;
 			Matrix4 restMatrix;
 			Matrix4 baseMatrix;
+            Matrix4 finalMatrix;
 		
             Quaternion baseRotation;
             Vector3 baseScale;

+ 2 - 15
Core/Contents/Include/PolyMesh.h

@@ -264,11 +264,8 @@ namespace Polycode {
             void addVertex(Vertex *vertex);
         
             Vertex *getVertex(unsigned int index) const;
-
-            Vertex *getActualVertex(unsigned int index) const;
-
-            unsigned int getActualVertexCount() const;
         
+            Vertex *getIndexedVertex(unsigned int index) const;
         
 			/**
 			* Sets the vertex buffer for the mesh.
@@ -296,7 +293,7 @@ namespace Polycode {
 			* @param smooth If true, will use smooth normals.
 			* @param smoothAngle If smooth, this parameter sets the angle tolerance for the approximation function.
 			*/
-			void calculateNormals(bool generateFaceNormals = false);
+			void calculateNormals();
 
 			/**
 			* Recalculates the tangent space vector for all vertices.
@@ -317,9 +314,6 @@ namespace Polycode {
 			void dirtyArray(unsigned int arrayIndex);
 			void dirtyArrays();
 
-            void setUseFaceNormals(bool val);
-            bool getUseFaceNormals();
-
 			inline unsigned int getIndexGroupSize() {
 				switch (meshType) {
 				case QUAD_MESH: return 4;
@@ -413,10 +407,6 @@ namespace Polycode {
 			/** For indexedMesh only, removes any unused vertices from the mesh. */
 			int removeUnusedVertices();
         
-            Vector3 getFaceNormalForVertex(unsigned int index);
-        
-            void addFaceNormal(Vector3 faceNormal);
-        
             unsigned int getIndexCount();
             unsigned int getIndexAt(unsigned int index);
         
@@ -426,13 +416,10 @@ namespace Polycode {
         
             Vector3 calculateFaceTangent(Vertex *v1, Vertex *v2, Vertex *v3);
         
-            bool useFaceNormals;
-        
             VertexBuffer *vertexBuffer;
             bool meshHasVertexBuffer;
             int meshType;
         
-            std::vector<Vector3> faceNormals;
             std::vector<unsigned int> indices;
             std::vector <Vertex*> vertices;
 	};

+ 12 - 6
Core/Contents/Source/PolyBone.cpp

@@ -71,13 +71,19 @@ Matrix4 Bone::getBoneMatrix() const {
 }
 
 Matrix4 Bone::getFinalMatrix() const {
-	Matrix4 final = boneMatrix;
+    return finalMatrix;
+}
 
-	if(parentBone) {
-		final = final * parentBone->getFinalMatrix();
-	} 
-	
-	return final;
+Matrix4 Bone::buildFinalMatrix() const {
+    if(parentBone) {
+        return boneMatrix * parentBone->buildFinalMatrix();
+    } else {
+        return boneMatrix;
+    }
+}
+
+void Bone::rebuildFinalMatrix() {
+    finalMatrix = buildFinalMatrix();
 }
 
 void Bone::setBoneMatrix(const Matrix4& matrix) {

+ 145 - 70
Core/Contents/Source/PolyGLRenderer.cpp

@@ -882,77 +882,152 @@ RenderDataArray *OpenGLRenderer::createRenderDataArrayForMesh(Mesh *mesh, int ar
 	newArray->count = 0;
 	long bufferOffset = 0;
 	GLfloat* buffer = NULL;
-	
-	switch (arrayType) {
-		case RenderDataArray::VERTEX_DATA_ARRAY:
-		{		
-			buffer = (GLfloat*)malloc(mesh->getVertexCount() * sizeof(GLfloat) * 3);
-			for(int i=0; i < mesh->getVertexCount(); i++) {
-                newArray->count++;
-                buffer[bufferOffset+0] = mesh->getVertex(i)->x;
-                buffer[bufferOffset+1] = mesh->getVertex(i)->y;
-                buffer[bufferOffset+2] = mesh->getVertex(i)->z;
-                bufferOffset += 3;
-			}
-		}
-		break;
-		case RenderDataArray::COLOR_DATA_ARRAY:
-		{
-			buffer = (GLfloat*)malloc(mesh->getVertexCount() * sizeof(GLfloat) * 4);
-			for(int i=0; i < mesh->getVertexCount(); i++) {
-                buffer[bufferOffset+0] = mesh->getVertex(i)->vertexColor.r;
-                buffer[bufferOffset+1] = mesh->getVertex(i)->vertexColor.g;
-                buffer[bufferOffset+2] = mesh->getVertex(i)->vertexColor.b;
-                buffer[bufferOffset+3] = mesh->getVertex(i)->vertexColor.a;
-                bufferOffset += 4;
-			}
-		}
-		break;
-		case RenderDataArray::NORMAL_DATA_ARRAY:
-		{
-			buffer = (GLfloat*)malloc(mesh->getVertexCount() * sizeof(GLfloat) * 3);
-			
-			for(int i=0; i < mesh->getVertexCount(); i++) {
-                if(mesh->getUseFaceNormals()) {
-                    Vector3 n = mesh->getFaceNormalForVertex(i);
-                    buffer[bufferOffset+0] = n.x;
-                    buffer[bufferOffset+1] = n.y;
-                    buffer[bufferOffset+2] = n.z;
-                } else {
-                    buffer[bufferOffset+0] = mesh->getVertex(i)->normal.x;
-                    buffer[bufferOffset+1] = mesh->getVertex(i)->normal.y;
-                    buffer[bufferOffset+2] = mesh->getVertex(i)->normal.z;
+    
+    Vertex *vertex;
+    if(mesh->indexedMesh) {
+        
+        unsigned int indexCount = mesh->getIndexCount();
+        
+        switch (arrayType) {
+            case RenderDataArray::VERTEX_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(indexCount * sizeof(GLfloat) * 3);
+                for(int i=0; i < indexCount; i++) {
+                    vertex = mesh->getIndexedVertex(i);
+                    buffer[bufferOffset+0] = vertex->x;
+                    buffer[bufferOffset+1] = vertex->y;
+                    buffer[bufferOffset+2] = vertex->z;
+                    bufferOffset += 3;
+                    newArray->count++;
                 }
-                bufferOffset += 3;
-			}			
-		}
-		break;
-		case RenderDataArray::TANGENT_DATA_ARRAY:
-		{
-			buffer = (GLfloat*)malloc(mesh->getVertexCount() * sizeof(GLfloat) * 3);
-			
-			for(int i=0; i < mesh->getVertexCount(); i++) {
-                buffer[bufferOffset+0] = mesh->getVertex(i)->tangent.x;
-                buffer[bufferOffset+1] = mesh->getVertex(i)->tangent.y;
-                buffer[bufferOffset+2] = mesh->getVertex(i)->tangent.z;
-                bufferOffset += 3;
-			}			
-		}
-		break;		
-		case RenderDataArray::TEXCOORD_DATA_ARRAY:
-		{
-			buffer = (GLfloat*)malloc(mesh->getVertexCount() * sizeof(GLfloat) * 2);
-			for(int i=0; i < mesh->getVertexCount(); i++) {
-                buffer[bufferOffset+0] = mesh->getVertex(i)->getTexCoord().x;
-                buffer[bufferOffset+1] = mesh->getVertex(i)->getTexCoord().y;
-                bufferOffset += 2;
-			}			
-		}
-		break;
-		default:
-		break;
-	}
-	
+            }
+                break;
+            case RenderDataArray::COLOR_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(indexCount * sizeof(GLfloat) * 4);
+                for(int i=0; i < indexCount; i++) {
+                    vertex = mesh->getIndexedVertex(i);
+                    buffer[bufferOffset+0] = vertex->vertexColor.r;
+                    buffer[bufferOffset+1] = vertex->vertexColor.g;
+                    buffer[bufferOffset+2] = vertex->vertexColor.b;
+                    buffer[bufferOffset+3] = vertex->vertexColor.a;
+                    bufferOffset += 4;
+                }
+            }
+                break;
+            case RenderDataArray::NORMAL_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(indexCount * sizeof(GLfloat) * 3);
+                for(int i=0; i < indexCount; i++) {
+                    vertex = mesh->getIndexedVertex(i);
+                    buffer[bufferOffset+0] = vertex->normal.x;
+                    buffer[bufferOffset+1] = vertex->normal.y;
+                    buffer[bufferOffset+2] = vertex->normal.z;
+                    bufferOffset += 3;                    
+                }
+                
+            }
+                break;
+            case RenderDataArray::TANGENT_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(indexCount * sizeof(GLfloat) * 3);
+                
+                for(int i=0; i < indexCount; i++) {
+                    vertex = mesh->getIndexedVertex(i);
+                    buffer[bufferOffset+0] = vertex->tangent.x;
+                    buffer[bufferOffset+1] = vertex->tangent.y;
+                    buffer[bufferOffset+2] = vertex->tangent.z;
+                    bufferOffset += 3;
+                }
+            }
+                break;
+            case RenderDataArray::TEXCOORD_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(indexCount * sizeof(GLfloat) * 2);
+                for(int i=0; i < indexCount; i++) {
+                    vertex = mesh->getIndexedVertex(i);
+                    buffer[bufferOffset+0] = vertex->getTexCoord().x;
+                    buffer[bufferOffset+1] = vertex->getTexCoord().y;
+                    bufferOffset += 2;
+                }
+            }
+                break;
+            default:
+            break;
+        }
+        
+    } else {
+        unsigned int vertexCount = mesh->getVertexCount();
+        
+        switch (arrayType) {
+            case RenderDataArray::VERTEX_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(vertexCount * sizeof(GLfloat) * 3);
+                for(int i=0; i < vertexCount; i++) {
+                    vertex = mesh->getVertex(i);
+                    buffer[bufferOffset+0] = vertex->x;
+                    buffer[bufferOffset+1] = vertex->y;
+                    buffer[bufferOffset+2] = vertex->z;
+                    bufferOffset += 3;
+                    newArray->count++;
+                }
+            }
+                break;
+            case RenderDataArray::COLOR_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(vertexCount * sizeof(GLfloat) * 4);
+                for(int i=0; i < vertexCount; i++) {
+                    vertex = mesh->getVertex(i);
+                    buffer[bufferOffset+0] = vertex->vertexColor.r;
+                    buffer[bufferOffset+1] = vertex->vertexColor.g;
+                    buffer[bufferOffset+2] = vertex->vertexColor.b;
+                    buffer[bufferOffset+3] = vertex->vertexColor.a;
+                    bufferOffset += 4;
+                }
+            }
+                break;
+            case RenderDataArray::NORMAL_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(vertexCount * sizeof(GLfloat) * 3);
+                for(int i=0; i < vertexCount; i++) {
+                    vertex = mesh->getVertex(i);
+                    buffer[bufferOffset+0] = vertex->normal.x;
+                    buffer[bufferOffset+1] = vertex->normal.y;
+                    buffer[bufferOffset+2] = vertex->normal.z;
+                    bufferOffset += 3;
+                }
+  
+            }
+                break;
+            case RenderDataArray::TANGENT_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(vertexCount * sizeof(GLfloat) * 3);
+                
+                for(int i=0; i < vertexCount; i++) {
+                    vertex = mesh->getVertex(i);
+                    buffer[bufferOffset+0] = vertex->tangent.x;
+                    buffer[bufferOffset+1] = vertex->tangent.y;
+                    buffer[bufferOffset+2] = vertex->tangent.z;
+                    bufferOffset += 3;
+                }
+            }
+                break;		
+            case RenderDataArray::TEXCOORD_DATA_ARRAY:
+            {
+                buffer = (GLfloat*)malloc(vertexCount * sizeof(GLfloat) * 2);
+                for(int i=0; i < vertexCount; i++) {
+                    vertex = mesh->getVertex(i);
+                    buffer[bufferOffset+0] = vertex->getTexCoord().x;
+                    buffer[bufferOffset+1] = vertex->getTexCoord().y;
+                    bufferOffset += 2;
+                }			
+            }
+            break;
+            default:
+            break;
+        }
+    }
+    
 	if(buffer != NULL) {
 		free(newArray->arrayPtr);
 		newArray->arrayPtr = buffer;		

+ 175 - 83
Core/Contents/Source/PolyGLVertexBuffer.cpp

@@ -51,96 +51,188 @@ OpenGLVertexBuffer::OpenGLVertexBuffer(Mesh *mesh) : VertexBuffer() {
 	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBufferID);
 	
 	meshType = mesh->getMeshType();
-	
-	long bufferOffset = 0;
-    int bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
-	GLfloat *buffer = (GLfloat*)malloc(bufferSize);
     
-	vertexCount = 0;
-	for(int i=0; i < mesh->getVertexCount(); i++) {
-        vertexCount++;
-        buffer[bufferOffset+0] = mesh->getVertex(i)->x;
-        buffer[bufferOffset+1] = mesh->getVertex(i)->y;
-        buffer[bufferOffset+2] = mesh->getVertex(i)->z;
-        bufferOffset += 3;
-	}
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
-	free(buffer);
+    Vertex *vertex;
+    
+    if(mesh->indexedMesh) {
+        
+        long bufferOffset = 0;
+        int bufferSize = mesh->getIndexCount() * sizeof(GLfloat) * 3;
+        GLfloat *buffer = (GLfloat*)malloc(bufferSize);
+        
+        vertexCount = 0;
+        for(int i=0; i < mesh->getIndexCount(); i++) {
+            vertexCount++;
+            vertex = mesh->getIndexedVertex(i);
+            buffer[bufferOffset+0] = vertex->x;
+            buffer[bufferOffset+1] = vertex->y;
+            buffer[bufferOffset+2] = vertex->z;
+            bufferOffset += 3;
+        }
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+        
+        glGenBuffersARB(1, &texCoordBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, texCoordBufferID);
+        
+        
+        
+        bufferOffset = 0;
+        bufferSize = mesh->getIndexCount() * sizeof(GLfloat) * 2;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getIndexCount(); i++) {
+            vertex = mesh->getIndexedVertex(i);
+            buffer[bufferOffset+0] = vertex->getTexCoord().x;
+            buffer[bufferOffset+1] = vertex->getTexCoord().y;
+            bufferOffset += 2;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+        
+        glGenBuffersARB(1, &normalBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalBufferID);
+        
+        bufferSize = mesh->getIndexCount() * sizeof(GLfloat) * 3;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getIndexCount(); i++) {
+            vertex = mesh->getIndexedVertex(i);
+            buffer[bufferOffset+0] = vertex->normal.x;
+            buffer[bufferOffset+1] = vertex->normal.y;
+            buffer[bufferOffset+2] = vertex->normal.z;
+            bufferOffset += 3;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+        
+        glGenBuffersARB(1, &tangentBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, tangentBufferID);
+        
+        bufferSize = mesh->getIndexCount() * sizeof(GLfloat) * 3;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getIndexCount(); i++) {
+            vertex = mesh->getIndexedVertex(i);
+            buffer[bufferOffset+0] = vertex->tangent.x;
+            buffer[bufferOffset+1] = vertex->tangent.y;
+            buffer[bufferOffset+2] = vertex->tangent.z;
+            bufferOffset += 3;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+        
+        glGenBuffersARB(1, &colorBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorBufferID);
+        
+        bufferSize = mesh->getIndexCount() * sizeof(GLfloat) * 4;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getIndexCount(); i++) {
+            vertex = mesh->getIndexedVertex(i);
+            buffer[bufferOffset+0] = vertex->vertexColor.r;
+            buffer[bufferOffset+1] = vertex->vertexColor.g;
+            buffer[bufferOffset+2] = vertex->vertexColor.b;
+            buffer[bufferOffset+3] = vertex->vertexColor.a;
+            bufferOffset += 4;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+    } else {
+    
 
-	glGenBuffersARB(1, &texCoordBufferID);
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, texCoordBufferID);
-	
-    bufferOffset = 0;
-	bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 2;
-	buffer = (GLfloat*)malloc(bufferSize);
-	
-	for(int i=0; i < mesh->getVertexCount(); i++) {
-        buffer[bufferOffset+0] = mesh->getVertex(i)->getTexCoord().x;
-        buffer[bufferOffset+1] = mesh->getVertex(i)->getTexCoord().y;
-        bufferOffset += 2;
-	}
-	
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
-	free(buffer);
-	
-	glGenBuffersARB(1, &normalBufferID);
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalBufferID);
-	
-	bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
-    bufferOffset = 0;
-	buffer = (GLfloat*)malloc(bufferSize);
-	
-	for(int i=0; i < mesh->getVertexCount(); i++) {
-        if(mesh->getUseFaceNormals()) {
-            Vector3 n = mesh->getFaceNormalForVertex(i);
-            buffer[bufferOffset+0] = n.x;
-            buffer[bufferOffset+1] = n.y;
-            buffer[bufferOffset+2] = n.z;
-        } else {
+        long bufferOffset = 0;
+        int bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
+        GLfloat *buffer = (GLfloat*)malloc(bufferSize);
+        
+        vertexCount = 0;
+        for(int i=0; i < mesh->getVertexCount(); i++) {
+            vertexCount++;
+            buffer[bufferOffset+0] = mesh->getVertex(i)->x;
+            buffer[bufferOffset+1] = mesh->getVertex(i)->y;
+            buffer[bufferOffset+2] = mesh->getVertex(i)->z;
+            bufferOffset += 3;
+        }
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+
+        glGenBuffersARB(1, &texCoordBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, texCoordBufferID);
+        
+        
+        
+        bufferOffset = 0;
+        bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 2;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getVertexCount(); i++) {
+            buffer[bufferOffset+0] = mesh->getVertex(i)->getTexCoord().x;
+            buffer[bufferOffset+1] = mesh->getVertex(i)->getTexCoord().y;
+            bufferOffset += 2;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+        
+        glGenBuffersARB(1, &normalBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalBufferID);
+        
+        bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getVertexCount(); i++) {
             buffer[bufferOffset+0] = mesh->getVertex(i)->normal.x;
             buffer[bufferOffset+1] = mesh->getVertex(i)->normal.y;
             buffer[bufferOffset+2] = mesh->getVertex(i)->normal.z;
+            bufferOffset += 3;
         }
-        bufferOffset += 3;
-	}
-	
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
-	free(buffer);	
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);	
 
-	glGenBuffersARB(1, &tangentBufferID);
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, tangentBufferID);
-	
-	bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
-    bufferOffset = 0;
-	buffer = (GLfloat*)malloc(bufferSize);
-	
-	for(int i=0; i < mesh->getVertexCount(); i++) {
-        buffer[bufferOffset+0] = mesh->getVertex(i)->tangent.x;
-        buffer[bufferOffset+1] = mesh->getVertex(i)->tangent.y;
-        buffer[bufferOffset+2] = mesh->getVertex(i)->tangent.z;
-        bufferOffset += 3;
-	}
-	
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
-	free(buffer);	
-	
-	glGenBuffersARB(1, &colorBufferID);
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorBufferID);
-	
-	bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 4;
-	bufferOffset = 0;
-	buffer = (GLfloat*)malloc(bufferSize);
-	
-	for(int i=0; i < mesh->getVertexCount(); i++) {
-        buffer[bufferOffset+0] = mesh->getVertex(i)->vertexColor.r;
-        buffer[bufferOffset+1] = mesh->getVertex(i)->vertexColor.g;
-        buffer[bufferOffset+2] = mesh->getVertex(i)->vertexColor.b;
-        buffer[bufferOffset+3] = mesh->getVertex(i)->vertexColor.a;
-        bufferOffset += 4;
-	}
-	
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
-	free(buffer);	
+        glGenBuffersARB(1, &tangentBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, tangentBufferID);
+        
+        bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 3;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getVertexCount(); i++) {
+            buffer[bufferOffset+0] = mesh->getVertex(i)->tangent.x;
+            buffer[bufferOffset+1] = mesh->getVertex(i)->tangent.y;
+            buffer[bufferOffset+2] = mesh->getVertex(i)->tangent.z;
+            bufferOffset += 3;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);	
+        
+        glGenBuffersARB(1, &colorBufferID);
+        glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorBufferID);
+        
+        bufferSize = mesh->getVertexCount() * sizeof(GLfloat) * 4;
+        bufferOffset = 0;
+        buffer = (GLfloat*)malloc(bufferSize);
+        
+        for(int i=0; i < mesh->getVertexCount(); i++) {
+            buffer[bufferOffset+0] = mesh->getVertex(i)->vertexColor.r;
+            buffer[bufferOffset+1] = mesh->getVertex(i)->vertexColor.g;
+            buffer[bufferOffset+2] = mesh->getVertex(i)->vertexColor.b;
+            buffer[bufferOffset+3] = mesh->getVertex(i)->vertexColor.a;
+            bufferOffset += 4;
+        }
+        
+        glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, buffer, GL_STATIC_DRAW_ARB);
+        free(buffer);
+    }
 	
 }
 

+ 7 - 76
Core/Contents/Source/PolyMesh.cpp

@@ -45,7 +45,6 @@ Mesh::Mesh(const String& fileName) {
     loadMesh(fileName);
     vertexBuffer = NULL;			
     useVertexColors = false;
-    useFaceNormals = false;
 }
 
 Mesh::Mesh(int meshType) {
@@ -58,7 +57,6 @@ Mesh::Mesh(int meshType) {
     vertexBuffer = NULL;
     useVertexColors = false;
     indexedMesh = false;
-    useFaceNormals = false;
 }
 
 Mesh *Mesh::MeshFromFileName(String& fileName) {
@@ -75,7 +73,6 @@ void Mesh::clearMesh() {
     }
     vertices.clear();
     indices.clear();
-    faceNormals.clear();
     
     if(vertexBuffer)
         delete vertexBuffer;
@@ -89,7 +86,6 @@ void Mesh::clearMesh() {
         }
     }
 
-    useFaceNormals = false;
     meshHasVertexBuffer = false;
 }
 
@@ -97,15 +93,6 @@ VertexBuffer *Mesh::getVertexBuffer() {
     return vertexBuffer;
 }
 
-void Mesh::setUseFaceNormals(bool val) {
-    useFaceNormals = val;
-    arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
-}
-
-bool Mesh::getUseFaceNormals() {
-    return useFaceNormals;
-}
-
 
 void Mesh::setVertexBuffer(VertexBuffer *buffer) {    
     if(vertexBuffer) {
@@ -401,7 +388,6 @@ void Mesh::createCircle(Number w, Number h, unsigned int numSegments) {
 Mesh *Mesh::Copy() const {
     Mesh *newMesh = new Mesh(meshType);
     newMesh->indexedMesh = indexedMesh;
-    newMesh->setUseFaceNormals(useFaceNormals);
     
     for(int i=0; i < vertices.size(); i++) {
         Vertex *v = new Vertex();
@@ -413,18 +399,10 @@ Mesh *Mesh::Copy() const {
         newMesh->addIndex(indices[i]);
     }
 
-    for(int i=0; i < faceNormals.size(); i++) {
-        newMesh->addFaceNormal(faceNormals[i]);
-    }
-    
     newMesh->dirtyArrays();
     return newMesh;
 }
 
-void Mesh::addFaceNormal(Vector3 faceNormal) {
-    faceNormals.push_back(faceNormal);
-}
-
 void Mesh::createLineCircle(Number w, Number h, unsigned int numSegments) {
     setMeshType(Mesh::TRIFAN_MESH);
  
@@ -779,16 +757,8 @@ void Mesh::createIcosphere(Number radius, int subdivisions) {
 	arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
 }
 
-unsigned int Mesh::getActualVertexCount() const {
-    return vertices.size();    
-}
-
 unsigned int Mesh::getVertexCount() {
-    if(indexedMesh) {
-        return indices.size();
-    } else {
-        return vertices.size();
-    }
+    return vertices.size();
 }
 
 unsigned int Mesh::getIndexCount() {
@@ -978,14 +948,6 @@ void Mesh::addIndex(unsigned int index) {
     indices.push_back(index % vertices.size());
 }
 
-Vertex *Mesh::getActualVertex(unsigned int index) const {
-    if(index < vertices.size()) {
-        return vertices[index];
-    } else {
-        return NULL;
-    }
-}
-
 void Mesh::addIndexedFace(unsigned int i1, unsigned int i2, unsigned int i3) {
     if(!vertices.size()) {
         return;
@@ -1039,9 +1001,6 @@ void Mesh::removeVertexRange(unsigned int beginRemoveVertex, int vertexRemovalCo
 				unsigned int faceIndex = i/groupSize;
 				i = faceIndex * groupSize;
 				indices.erase(indices.begin() + i, indices.begin() + i + groupSize);
-				if (useFaceNormals) {
-					faceNormals.erase(faceNormals.begin() + i);
-				}
 			}
 			else {
 				if (faceVertexIndex > beginRemoveVertex) {
@@ -1159,12 +1118,12 @@ void Mesh::dirtyArrays() {
     }
 }
 
+Vertex *Mesh::getIndexedVertex(unsigned int index) const {
+    return vertices[indices[index]];
+}
+
 Vertex *Mesh::getVertex(unsigned int index) const {
-    if(indexedMesh) {
-        return vertices[indices[index]];
-    } else {
-        return vertices[index];
-    }
+    return vertices[index];
 }
 
 Vector3 Mesh::calculateFaceTangent(Vertex *v1, Vertex *v2, Vertex *v3) {
@@ -1197,7 +1156,6 @@ void Mesh::calculateTangents() {
         polySize = 4;
     }
     
-    faceNormals.clear();
     for(int i=0; i < vertices.size(); i++) {
         vertices[i]->tangent = Vector3();
     }
@@ -1227,29 +1185,13 @@ void Mesh::calculateTangents() {
     arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;		
 }
 
-Vector3 Mesh::getFaceNormalForVertex(unsigned int index) {
-    unsigned int faceNormalIndex;
-    if(meshType == Mesh::QUAD_MESH) {
-        faceNormalIndex = floor(((Number)index)/4.0);
-    } else {
-        faceNormalIndex = floor(((Number)index)/3.0);
-    }
-    
-    if(faceNormalIndex < faceNormals.size()) {
-        return faceNormals[faceNormalIndex];
-    } else {
-        return Vector3();
-    }
-}
-
-void Mesh::calculateNormals(bool generateFaceNormals) {
+void Mesh::calculateNormals() {
     
     int polySize = 3;
     if(meshType == Mesh::QUAD_MESH) {
         polySize = 4;
     }
     
-    faceNormals.clear();
     for(int i=0; i < vertices.size(); i++) {
         vertices[i]->normal = Vector3();
     }
@@ -1263,10 +1205,6 @@ void Mesh::calculateNormals(bool generateFaceNormals) {
             for(int j=0; j < polySize; j++) {
                 vertices[indices[i+j]]->normal -= no;
             }
-            
-            if(generateFaceNormals) {
-                faceNormals.push_back(no * -1.0);
-            }
         }
     } else {
         for(int i=0; i+polySize-1 < vertices.size(); i += polySize) {
@@ -1277,19 +1215,12 @@ void Mesh::calculateNormals(bool generateFaceNormals) {
             for(int j=0; j < polySize; j++) {
                 vertices[i+j]->normal = no * -1.0;
             }
-            
-            if(generateFaceNormals) {
-                faceNormals.push_back(no * -1.0);
-            }
         }
     }
     
     for(int i=0; i < vertices.size(); i++) {
         vertices[i]->normal.Normalize();
     }
-    for(int i=0; i < faceNormals.size(); i++) {
-        faceNormals[i].Normalize();
-    }
     
     arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;		
 }

+ 3 - 3
Core/Contents/Source/PolyParticleEmitter.cpp

@@ -243,10 +243,10 @@ void SceneParticleEmitter::rebuildParticles() {
                     int meshIndex = particles[i].varianceIndex;
                     if(meshIndex < sourceMeshes.size()) {
                         
-                        indexOffset = mesh->getActualVertexCount();
+                        indexOffset = mesh->getVertexCount();
                         
-                        for(int v=0; v <  sourceMeshes[meshIndex]->getActualVertexCount(); v++) {
-                            Vertex *sv = sourceMeshes[meshIndex]->getActualVertex(v);
+                        for(int v=0; v <  sourceMeshes[meshIndex]->getVertexCount(); v++) {
+                            Vertex *sv = sourceMeshes[meshIndex]->getVertex(v);
                             Vector3 vpos = Vector3(sv->x, sv->y, sv->z) * finalParticleSize;
                             vpos = q.applyTo(vpos);
                             

+ 2 - 2
Core/Contents/Source/PolySceneMesh.cpp

@@ -258,8 +258,8 @@ void SceneMesh::renderMeshLocally() {
 	Renderer *renderer = CoreServices::getInstance()->getRenderer();
 	
 	if(skeleton) {	
-		for(int i=0; i < mesh->getActualVertexCount(); i++) {
-            Vertex *vert = mesh->getActualVertex(i);
+		for(int i=0; i < mesh->getVertexCount(); i++) {
+            Vertex *vert = mesh->getVertex(i);
             Vector3 norm;
             
             Vector3 tPos;

+ 4 - 3
Core/Contents/Source/PolySceneSprite.cpp

@@ -412,15 +412,16 @@ void SpriteState::rebuildStateMeshes() {
         
         
         for(int j=0; j < 4; j++) {
-            Number val = fabs(frameMesh->getActualVertex(j)->x);
+            Vertex *vertex = frameMesh->getVertex(j);
+            Number val = fabs(vertex->x);
             if(val > largestFrameBoundingBox.x) {
                 largestFrameBoundingBox.x = val;
             }
-            val = fabs(frameMesh->getActualVertex(j)->y);
+            val = fabs(vertex->y);
             if(val > largestFrameBoundingBox.y) {
                 largestFrameBoundingBox.y = val;
             }
-            val = fabs(frameMesh->getActualVertex(j)->z);
+            val = fabs(vertex->z);
             if(val > largestFrameBoundingBox.z) {
                 largestFrameBoundingBox.z = val;
             }

+ 4 - 0
Core/Contents/Source/PolySkeleton.cpp

@@ -135,6 +135,10 @@ void Skeleton::Update() {
         bones[i]->rebuildTransformMatrix();
         bones[i]->setBoneMatrix(bones[i]->getTransformMatrix());
     }
+    
+    for(int i=0; i < bones.size(); i++) {
+        bones[i]->rebuildFinalMatrix();
+    }
 }
 
 void Skeleton::loadSkeleton(const String& fileName) {

+ 12 - 12
IDE/Contents/Source/PolycodeEntityEditor.cpp

@@ -328,10 +328,10 @@ void LightDisplay::Update() {
        	spotSpot->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
         
         spotLightSize *= 0.5;
-        fovMesh->getActualVertex(1)->set(sin(PI/2.0)*spotLightSize, cos(PI/2.0)*spotLightSize, -distance);
-        fovMesh->getActualVertex(2)->set(sin(PI)*spotLightSize, cos(PI)*spotLightSize, -distance);
-        fovMesh->getActualVertex(3)->set(sin(PI + (PI/2.0))*spotLightSize, cos(PI + (PI/2.0))*spotLightSize, -distance);
-        fovMesh->getActualVertex(4)->set(sin(PI*2.0)*spotLightSize, cos(PI*2.0)*spotLightSize, -distance);
+        fovMesh->getVertex(1)->set(sin(PI/2.0)*spotLightSize, cos(PI/2.0)*spotLightSize, -distance);
+        fovMesh->getVertex(2)->set(sin(PI)*spotLightSize, cos(PI)*spotLightSize, -distance);
+        fovMesh->getVertex(3)->set(sin(PI + (PI/2.0))*spotLightSize, cos(PI + (PI/2.0))*spotLightSize, -distance);
+        fovMesh->getVertex(4)->set(sin(PI*2.0)*spotLightSize, cos(PI*2.0)*spotLightSize, -distance);
          fovMesh->dirtyArray(RenderDataArray::VERTEX_DATA_ARRAY);
         fovSceneMesh->setLocalBoundingBox(fovMesh->calculateBBox());
     } else {
@@ -401,10 +401,10 @@ void CameraDisplay::Update() {
             break;
         }
         
-        fovMesh->getActualVertex(1)->set(-xPos, yPos, zPos);
-        fovMesh->getActualVertex(2)->set(xPos, yPos, zPos);
-        fovMesh->getActualVertex(3)->set(xPos, -yPos, zPos);
-        fovMesh->getActualVertex(4)->set(-xPos, -yPos, zPos);
+        fovMesh->getVertex(1)->set(-xPos, yPos, zPos);
+        fovMesh->getVertex(2)->set(xPos, yPos, zPos);
+        fovMesh->getVertex(3)->set(xPos, -yPos, zPos);
+        fovMesh->getVertex(4)->set(-xPos, -yPos, zPos);
         fovMesh->dirtyArray(RenderDataArray::VERTEX_DATA_ARRAY);
     } else {
         Number fovRad = (90+camera->getFOV()/2.0) * TORADIANS;
@@ -413,10 +413,10 @@ void CameraDisplay::Update() {
         Number yPos = xPos * 0.5625;
         Number zPos = -sin(fovRad) * displayScale * 0.5;
         
-        fovMesh->getActualVertex(1)->set(-xPos, yPos, zPos);
-        fovMesh->getActualVertex(2)->set(xPos, yPos, zPos);
-        fovMesh->getActualVertex(3)->set(xPos, -yPos, zPos);
-        fovMesh->getActualVertex(4)->set(-xPos, -yPos, zPos);
+        fovMesh->getVertex(1)->set(-xPos, yPos, zPos);
+        fovMesh->getVertex(2)->set(xPos, yPos, zPos);
+        fovMesh->getVertex(3)->set(xPos, -yPos, zPos);
+        fovMesh->getVertex(4)->set(-xPos, -yPos, zPos);
         fovMesh->dirtyArray(RenderDataArray::VERTEX_DATA_ARRAY);
     }
 }

+ 2 - 2
IDE/Contents/Source/PolycodeMaterialEditor.cpp

@@ -591,7 +591,7 @@ PostPreviewBox::PostPreviewBox() : UIElement() {
 	previewPrimitive->setPosition(-0.8, 1.0, 0.8);
 
 	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 2,  2, 2);
-	previewPrimitive->getMesh()->calculateNormals(false);	
+	previewPrimitive->getMesh()->calculateNormals();	
 	previewScene->addChild(previewPrimitive);
 	previewPrimitive->setMaterialByName("DefaultHDR");
 	previewPrimitive->setColorInt(0, 0, 255, 255);
@@ -733,7 +733,7 @@ MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
 
 	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 4.0, 4.0, 4.0);
 	previewPrimitive->Yaw(45.0);
-	previewPrimitive->getMesh()->calculateNormals(false);
+	previewPrimitive->getMesh()->calculateNormals();
 	previewPrimitive->getMesh()->calculateTangents();
 	previewScene->addChild(previewPrimitive);
 	shapePrimitives.push_back(previewPrimitive);