| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884 |
- /*
- Copyright (C) 2011 by Ivan Safrin
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
- #include "PolyMesh.h"
- #include "PolyLogger.h"
- #include "OSBasics.h"
- using std::min;
- using std::max;
- using std::vector;
- using namespace Polycode;
- Mesh::Mesh(const String& fileName) {
-
- for(int i=0; i < 16; i++) {
- arrayDirtyMap[i] = false;
- renderDataArrays[i] = NULL;
- }
- indexedMesh = false;
- meshType = TRI_MESH;
- meshHasVertexBuffer = false;
- loadMesh(fileName);
- vertexBuffer = NULL;
- useVertexColors = false;
- useFaceNormals = false;
- }
- Mesh::Mesh(int meshType) {
- for(int i=0; i < 16; i++) {
- arrayDirtyMap[i] = false;
- renderDataArrays[i] = NULL;
- }
- this->meshType = meshType;
- meshHasVertexBuffer = false;
- vertexBuffer = NULL;
- useVertexColors = false;
- indexedMesh = false;
- useFaceNormals = false;
- }
- Mesh *Mesh::MeshFromFileName(String& fileName) {
- return new Mesh(fileName);
- }
- Mesh::~Mesh() {
- clearMesh();
- }
- void Mesh::clearMesh() {
- for(int i=0; i < vertices.size(); i++) {
- delete vertices[i];
- }
- vertices.clear();
- if(vertexBuffer)
- delete vertexBuffer;
- vertexBuffer = NULL;
-
- for(int i=0; i < 16; i++) {
- if(renderDataArrays[i]) {
- free(renderDataArrays[i]->arrayPtr);
- delete renderDataArrays[i];
- renderDataArrays[i] = NULL;
- }
- }
- indexedMesh = false;
- useFaceNormals = false;
- meshHasVertexBuffer = false;
- }
- 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) {
- vertexBuffer = buffer;
- meshHasVertexBuffer = true;
- }
- Number Mesh::getRadius() {
- Number hRad = 0;
- Number len;
- for(int i=0; i < vertices.size(); i++) {
- len = vertices[i]->length();
- if(len > hRad) {
- hRad = len;
- }
- }
- return hRad;
- }
- void Mesh::saveToFile(OSFILE *outFile, bool writeNormals, bool writeTangents, bool writeColors, bool writeBoneWeights, bool writeUVs, bool writeSecondaryUVs) {
-
- unsigned char meshFlags = 0;
-
- if(indexedMesh) {
- meshFlags |= 1 << 0;
- }
- if(writeNormals) {
- meshFlags |= 1 << 1;
- }
- if(writeTangents) {
- meshFlags |= 1 << 2;
- }
- if(writeColors) {
- meshFlags |= 1 << 3;
- }
- if(writeUVs) {
- meshFlags |= 1 << 4;
- }
- if(writeSecondaryUVs) {
- meshFlags |= 1 << 5;
- }
- if(writeBoneWeights) {
- meshFlags |= 1 << 6;
- }
-
- OSBasics::write(&meshFlags, sizeof(unsigned char), 1, outFile);
-
- unsigned int numVertices = vertices.size();
- OSBasics::write(&meshType, sizeof(unsigned int), 1, outFile);
- OSBasics::write(&numVertices, sizeof(unsigned int), 1, outFile);
- Vector3_struct pos;
- Vector3_struct nor;
- Vector3_struct tan;
- Vector4_struct col;
- Vector2_struct tex;
- Vector2_struct tex2;
-
- for(int i=0; i < vertices.size(); i++) {
- pos.x = vertices[i]->x;
- pos.y = vertices[i]->y;
- pos.z = vertices[i]->z;
- nor.x = vertices[i]->normal.x;
- nor.y = vertices[i]->normal.y;
- nor.z = vertices[i]->normal.z;
- tan.x = vertices[i]->tangent.x;
- tan.y = vertices[i]->tangent.y;
- tan.z = vertices[i]->tangent.z;
- col.x = vertices[i]->vertexColor.r;
- col.y = vertices[i]->vertexColor.g;
- col.z = vertices[i]->vertexColor.b;
- col.w = vertices[i]->vertexColor.a;
-
- tex.x = vertices[i]->getTexCoord().x;
- tex.y = vertices[i]->getTexCoord().y;
- tex2.x = vertices[i]->getSecondaryTexCoord().x;
- tex2.y = vertices[i]->getSecondaryTexCoord().y;
- OSBasics::write(&pos, sizeof(Vector3_struct), 1, outFile);
-
- if(writeNormals) {
- OSBasics::write(&nor, sizeof(Vector3_struct), 1, outFile);
- }
- if(writeTangents) {
- OSBasics::write(&tan, sizeof(Vector3_struct), 1, outFile);
- }
- if(writeColors) {
- OSBasics::write(&col, sizeof(Vector4_struct), 1, outFile);
- }
- if(writeUVs) {
- OSBasics::write(&tex, sizeof(Vector2_struct), 1, outFile);
- }
- if(writeSecondaryUVs) {
- OSBasics::write(&tex2, sizeof(Vector2_struct), 1, outFile);
- }
-
- if(writeBoneWeights) {
- unsigned int numBoneWeights = vertices[i]->getNumBoneAssignments();
- OSBasics::write(&numBoneWeights, sizeof(unsigned int), 1, outFile);
- for(int b=0; b < numBoneWeights; b++) {
- BoneAssignment *a = vertices[i]->getBoneAssignment(b);
- unsigned int boneID = a->boneID;
- float weight = a->weight;
- OSBasics::write(&boneID, sizeof(unsigned int), 1, outFile);
- OSBasics::write(&weight, sizeof(float), 1, outFile);
- }
- }
- }
-
- if(indexedMesh) {
- unsigned int numIndices = indices.size();
- OSBasics::write(&numIndices, sizeof(unsigned int), 1, outFile);
- for(int i=0; i < numIndices; i++) {
- OSBasics::write(&indices[i], sizeof(unsigned int), 1, outFile);
- }
- }
- }
- void Mesh::loadFromFile(OSFILE *inFile) {
-
- unsigned char meshFlags;
- OSBasics::read(&meshFlags, sizeof(unsigned char), 1, inFile);
-
- indexedMesh = meshFlags & (1 << 0);
- bool hasNormals = meshFlags & (1 << 1);
- bool hasTangents = meshFlags & (1 << 2);
- bool hasColors = meshFlags & (1 << 3);
- bool hasUV = meshFlags & (1 << 4);
- bool hasSecondaryUVs = meshFlags & (1 << 5);
- bool hasBoneWeights = meshFlags & (1 << 6);
-
- unsigned int meshType;
- OSBasics::read(&meshType, sizeof(unsigned int), 1, inFile);
- setMeshType(meshType);
-
- unsigned int numVertices;
- OSBasics::read(&numVertices, sizeof(unsigned int), 1, inFile);
-
- Vector3_struct pos;
- Vector3_struct nor;
- Vector3_struct tan;
- Vector4_struct col;
- Vector2_struct tex;
-
- for(int i=0; i < numVertices; i++) {
- OSBasics::read(&pos, sizeof(Vector3_struct), 1, inFile);
- Vertex *vertex = new Vertex(pos.x, pos.y, pos.z);
-
- if(hasNormals) {
- OSBasics::read(&nor, sizeof(Vector3_struct), 1, inFile);
- vertex->setNormal(nor.x,nor.y, nor.z);
- vertex->restNormal.set(nor.x,nor.y, nor.z);
- }
- if(hasTangents) {
- OSBasics::read(&tan, sizeof(Vector3_struct), 1, inFile);
- vertex->tangent = Vector3(tan.x, tan.y, tan.z);
- }
-
- if(hasColors) {
- OSBasics::read(&col, sizeof(Vector4_struct), 1, inFile);
- vertex->vertexColor.setColor(col.x,col.y, col.z, col.w);
- }
-
- if(hasUV) {
- OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);
- vertex->setTexCoord(tex.x, tex.y);
- }
-
- if(hasSecondaryUVs) {
- OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);
- vertex->setSecondaryTexCoord(tex.x, tex.y);
- }
-
- if(hasBoneWeights) {
- unsigned int numBoneWeights;
- OSBasics::read(&numBoneWeights, sizeof(unsigned int), 1, inFile);
- for(int b=0; b < numBoneWeights; b++) {
- float weight;
- unsigned int boneID;
- OSBasics::read(&boneID, sizeof(unsigned int), 1, inFile);
- OSBasics::read(&weight, sizeof(float), 1, inFile);
- vertex->addBoneAssignment(boneID, weight);
- }
-
- Number totalWeight = 0;
- for(int m=0; m < vertex->getNumBoneAssignments(); m++) {
- BoneAssignment *ba = vertex->getBoneAssignment(m);
- totalWeight += ba->weight;
- }
- for(int m=0; m < vertex->getNumBoneAssignments(); m++) {
- BoneAssignment *ba = vertex->getBoneAssignment(m);
- ba->weight = ba->weight/totalWeight;
- }
- }
- addVertex(vertex);
- }
-
- if(indexedMesh) {
- unsigned int numIndices;
- OSBasics::read(&numIndices, sizeof(unsigned int), 1, inFile);
- indices.clear();
- unsigned int val;
- for(int i=0; i < numIndices; i++) {
- OSBasics::read(&val, sizeof(unsigned int), 1, inFile);
- indices.push_back(val);
- }
- }
- dirtyArrays();
- }
- Vertex *Mesh::addVertex(Number x, Number y, Number z) {
- Vertex *vertex = new Vertex(x,y,z);
- vertices.push_back(vertex);
- return vertex;
- }
- void Mesh::addVertex(Vertex *vertex) {
- vertices.push_back(vertex);
- }
- Vertex *Mesh::addVertex(Number x, Number y, Number z, Number u, Number v) {
- Vertex *vertex = new Vertex(x,y,z,u,v);
- vertices.push_back(vertex);
- return vertex;
- }
- void Mesh::saveToFile(const String& fileName, bool writeNormals, bool writeTangents, bool writeColors, bool writeBoneWeights, bool writeUVs, bool writeSecondaryUVs) {
- OSFILE *outFile = OSBasics::open(fileName, "wb");
- if(!outFile) {
- Logger::log("Error opening mesh file for saving: %s", fileName.c_str());
- }
- saveToFile(outFile, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
- OSBasics::close(outFile);
- }
- void Mesh::loadMesh(const String& fileName) {
- OSFILE *inFile = OSBasics::open(fileName, "rb");
- if(!inFile) {
- Logger::log("Error opening mesh file %s", fileName.c_str());
- }
- loadFromFile(inFile);
- OSBasics::close(inFile);
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::createCircle(Number w, Number h, unsigned int numSegments) {
- setMeshType(Mesh::TRI_MESH);
- Number lastx = 0;
- Number lasty = 0;
- Number lastv = 0;
- for (int i=0 ; i < numSegments+1; i++) {
- Number v = ((Number)i)/((Number)numSegments);
- Number pos = ((PI*2.0)/((Number)numSegments)) * i;
- Number x = sin(pos) * w * 0.5;
- Number y = cos(pos) * h * 0.5;
-
- if(i > 0) {
- addVertex(0,0,0,0.5,0.5)->setNormal(0.0, 0.0, 1.0);
- addVertex(x,y,0, 0.5+(y/h*0.5), 0.5+(x/w*0.5))->setNormal(0.0, 0.0, 1.0);
- addVertex(lastx,lasty,0, 0.5+(lasty/h*0.5), 0.5+(lastx/w*0.5))->setNormal(0.0, 0.0, 1.0);
- }
- lastx = x;
- lastv = v;
- lasty = y;
- }
-
-
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::createLineCircle(Number w, Number h, unsigned int numSegments) {
- setMeshType(Mesh::TRIFAN_MESH);
-
- int step;
- if(numSegments > 0) {
- step = ceil(360/numSegments);
- } else {
- step = 1;
- }
-
-
- addVertex(cosf(0)*(w/2),sinf(0)*(h/2), 0, (cosf(0)*0.5) + 0.5,(sinf(0) * 0.5)+ 0.5);
-
- for (int i=0; i < 361; i+= step) {
- Number degInRad = i*TORADIANS;
- Vertex *v = addVertex(cos(degInRad)*(w/2),sin(degInRad)*(h/2), 0, (cos(degInRad) * 0.5)+ 0.5 , 1.0- ((sin(degInRad) * 0.5)+ 0.5));
- Vector3 normal = *v;
- normal.Normalize();
- v->normal = normal;
- }
-
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
- void Mesh::createVPlane(Number w, Number h) {
- setMeshType(Mesh::TRI_MESH);
-
- addVertex(0,0,0,0,0)->setNormal(0.0, 0.0, 1.0);
- addVertex(w,0,0, 1, 0)->setNormal(0.0, 0.0, 1.0);
- addVertex(w,h,0, 1, 1)->setNormal(0.0, 0.0, 1.0);
-
- addVertex(0,0,0,0,0)->setNormal(0.0, 0.0, 1.0);
- addVertex(w,h,0, 1, 1)->setNormal(0.0, 0.0, 1.0);
- addVertex(0,h,0,0,1)->setNormal(0.0, 0.0, 1.0);
-
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->x = vertices[i]->x - (w/2.0f);
- vertices[i]->y = vertices[i]->y - (h/2.0f);
- }
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::createPlane(Number w, Number h) {
- setMeshType(Mesh::TRI_MESH);
-
- addVertex(0,0,h,0,0);
- addVertex(w,0,h, 1, 0);
- addVertex(w,0,0, 1, 1);
-
- addVertex(0,0,h,0,0);
- addVertex(w,0,0, 1, 1);
- addVertex(0,0,0,0,1);
-
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->x = vertices[i]->x - (w/2.0f);
- vertices[i]->z = vertices[i]->z - (h/2.0f);
- }
- calculateNormals();
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- Vector3 Mesh::recenterMesh() {
- Vector3 positiveOffset;
- Vector3 negativeOffset;
-
- for(int i=0; i < vertices.size(); i++) {
- positiveOffset.x = max(positiveOffset.x, vertices[i]->x);
- positiveOffset.y = max(positiveOffset.y, vertices[i]->y);
- positiveOffset.z = max(positiveOffset.z, vertices[i]->z);
- negativeOffset.x = min(negativeOffset.x, vertices[i]->x);
- negativeOffset.y = min(negativeOffset.y, vertices[i]->y);
- negativeOffset.z = min(negativeOffset.z, vertices[i]->z);
- }
-
- Vector3 finalOffset;
-
- finalOffset.x = (positiveOffset.x + negativeOffset.x)/2.0f;
- finalOffset.y = (positiveOffset.y + negativeOffset.y)/2.0f;
- finalOffset.z = (positiveOffset.z + negativeOffset.z)/2.0f;
-
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->x = vertices[i]->x - finalOffset.x;
- vertices[i]->y = vertices[i]->y - finalOffset.y;
- vertices[i]->z = vertices[i]->z - finalOffset.z;
- }
-
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
-
- return finalOffset;
- }
- Vector3 Mesh::calculateBBox() {
- Vector3 retVec;
-
- for(int i=0; i < vertices.size(); i++) {
- retVec.x = max(retVec.x,fabs(vertices[i]->x));
- retVec.y = max(retVec.y,fabs(vertices[i]->y));
- retVec.z = max(retVec.z,fabs(vertices[i]->z));
- }
-
- return retVec*2;
- }
- void Mesh::createSphere(Number _radius, int _segmentsH, int _segmentsW) {
- setMeshType(Mesh::TRI_MESH);
- Vector3 **grid = (Vector3 **) malloc(sizeof(Vector3*) * (_segmentsH+1));
- for (int i=0 ; i < _segmentsH+1; i++) {
- grid[i] = (Vector3*) malloc(sizeof(Vector3) * _segmentsW+1);
- }
-
- for (int i = 0; i < _segmentsW; i++) {
- grid[0][i] = Vector3(0,-_radius,0);
- }
-
- for (int j = 1; j < _segmentsH; j++) {
- Number horangle = ((float)j) / ((float)_segmentsH) * PI;
- Number z = -_radius * cos(horangle);
- Number ringradius = _radius * sin(horangle);
- for (int i = 0; i < _segmentsW; i++) {
- Number verangle = 2.0 * ((float)i) / ((float)_segmentsW) * PI;
- Number x = ringradius * sin(verangle);
- Number y = ringradius * cos(verangle);
- grid[j][i] = Vector3(y, z, x);
- }
- }
- for (int i = 0; i < _segmentsW; i++) {
- grid[_segmentsH][i] = Vector3(0,_radius, 0);
- }
- for (int j = 1; j <= _segmentsH; j++) {
- for (int i = 0; i < _segmentsW; i++) {
- Vector3 a = grid[j][i];
- Vector3 b = grid[j][(i-1+_segmentsW) % _segmentsW];
- Vector3 c = grid[j-1][(i-1+_segmentsW) % _segmentsW];
- Vector3 d = grid[j-1][i];
- int i2 = i;
- if (i == 0) i2 = _segmentsW;
- Number vab = ((float)j) / ((float)_segmentsH);
- Number vcd = (((float)j)-1.0) / ((float)_segmentsH);
- Number uad = ((float)i2) / ((float)_segmentsW);
- Number ubc = (((float)i2)-1.0) / ((float)_segmentsW);
- Vector2 uva = Vector2(uad,vab);
- Vector2 uvb = Vector2(ubc,vab);
- Vector2 uvc = Vector2(ubc,vcd);
- Vector2 uvd = Vector2(uad,vcd);
- if (j < _segmentsH) {
- addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
- addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);
- addVertex(a.x, a.y, a.z, uva.x ,uva.y);
- }
- if (j > 1) {
- addVertex(d.x, d.y, d.z, uvd.x ,uvd.y);
- addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
- addVertex(a.x, a.y, a.z, uva.x ,uva.y);
- }
- }
- }
-
- for (int i=0 ; i < _segmentsH+1; i++) {
- free(grid[i]);
- }
- free(grid);
- calculateNormals();
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- unsigned int Mesh::getVertexCount() {
- if(indexedMesh) {
- return indices.size();
- } else {
- return vertices.size();
- }
- }
- void Mesh::createTorus(Number radius, Number tubeRadius, int rSegments, int tSegments) {
- setMeshType(Mesh::TRI_MESH);
-
- Vector3 **grid = (Vector3 **) malloc(sizeof(Vector3*) * rSegments);
- for (int i=0 ; i < rSegments; i++) {
- grid[i] = (Vector3*) malloc(sizeof(Vector3) * tSegments);
- }
-
- for (int i=0 ; i < rSegments; i++) {
- for (int j = 0; j < tSegments; ++j) {
- Number u = ((Number)i) / rSegments * 2.0 * PI;
- Number v = ((Number)j) / tSegments * 2.0 * PI;
- grid[i][j] = Vector3((radius + tubeRadius*cos(v))*cos(u), tubeRadius*sin(v), (radius + tubeRadius*cos(v))*sin(u));
-
- }
- }
-
- for (int i=0 ; i < rSegments; i++) {
- for (int j = 0; j < tSegments; ++j) {
- int ip = (i+1) % rSegments;
- int jp = (j+1) % tSegments;
-
- Vector3 a = grid[i ][j];
- Vector3 b = grid[ip][j];
- Vector3 c = grid[i ][jp];
- Vector3 d = grid[ip][jp];
- Vector2 uva = Vector2(((Number)i) / ((Number)rSegments), ((Number)j) / ((Number)tSegments));
- Vector2 uvb = Vector2((((Number)i)+1.0) / ((Number)rSegments), ((Number)j) / ((Number)tSegments));
- Vector2 uvc = Vector2(((Number)i) / ((Number)rSegments), (((Number)j)+1.0) / ((Number)tSegments));
- Vector2 uvd = Vector2((((Number)i)+1.0) / ((Number)rSegments), (((Number)j)+1.0) / ((Number)tSegments));
- addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
- addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);
- addVertex(a.x, a.y, a.z, uva.x ,uva.y);
- addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);
- addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
- addVertex(d.x, d.y, d.z, uvd.x ,uvd.y);
- }
- }
-
- for (int i=0 ; i < rSegments; i++) {
- free(grid[i]);
- }
- free(grid);
-
- calculateNormals();
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::createCylinder(Number height, Number radius, int numSegments, bool capped) {
- setMeshType(Mesh::TRI_MESH);
- Number lastx = 0;
- Number lastz = 0;
- Number lastv = 0;
- for (int i=0 ; i < numSegments+1; i++) {
- Number v = ((Number)i)/((Number)numSegments);
- Number pos = ((PI*2.0)/((Number)numSegments)) * i;
- Number x = sin(pos) * radius;
- Number z = cos(pos) * radius;
-
- if(i > 0) {
- addVertex(lastx,0,lastz,lastv,0);
- addVertex(x,0,z, v, 0);
- addVertex(x,height,z, v, 1);
- addVertex(x,height,z, v, 1);
- addVertex(lastx,height,lastz, lastv, 1);
- addVertex(lastx,0,lastz,lastv,0);
-
- if(capped) {
- addVertex(lastx,height,lastz, 0.5+(lastz/radius*0.5), 0.5+(lastx/radius*0.5));
- addVertex(x,height,z, 0.5+(z/radius*0.5), 0.5+(x/radius*0.5));
- addVertex(0,height,0,0.5,0.5);
- addVertex(lastx,0,lastz, 0.5+(lastz/radius*0.5), 0.5+(lastx/radius*0.5));
- addVertex(0,0,0,0.5,0.5);
- addVertex(x,0,z, 0.5+(z/radius*0.5), 0.5+(x/radius*0.5));
- }
-
- }
- lastx = x;
- lastz = z;
- lastv = v;
- }
-
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->y = vertices[i]->y - (height/2.0f);
- }
-
-
- calculateNormals();
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::createCone(Number height, Number radius, int numSegments) {
- setMeshType(Mesh::TRI_MESH);
-
- Number lastx = 0;
- Number lasty = 0;
- Number lastv = 0;
-
- for (int i=0 ; i < numSegments+1; i++) {
- Number v = ((Number)i)/((Number)numSegments);
- Number pos = ((PI*2.0)/((Number)numSegments)) * i;
- Number x = sin(pos) * radius * 0.5;
- Number y = cos(pos) * radius * 0.5;
-
- if(i > 0) {
-
- addVertex(lastx,0, lasty, 0.5+(lasty/radius*0.5), 0.5+(lastx/radius*0.5))->setNormal(0.0, -1.0, 0.0);
- addVertex(x,0,y, 0.5+(y/radius*0.5), 0.5+(x/radius*0.5))->setNormal(0.0, -1.0, 0.0);
- addVertex(0,height,0,0.5,0.5)->setNormal(0.0, -1.0, 0.0);
-
- addVertex(0,0,0,0.5,0.5)->setNormal(0.0, -1.0, 0.0);
- addVertex(x,0,y, 0.5+(y/radius*0.5), 0.5+(x/radius*0.5))->setNormal(0.0, -1.0, 0.0);
- addVertex(lastx,0, lasty, 0.5+(lasty/radius*0.5), 0.5+(lastx/radius*0.5))->setNormal(0.0, -1.0, 0.0);
- }
- lastx = x;
- lastv = v;
- lasty = y;
- }
-
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->y = vertices[i]->y - (height/2.0f);
- }
-
- calculateNormals();
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::addIndex(unsigned int index) {
- indices.push_back(index);
- }
- void Mesh::addIndexedFace(unsigned int i1, unsigned int i2, unsigned int i3) {
- indices.push_back(i1);
- indices.push_back(i2);
- indices.push_back(i3);
- }
- void Mesh::addIndexedFace(unsigned int i1, unsigned int i2, unsigned int i3, unsigned int i4) {
- indices.push_back(i1);
- indices.push_back(i2);
- indices.push_back(i3);
- indices.push_back(i4);
- }
- void Mesh::createBox(Number w, Number d, Number h) {
- setMeshType(Mesh::TRI_MESH);
- indexedMesh = true;
-
- addVertex(w,0,h, 1, 1);
- addVertex(0,0,h, 1, 0);
- addVertex(0,0,0,0,0);
- addVertex(w,0,0,0,1);
- addVertex(w,d,h, 1, 1);
- addVertex(0,d,h, 1, 0);
- addVertex(0,d,0,0,0);
- addVertex(w,d,0,0,1);
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->x = vertices[i]->x - (w/2.0f);
- vertices[i]->y = vertices[i]->y - (d/2.0f);
- vertices[i]->z = vertices[i]->z - (h/2.0f);
- }
-
- addIndexedFace(0, 1, 2);
- addIndexedFace(0, 2, 3);
- addIndexedFace(4, 7, 6);
- addIndexedFace(4, 6, 5);
- addIndexedFace(6, 7, 3);
- addIndexedFace(6, 3, 2);
- addIndexedFace(1, 0, 4);
- addIndexedFace(1, 4, 5);
- addIndexedFace(1, 5, 6);
- addIndexedFace(1, 6, 2);
- addIndexedFace(0, 3, 7);
- addIndexedFace(0, 7, 4);
- calculateNormals(true);
- setUseFaceNormals(true);
-
- calculateTangents();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;
- }
- void Mesh::dirtyArray(unsigned int arrayIndex) {
- if(arrayIndex < 16)
- arrayDirtyMap[arrayIndex] = true;
- }
- void Mesh::dirtyArrays() {
- for(int i=0; i < 16; i++) {
- arrayDirtyMap[i] = true;
- }
- }
- Vertex *Mesh::getVertex(unsigned int index) const {
- if(indexedMesh) {
- return vertices[indices[index]];
- } else {
- return vertices[index];
- }
- }
- 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(index/4);
- } else {
- faceNormalIndex = floor(index/3);
- }
-
- if(faceNormalIndex < faceNormals.size()) {
- return faceNormals[faceNormalIndex];
- } else {
- return Vector3();
- }
- }
- void Mesh::calculateNormals(bool generateFaceNormals) {
-
- int polySize = 3;
- if(meshType == Mesh::QUAD_MESH) {
- polySize = 4;
- }
-
- faceNormals.clear();
- for(int i=0; i < vertices.size(); i++) {
- vertices[i]->normal = Vector3();
- }
- if(indexedMesh) {
- for(int i=0; i+polySize-1 < indices.size(); i += polySize) {
- const Vector3 e1 = *(vertices[indices[i]]) - *(vertices[indices[i+1]]);
- const Vector3 e2 = *(vertices[indices[i+2]]) - *(vertices[indices[i+1]]);
- const Vector3 no = e1.crossProduct(e2);
-
- vertices[indices[i]]->normal -= no;
- vertices[indices[i+1]]->normal -= no;
- vertices[indices[i+2]]->normal -= no;
-
- if(generateFaceNormals) {
- faceNormals.push_back(no * -1.0);
- }
- }
- }
-
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
- int Mesh::getMeshType() {
- return meshType;
- }
- void Mesh::setMeshType(int newType) {
- meshType = newType;
- }
|