int R3Mesh:: ReadImage(const char *filename) { // Create a mesh by reading an image file, // constructing vertices at (x,y,luminance), // and connecting adjacent pixels into faces. // That is, the image is interpretted as a height field, // where the luminance of each pixel provides its z-coordinate. // Read image R2Image *image = new R2Image(); if (!image->Read(filename)) return 0; // Create vertices and store in arrays R3MeshVertex ***vertices = new R3MeshVertex **[image->Width() ]; for (int i = 0; i < image->Width(); i++) { vertices[i] = new R3MeshVertex *[image->Height() ]; for (int j = 0; j < image->Height(); j++) { double luminance = image->Pixel(i, j).Luminance(); double z = luminance * image->Width(); R3Point position((double) i, (double) j, z); R2Point texcoords((double) i, (double) j); vertices[i][j] = CreateVertex(position, R3zero_vector, texcoords); } } // Create faces vector<R3MeshVertex *> face_vertices; for (int i = 1; i < image->Width(); i++) { for (int j = 1; j < image->Height(); j++) { face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j-1]); face_vertices.push_back(vertices[i][j]); CreateFace(face_vertices); face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j]); face_vertices.push_back(vertices[i-1][j]); CreateFace(face_vertices); } } // Delete vertex arrays for (int i = 0; i < image->Width(); i++) delete [] vertices[i]; delete [] vertices; // Delete image delete image; // Return success return 1; }
EpaFace* EpaPolyhedron::CreateConeFace( EpaVertex* pAppexVertex, EpaHalfEdge* pBaseTwinHalfEdge, std::list< EpaHalfEdge* >& halfEdgesToLink ) { EpaFace* pNewFace = CreateFace(); EpaHalfEdge* pNewHalfEdge0 = CreateHalfEdge(); EpaHalfEdge* pNewHalfEdge1 = CreateHalfEdge(); EpaHalfEdge* pNewHalfEdge2 = CreateHalfEdge(); // Let new face point to one of its new half-edges pNewFace->m_pHalfEdge = pNewHalfEdge0; // Link new half-edges in a loop pNewHalfEdge0->m_pNextCCW = pNewHalfEdge1; pNewHalfEdge1->m_pNextCCW = pNewHalfEdge2; pNewHalfEdge2->m_pNextCCW = pNewHalfEdge0; // Let new half-edges point to new face pNewHalfEdge0->m_pFace = pNewFace; pNewHalfEdge1->m_pFace = pNewFace; pNewHalfEdge2->m_pFace = pNewFace; // Let new half-edge 0 and base twin half-edge point to each other pNewHalfEdge0->m_pTwin = pBaseTwinHalfEdge; pBaseTwinHalfEdge->m_pTwin = pNewHalfEdge0; // Let new half-edges know about their origin vertex pNewHalfEdge0->m_pVertex = pBaseTwinHalfEdge->m_pNextCCW->m_pVertex; pNewHalfEdge1->m_pVertex = pBaseTwinHalfEdge->m_pVertex; pNewHalfEdge2->m_pVertex = pAppexVertex; // Let vertices know about one of their outgoing edges //pNewHalfEdge0->m_pVertex->m_pHalfEdge = pNewHalfEdge0; //pNewHalfEdge1->m_pVertex->m_pHalfEdge = pNewHalfEdge1; //pNewHalfEdge2->m_pVertex->m_pHalfEdge = pNewHalfEdge2; halfEdgesToLink.push_back( pNewHalfEdge1 ); halfEdgesToLink.push_back( pNewHalfEdge2 ); return pNewFace; }
CubeMesh::CubeMesh( ) { // F & B CreateFace( { -0.5, 0.5f, 0.5f }, { 0.5, 0.5f, 0.5f }, { 0.5, -0.5f, 0.5f }, { -0.5, -0.5f, 0.5f }, { 0, 0, 1 } ); CreateFace( { -0.5, -0.5f, -0.5f }, { 0.5, -0.5f, -0.5f }, { 0.5, 0.5f, -0.5f }, { -0.5, 0.5f, -0.5f }, { 0, 0, -1 } ); // Up && Down CreateFace( { -0.5, 0.5f, -0.5f }, { 0.5, 0.5f, -0.5f }, { 0.5, 0.5f, 0.5f }, { -0.5, 0.5f, 0.5f }, { 0, 1, 0 } ); CreateFace( { -0.5, -0.5f, 0.5f }, { 0.5, -0.5f, 0.5f }, { 0.5, -0.5f, -0.5f }, { -0.5, -0.5f, -0.5f }, { 0, -1, 0 } ); // L && R CreateFace( { -0.5, -0.5f, 0.5f }, { -0.5, -0.5f, -0.5f }, { -0.5, 0.5f, -0.5f }, { -0.5, 0.5f, 0.5f }, { -1, 0, 0 } ); CreateFace( { 0.5, -0.5f, -0.5f }, { 0.5, -0.5f, 0.5f }, { 0.5, 0.5f, 0.5f }, { 0.5, 0.5f, -0.5f }, { 1, 0, 0 } ); auto Device = static_cast<DXGraphics*>(LVP::Graphics)->Device; // vertex array descriptor D3D11_BUFFER_DESC vbufferDesc = { 0.0f }; vbufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbufferDesc.CPUAccessFlags = 0; vbufferDesc.Usage = D3D11_USAGE_DEFAULT; vbufferDesc.MiscFlags = 0; vbufferDesc.ByteWidth = vertices.size() * sizeof( vertex_t ); // data resource D3D11_SUBRESOURCE_DATA vdata; vdata.pSysMem = &vertices[0]; // create vertex buffer on device using descriptor & data HRESULT vhr = Device->CreateBuffer( &vbufferDesc, &vdata, &VertexBuffer ); // index array descriptor D3D11_BUFFER_DESC ibufferDesc = { 0.0f }; ibufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; ibufferDesc.CPUAccessFlags = 0; ibufferDesc.Usage = D3D11_USAGE_DEFAULT; ibufferDesc.MiscFlags = 0; ibufferDesc.ByteWidth = indices.size() * sizeof( unsigned ); // data resource D3D11_SUBRESOURCE_DATA idata; idata.pSysMem = &indices[0]; // create index buffer on device using descriptor & data HRESULT ihr = Device->CreateBuffer( &ibufferDesc, &idata, &IndexBuffer ); // local data is now loaded to device so it can be released vertices.clear(); nbr_indices = indices.size(); indices.clear(); }
R3Mesh:: R3Mesh(const R3Mesh& mesh) : bbox(R3null_box) { // Create vertices for (int i = 0; i < mesh.NVertices(); i++) { R3MeshVertex *v = mesh.Vertex(i); CreateVertex(v->position, v->normal, v->texcoords); } // Create faces for (int i = 0; i < mesh.NFaces(); i++) { R3MeshFace *f = mesh.Face(i); vector<R3MeshVertex *> face_vertices; for (unsigned int j = 0; j < f->vertices.size(); j++) { R3MeshVertex *ov = f->vertices[j]; R3MeshVertex *nv = Vertex(ov->id); face_vertices.push_back(nv); } CreateFace(face_vertices); } }
bool EpaPolyhedron::Create( btPoint3* pInitialPoints, btPoint3* pSupportPointsOnA, btPoint3* pSupportPointsOnB, const int nbInitialPoints ) { #ifndef EPA_POLYHEDRON_USE_PLANES EPA_DEBUG_ASSERT( ( nbInitialPoints <= 4 ) ,"nbInitialPoints greater than 4!" ); #endif if ( nbInitialPoints < 4 ) { // Insufficient nb of points return false; } //////////////////////////////////////////////////////////////////////////////// #ifdef EPA_POLYHEDRON_USE_PLANES int nbDiffCoords[ 3 ] = { 0, 0, 0 }; bool* pDiffCoords = new bool[ 3 * nbInitialPoints ]; int i; for (i=0;i<nbInitialPoints*3;i++) { pDiffCoords[i] = false; } //::memset( pDiffCoords, 0, sizeof( bool ) * 3 * nbInitialPoints ); int axis; for ( axis = 0; axis < 3; ++axis ) { for ( int i = 0; i < nbInitialPoints; ++i ) { bool isDifferent = true; for ( int j = 0; j < i; ++j ) { if ( pInitialPoints[ i ][ axis ] == pInitialPoints[ j ][ axis ] ) { isDifferent = false; break; } } if ( isDifferent ) { ++nbDiffCoords[ axis ]; pDiffCoords[ axis * nbInitialPoints + i ] = true; } } if ( nbDiffCoords[ axis ] <= 1 ) { // The input is degenerate return false; } } int finalPointsIndices[ 4 ] = { -1, -1, -1, -1 }; int axisOrderIndices[ 3 ] = { 0, 1, 2 }; for ( i = 0; i < 2/*round( nbAxis / 2 )*/; ++i ) { if ( nbDiffCoords[ i ] > nbDiffCoords[ i + 1 ] ) { int tmp = nbDiffCoords[ i ]; nbDiffCoords[ i ] = nbDiffCoords[ i + 1 ]; nbDiffCoords[ i + 1 ] = tmp; tmp = axisOrderIndices[ i ]; axisOrderIndices[ i ] = axisOrderIndices[ i + 1 ]; axisOrderIndices[ i + 1 ] = tmp; } } int nbSuccessfullAxis = 0; // The axes with less different coordinates choose first int minsIndices[ 3 ] = { -1, -1, -1 }; int maxsIndices[ 3 ] = { -1, -1, -1 }; int finalPointsIndex = 0; for ( axis = 0; ( axis < 3 ) && ( nbSuccessfullAxis < 2 ); ++axis ) { int axisIndex = axisOrderIndices[ axis ]; btScalar axisMin = SIMD_INFINITY; btScalar axisMax = -SIMD_INFINITY; for ( int i = 0; i < 4; ++i ) { // Among the diff coords pick the min and max coords if ( pDiffCoords[ axisIndex * nbInitialPoints + i ] ) { if ( pInitialPoints[ i ][ axisIndex ] < axisMin ) { axisMin = pInitialPoints[ i ][ axisIndex ]; minsIndices[ axisIndex ] = i; } if ( pInitialPoints[ i ][ axisIndex ] > axisMax ) { axisMax = pInitialPoints[ i ][ axisIndex ]; maxsIndices[ axisIndex ] = i; } } } //assert( ( minsIndices[ axisIndex ] != maxsIndices[ axisIndex ] ) && // "min and max have the same index!" ); if ( ( minsIndices[ axisIndex ] != -1 ) && ( maxsIndices[ axisIndex ] != -1 ) && ( minsIndices[ axisIndex ] != maxsIndices[ axisIndex ] ) ) { ++nbSuccessfullAxis; finalPointsIndices[ finalPointsIndex++ ] = minsIndices[ axisIndex ]; finalPointsIndices[ finalPointsIndex++ ] = maxsIndices[ axisIndex ]; // Make the choosen points to be impossible for other axes to choose //assert( ( minsIndices[ axisIndex ] != -1 ) && "Invalid index!" ); //assert( ( maxsIndices[ axisIndex ] != -1 ) && "Invalid index!" ); for ( int i = 0; i < 3; ++i ) { pDiffCoords[ i * nbInitialPoints + minsIndices[ axisIndex ] ] = false; pDiffCoords[ i * nbInitialPoints + maxsIndices[ axisIndex ] ] = false; } } } if ( nbSuccessfullAxis <= 1 ) { // Degenerate input ? EPA_DEBUG_ASSERT( false ,"nbSuccessfullAxis must be greater than 1!" ); return false; } delete[] pDiffCoords; #endif ////////////////////////////////////////////////////////////////////////// #ifdef EPA_POLYHEDRON_USE_PLANES btVector3 v0 = pInitialPoints[ finalPointsIndices[ 1 ] ] - pInitialPoints[ finalPointsIndices[ 0 ] ]; btVector3 v1 = pInitialPoints[ finalPointsIndices[ 2 ] ] - pInitialPoints[ finalPointsIndices[ 0 ] ]; #else btVector3 v0 = pInitialPoints[ 1 ] - pInitialPoints[ 0 ]; btVector3 v1 = pInitialPoints[ 2 ] - pInitialPoints[ 0 ]; #endif btVector3 planeNormal = v1.cross( v0 ); planeNormal.normalize(); #ifdef EPA_POLYHEDRON_USE_PLANES btScalar planeDistance = pInitialPoints[ finalPointsIndices[ 0 ] ].dot( -planeNormal ); #else btScalar planeDistance = pInitialPoints[ 0 ].dot( -planeNormal ); #endif #ifdef EPA_POLYHEDRON_USE_PLANES bool pointOnPlane0 = btEqual( pInitialPoints[ finalPointsIndices[ 0 ] ].dot( planeNormal ) + planeDistance, PLANE_THICKNESS ); if (!pointOnPlane0) { EPA_DEBUG_ASSERT(0,"Point0 should be on plane!"); return false; } bool pointOnPlane1 = btEqual( pInitialPoints[ finalPointsIndices[ 1 ] ].dot( planeNormal ) + planeDistance, PLANE_THICKNESS ); if (!pointOnPlane1) { EPA_DEBUG_ASSERT(0,"Point1 should be on plane!"); return false; } bool pointOnPlane2 = btEqual( pInitialPoints[ finalPointsIndices[ 2 ] ].dot( planeNormal ) + planeDistance, PLANE_THICKNESS ); if (!pointOnPlane2) { EPA_DEBUG_ASSERT(0,"Point2 should be on plane!"); return false; } #endif #ifndef EPA_POLYHEDRON_USE_PLANES { if ( planeDistance > 0 ) { btVector3 tmp = pInitialPoints[ 1 ]; pInitialPoints[ 1 ] = pInitialPoints[ 2 ]; pInitialPoints[ 2 ] = tmp; tmp = pSupportPointsOnA[ 1 ]; pSupportPointsOnA[ 1 ] = pSupportPointsOnA[ 2 ]; pSupportPointsOnA[ 2 ] = tmp; tmp = pSupportPointsOnB[ 1 ]; pSupportPointsOnB[ 1 ] = pSupportPointsOnB[ 2 ]; pSupportPointsOnB[ 2 ] = tmp; } } EpaVertex* pVertexA = CreateVertex( pInitialPoints[ 0 ], pSupportPointsOnA[ 0 ], pSupportPointsOnB[ 0 ] ); EpaVertex* pVertexB = CreateVertex( pInitialPoints[ 1 ], pSupportPointsOnA[ 1 ], pSupportPointsOnB[ 1 ] ); EpaVertex* pVertexC = CreateVertex( pInitialPoints[ 2 ], pSupportPointsOnA[ 2 ], pSupportPointsOnB[ 2 ] ); EpaVertex* pVertexD = CreateVertex( pInitialPoints[ 3 ], pSupportPointsOnA[ 3 ], pSupportPointsOnB[ 3 ] ); #else finalPointsIndices[ 3 ] = -1; btScalar absMaxDist = -SIMD_INFINITY; btScalar maxDist; for ( int pointIndex = 0; pointIndex < nbInitialPoints; ++pointIndex ) { btScalar dist = planeNormal.dot( pInitialPoints[ pointIndex ] ) + planeDistance; btScalar absDist = abs( dist ); if ( ( absDist > absMaxDist ) && !btEqual( dist, PLANE_THICKNESS ) ) { absMaxDist = absDist; maxDist = dist; finalPointsIndices[ 3 ] = pointIndex; } } if ( finalPointsIndices[ 3 ] == -1 ) { Destroy(); return false; } if ( maxDist > PLANE_THICKNESS ) { // Can swap indices only btPoint3 tmp = pInitialPoints[ finalPointsIndices[ 1 ] ]; pInitialPoints[ finalPointsIndices[ 1 ] ] = pInitialPoints[ finalPointsIndices[ 2 ] ]; pInitialPoints[ finalPointsIndices[ 2 ] ] = tmp; tmp = pSupportPointsOnA[ finalPointsIndices[ 1 ] ]; pSupportPointsOnA[ finalPointsIndices[ 1 ] ] = pSupportPointsOnA[ finalPointsIndices[ 2 ] ]; pSupportPointsOnA[ finalPointsIndices[ 2 ] ] = tmp; tmp = pSupportPointsOnB[ finalPointsIndices[ 1 ] ]; pSupportPointsOnB[ finalPointsIndices[ 1 ] ] = pSupportPointsOnB[ finalPointsIndices[ 2 ] ]; pSupportPointsOnB[ finalPointsIndices[ 2 ] ] = tmp; } EpaVertex* pVertexA = CreateVertex( pInitialPoints[ finalPointsIndices[ 0 ] ], pSupportPointsOnA[ finalPointsIndices[ 0 ] ], pSupportPointsOnB[ finalPointsIndices[ 0 ] ] ); EpaVertex* pVertexB = CreateVertex( pInitialPoints[ finalPointsIndices[ 1 ] ], pSupportPointsOnA[ finalPointsIndices[ 1 ] ], pSupportPointsOnB[ finalPointsIndices[ 1 ] ] ); EpaVertex* pVertexC = CreateVertex( pInitialPoints[ finalPointsIndices[ 2 ] ], pSupportPointsOnA[ finalPointsIndices[ 2 ] ], pSupportPointsOnB[ finalPointsIndices[ 2 ] ] ); EpaVertex* pVertexD = CreateVertex( pInitialPoints[ finalPointsIndices[ 3 ] ], pSupportPointsOnA[ finalPointsIndices[ 3 ] ], pSupportPointsOnB[ finalPointsIndices[ 3 ] ] ); #endif EpaFace* pFaceA = CreateFace(); EpaFace* pFaceB = CreateFace(); EpaFace* pFaceC = CreateFace(); EpaFace* pFaceD = CreateFace(); EpaHalfEdge* pFaceAHalfEdges[ 3 ]; EpaHalfEdge* pFaceCHalfEdges[ 3 ]; EpaHalfEdge* pFaceBHalfEdges[ 3 ]; EpaHalfEdge* pFaceDHalfEdges[ 3 ]; pFaceAHalfEdges[ 0 ] = CreateHalfEdge(); pFaceAHalfEdges[ 1 ] = CreateHalfEdge(); pFaceAHalfEdges[ 2 ] = CreateHalfEdge(); pFaceBHalfEdges[ 0 ] = CreateHalfEdge(); pFaceBHalfEdges[ 1 ] = CreateHalfEdge(); pFaceBHalfEdges[ 2 ] = CreateHalfEdge(); pFaceCHalfEdges[ 0 ] = CreateHalfEdge(); pFaceCHalfEdges[ 1 ] = CreateHalfEdge(); pFaceCHalfEdges[ 2 ] = CreateHalfEdge(); pFaceDHalfEdges[ 0 ] = CreateHalfEdge(); pFaceDHalfEdges[ 1 ] = CreateHalfEdge(); pFaceDHalfEdges[ 2 ] = CreateHalfEdge(); pFaceA->m_pHalfEdge = pFaceAHalfEdges[ 0 ]; pFaceB->m_pHalfEdge = pFaceBHalfEdges[ 0 ]; pFaceC->m_pHalfEdge = pFaceCHalfEdges[ 0 ]; pFaceD->m_pHalfEdge = pFaceDHalfEdges[ 0 ]; pFaceAHalfEdges[ 0 ]->m_pNextCCW = pFaceAHalfEdges[ 1 ]; pFaceAHalfEdges[ 1 ]->m_pNextCCW = pFaceAHalfEdges[ 2 ]; pFaceAHalfEdges[ 2 ]->m_pNextCCW = pFaceAHalfEdges[ 0 ]; pFaceBHalfEdges[ 0 ]->m_pNextCCW = pFaceBHalfEdges[ 1 ]; pFaceBHalfEdges[ 1 ]->m_pNextCCW = pFaceBHalfEdges[ 2 ]; pFaceBHalfEdges[ 2 ]->m_pNextCCW = pFaceBHalfEdges[ 0 ]; pFaceCHalfEdges[ 0 ]->m_pNextCCW = pFaceCHalfEdges[ 1 ]; pFaceCHalfEdges[ 1 ]->m_pNextCCW = pFaceCHalfEdges[ 2 ]; pFaceCHalfEdges[ 2 ]->m_pNextCCW = pFaceCHalfEdges[ 0 ]; pFaceDHalfEdges[ 0 ]->m_pNextCCW = pFaceDHalfEdges[ 1 ]; pFaceDHalfEdges[ 1 ]->m_pNextCCW = pFaceDHalfEdges[ 2 ]; pFaceDHalfEdges[ 2 ]->m_pNextCCW = pFaceDHalfEdges[ 0 ]; pFaceAHalfEdges[ 0 ]->m_pFace = pFaceA; pFaceAHalfEdges[ 1 ]->m_pFace = pFaceA; pFaceAHalfEdges[ 2 ]->m_pFace = pFaceA; pFaceBHalfEdges[ 0 ]->m_pFace = pFaceB; pFaceBHalfEdges[ 1 ]->m_pFace = pFaceB; pFaceBHalfEdges[ 2 ]->m_pFace = pFaceB; pFaceCHalfEdges[ 0 ]->m_pFace = pFaceC; pFaceCHalfEdges[ 1 ]->m_pFace = pFaceC; pFaceCHalfEdges[ 2 ]->m_pFace = pFaceC; pFaceDHalfEdges[ 0 ]->m_pFace = pFaceD; pFaceDHalfEdges[ 1 ]->m_pFace = pFaceD; pFaceDHalfEdges[ 2 ]->m_pFace = pFaceD; pFaceAHalfEdges[ 0 ]->m_pVertex = pVertexA; pFaceAHalfEdges[ 1 ]->m_pVertex = pVertexB; pFaceAHalfEdges[ 2 ]->m_pVertex = pVertexC; pFaceBHalfEdges[ 0 ]->m_pVertex = pVertexB; pFaceBHalfEdges[ 1 ]->m_pVertex = pVertexD; pFaceBHalfEdges[ 2 ]->m_pVertex = pVertexC; pFaceCHalfEdges[ 0 ]->m_pVertex = pVertexD; pFaceCHalfEdges[ 1 ]->m_pVertex = pVertexA; pFaceCHalfEdges[ 2 ]->m_pVertex = pVertexC; pFaceDHalfEdges[ 0 ]->m_pVertex = pVertexB; pFaceDHalfEdges[ 1 ]->m_pVertex = pVertexA; pFaceDHalfEdges[ 2 ]->m_pVertex = pVertexD; //pVertexA->m_pHalfEdge = pFaceAHalfEdges[ 0 ]; //pVertexB->m_pHalfEdge = pFaceAHalfEdges[ 1 ]; //pVertexC->m_pHalfEdge = pFaceAHalfEdges[ 2 ]; //pVertexD->m_pHalfEdge = pFaceBHalfEdges[ 1 ]; pFaceAHalfEdges[ 0 ]->m_pTwin = pFaceDHalfEdges[ 0 ]; pFaceAHalfEdges[ 1 ]->m_pTwin = pFaceBHalfEdges[ 2 ]; pFaceAHalfEdges[ 2 ]->m_pTwin = pFaceCHalfEdges[ 1 ]; pFaceBHalfEdges[ 0 ]->m_pTwin = pFaceDHalfEdges[ 2 ]; pFaceBHalfEdges[ 1 ]->m_pTwin = pFaceCHalfEdges[ 2 ]; pFaceBHalfEdges[ 2 ]->m_pTwin = pFaceAHalfEdges[ 1 ]; pFaceCHalfEdges[ 0 ]->m_pTwin = pFaceDHalfEdges[ 1 ]; pFaceCHalfEdges[ 1 ]->m_pTwin = pFaceAHalfEdges[ 2 ]; pFaceCHalfEdges[ 2 ]->m_pTwin = pFaceBHalfEdges[ 1 ]; pFaceDHalfEdges[ 0 ]->m_pTwin = pFaceAHalfEdges[ 0 ]; pFaceDHalfEdges[ 1 ]->m_pTwin = pFaceCHalfEdges[ 0 ]; pFaceDHalfEdges[ 2 ]->m_pTwin = pFaceBHalfEdges[ 0 ]; if ( !pFaceA->Initialize() || !pFaceB->Initialize() || !pFaceC->Initialize() || !pFaceD->Initialize() ) { EPA_DEBUG_ASSERT( false, "One initial face failed to initialize!" ); return false; } #ifdef EPA_POLYHEDRON_USE_PLANES if ( nbInitialPoints > 4 ) { for ( int i = 0; i < nbInitialPoints; ++i ) { if ( ( i != finalPointsIndices[ 0 ] ) && ( i != finalPointsIndices[ 1 ] ) && ( i != finalPointsIndices[ 2 ] ) && ( i != finalPointsIndices[ 3 ] ) ) { std::list< EpaFace* >::iterator facesItr( m_faces.begin() ); while ( facesItr != m_faces.end() ) { EpaFace* pFace = *facesItr; btScalar dist = pFace->m_planeNormal.dot( pInitialPoints[ i ] ) + pFace->m_planeDistance; if ( dist > PLANE_THICKNESS ) { std::list< EpaFace* > newFaces; bool expandOk = Expand( pInitialPoints[ i ], pSupportPointsOnA[ i ], pSupportPointsOnB[ i ], pFace, newFaces ); if ( !expandOk ) { // One or more new faces are affinely dependent return false; } EPA_DEBUG_ASSERT( !newFaces.empty() ,"Polyhedron should have expanded!" ); break; } ++facesItr; } } } } #endif return true; }
int R3Mesh:: ReadOff(const char *filename) { // Open file FILE *fp; if (!(fp = fopen(filename, "r"))) { fprintf(stderr, "Unable to open file %s\n", filename); return 0; } // Read file int nverts = 0; int nfaces = 0; int nedges = 0; int line_count = 0; int vertex_count = 0; int face_count = 0; char buffer[1024]; char header[64]; while (fgets(buffer, 1023, fp)) { // Increment line counter line_count++; // Skip white space char *bufferp = buffer; while (isspace(*bufferp)) bufferp++; // Skip blank lines and comments if (*bufferp == '#') continue; if (*bufferp == '\0') continue; // Check section if (nverts == 0) { // Read header keyword if (strstr(bufferp, "OFF")) { // Check if counts are on first line int tmp; if (sscanf(bufferp, "%s%d%d%d", header, &tmp, &nfaces, &nedges) == 4) { nverts = tmp; } } else { // Read counts from second line if ((sscanf(bufferp, "%d%d%d", &nverts, &nfaces, &nedges) != 3) || (nverts == 0)) { fprintf(stderr, "Syntax error reading header on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } } } else if (vertex_count < nverts) { // Read vertex coordinates double x, y, z; if (sscanf(bufferp, "%lf%lf%lf", &x, &y, &z) != 3) { fprintf(stderr, "Syntax error with vertex coordinates on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Create vertex CreateVertex(R3Point(x, y, z), R3zero_vector, R2zero_point); // Increment counter vertex_count++; } else if (face_count < nfaces) { // Read number of vertices in face int face_nverts = 0; bufferp = strtok(bufferp, " \t"); if (bufferp) face_nverts = atoi(bufferp); else { fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Read vertex indices for face vector<R3MeshVertex *> face_vertices; for (int i = 0; i < face_nverts; i++) { R3MeshVertex *v = NULL; bufferp = strtok(NULL, " \t"); if (bufferp) v = Vertex(atoi(bufferp)); else { fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Add vertex to vector face_vertices.push_back(v); } // Create face CreateFace(face_vertices); // Increment counter face_count++; } else { // Should never get here fprintf(stderr, "Found extra text starting at line %d in file %s\n", line_count, filename); break; } } // Check whether read all vertices if ((vertex_count != nverts) || (NVertices() < nverts)) { fprintf(stderr, "Expected %d vertices, but read %d vertex lines and created %d vertices in file %s\n", nverts, vertex_count, NVertices(), filename); } // Check whether read all faces if ((face_count != nfaces) || (NFaces() < nfaces)) { fprintf(stderr, "Expected %d faces, but read %d face lines and created %d faces in file %s\n", nfaces, face_count, NFaces(), filename); } // Close file fclose(fp); // Return number of faces read return NFaces(); }
int R3Mesh:: ReadRay(const char *filename) { // Open file FILE *fp; if (!(fp = fopen(filename, "r"))) { fprintf(stderr, "Unable to open file %s", filename); return 0; } // Read body char cmd[128]; int polygon_count = 0; int command_number = 1; while (fscanf(fp, "%s", cmd) == 1) { if (!strcmp(cmd, "#vertex")) { // Read data double px, py, pz; double nx, ny, nz; double ts, tt; if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf", &px, &py, &pz, &nx, &ny, &nz, &ts, &tt) != 8) { fprintf(stderr, "Unable to read vertex at command %d in file %s", command_number, filename); return 0; } // Create vertex R3Point point(px, py, pz); R3Vector normal(nx, ny, nz); R2Point texcoords(ts, tt); CreateVertex(point, normal, texcoords); } else if (!strcmp(cmd, "#shape_polygon")) { // Read data int m, nverts; if (fscanf(fp, "%d%d", &m, &nverts) != 2) { fprintf(stderr, "Unable to read polygon at command %d in file %s", command_number, filename); return 0; } // Get vertices vector<R3MeshVertex *> face_vertices; for (int i = 0; i < nverts; i++) { // Read vertex id int vertex_id; if (fscanf(fp, "%d", &vertex_id) != 1) { fprintf(stderr, "Unable to read polygon at command %d in file %s", command_number, filename); return 0; } // Get vertex R3MeshVertex *v = Vertex(vertex_id); face_vertices.push_back(v); } // Create face CreateFace(face_vertices); // Increment polygon counter polygon_count++; } // Increment command number command_number++; } // Close file fclose(fp); // Return number of faces created return polygon_count; }
ObjModel::ObjModel(const std::string& filePath) { // standardise dir seperators std::string filePathStd = std::string(filePath); std::replace(filePathStd.begin(), filePathStd.end(), '\\', '/'); // asd/asd/asd/asd/asd/asd/file.obj auto tokens = SplitString(filePathStd, '/'); std::string fileName = tokens[tokens.size() - 1]; std::string workingDir = filePathStd.substr(0, filePathStd.size() - fileName.size()); std::ifstream file; file.open((workingDir + "/" + fileName).c_str()); int curMaterialIndex = 0; std::string line; if (file.is_open()) { while (file.good()) { getline(file, line); unsigned int lineLength = line.length(); if (lineLength < 2) continue; const char* lineCStr = line.c_str(); switch (lineCStr[0]) { case 'v': // "v?" => vertex { switch (lineCStr[1]) { case 't': // ? == 't' => vertex texture / uv coords { #define TEMP_SSCANF // ~5.5 secs //#define TEMP_SPLIT // ~10 secs //#define TEMP_STREAM // ~7.5 secs #ifdef TEMP_SSCANF glm::vec2 vt; sscanf_s(lineCStr, "vt %f %f", &vt.x, &vt.y); textures.push_back(vt); #endif // SSCANF #ifdef TEMP_SPLIT textures.push_back(ParseVec2(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec2 vt; issvt >> vt.x; issvt >> vt.y; textures.push_back(vt); #endif // TEMP_STREAM break; } case 'n': // ? == 'n' => vertex normal { #ifdef TEMP_SSCANF glm::vec3 vn; sscanf_s(lineCStr, "vn %f %f %f", &vn.x, &vn.y, &vn.z); normals.push_back(vn); #endif // SSCANF #ifdef TEMP_SPLIT normals.push_back(ParseVec3(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec3 vn; issvt >> vn.x; issvt >> vn.y; issvt >> vn.z; normals.push_back(vn); #endif // TEMP_STREAM break; } case '\t': // ? == ' ' => vertex case ' ': { #ifdef TEMP_SSCANF glm::vec3 v; sscanf_s(lineCStr, "v %f %f %f", &v.x, &v.y, &v.z); positions.push_back(v); #endif // SSCANF #ifdef TEMP_SPLIT positions.push_back(ParseVec3(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec3 v; issvt >> v.x; issvt >> v.y; issvt >> v.z; positions.push_back(v); #endif // TEMP_STREAM break; } } break; } case 'f': // 'f' => face { CreateFace(curMaterialIndex, line); break; } case 'm': // 'm' => material template lib { if (lineCStr[1] != 't') break; char buffer[BUFSIZ]; sscanf_s(lineCStr, "mtllib %s", &buffer); std::string mtlFileName = std::string(buffer); //std::string mtlFileName = SplitString(line, ' ')[1]; std::vector<Material*> mats = LoadMaterials(workingDir, mtlFileName); materials.insert(std::end(materials), std::begin(mats), std::end(mats)); break; } case 'u': // 'u' => usemtl { if (lineCStr[1] != 's') break; std::string mtlName = SplitString(line, ' ')[1]; for (int i = 0; i < materials.size(); i++) { if (materials[i]->name == mtlName) { curMaterialIndex = i; break; } } break; } }; } } else {
void Chunk::Init(ID3D11Device* p_pDevice, ID3D11DeviceContext* p_pDevCon) { m_pDevice = p_pDevice; m_pDevCon = p_pDevCon; TimeSinceStart = 0; // World Gen for (int x = 0; x < ChunkSize; x++) for (int y = 0; y < ChunkSize; y++) for (int z = 0; z < ChunkSize; z++) { if (rand() % 2 > 0) { m_BlockData[x][y][z] = 1; } else { m_BlockData[x][y][z] = 0; } } // Faces Zählen FaceCount = 0; for (int x = 0; x < ChunkSize; x++) for (int y = 0; y < ChunkSize; y++) for (int z = 0; z < ChunkSize; z++) { // Wenn der eigene Block Solide ist, dann Faces generieren if (GetBlockAt(x, y, z) != 0) { // Ein Face für jeden anliegenden LuftBlock if (GetBlockAt(x + 1, y, z) == 0) FaceCount += 1; if (GetBlockAt(x - 1, y, z) == 0) FaceCount += 1; if (GetBlockAt(x, y + 1, z) == 0) FaceCount += 1; if (GetBlockAt(x, y - 1, z) == 0) FaceCount += 1; if (GetBlockAt(x, y, z + 1) == 0) FaceCount += 1; if (GetBlockAt(x, y, z - 1) == 0) FaceCount += 1; } } ChunkVertexStruct* _Vertices = new ChunkVertexStruct[FaceCount * 4]; unsigned int* _Indices = new unsigned int[FaceCount * 6]; int FaceIndex = 0; for (int x = 0; x < ChunkSize; x++) for (int y = 0; y < ChunkSize; y++) for (int z = 0; z < ChunkSize; z++) { // Wenn der eigene Block Solide ist, dann Faces generieren if (GetBlockAt(x, y, z) != 0) { if (GetBlockAt(x + 1, y, z) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x + 0.5f, y, z), D3DXVECTOR3(0, 0, 1), D3DXVECTOR3(0, 1, 0), _Indices, _Vertices, FaceIndex); FaceIndex++; } if (GetBlockAt(x - 1, y, z) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x - 0.5f, y, z), D3DXVECTOR3(0, 0, -1), D3DXVECTOR3(0, 1, 0), _Indices, _Vertices, FaceIndex); FaceIndex++; } if (GetBlockAt(x, y - 1, z) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x, y - 0.5f, z), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR3(0, 0, 1), _Indices, _Vertices, FaceIndex); FaceIndex++; } if (GetBlockAt(x, y + 1, z) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x, y + 0.5f, z), D3DXVECTOR3(1, 0, 0), D3DXVECTOR3(0, 0, 1), _Indices, _Vertices, FaceIndex); FaceIndex++; } if (GetBlockAt(x, y, z + 1) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x, y, z + 0.5f), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR3(0, 1, 0), _Indices, _Vertices, FaceIndex); FaceIndex++; } if (GetBlockAt(x, y, z - 1) == 0) { // Face generieren CreateFace(D3DXVECTOR3(x, y, z - 0.5f), D3DXVECTOR3(1, 0, 0), D3DXVECTOR3(0, 1, 0), _Indices, _Vertices, FaceIndex); FaceIndex++; } } } // VertexBuffer erstellen D3D11_BUFFER_DESC _VBDesc; ZeroMemory(&_VBDesc, sizeof(_VBDesc)); _VBDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_VERTEX_BUFFER; _VBDesc.ByteWidth = (FaceCount * 4) * sizeof(ChunkVertexStruct); _VBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE; _VBDesc.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC; m_pDevice->CreateBuffer(&_VBDesc, nullptr, &m_pVertexBuffer); D3D11_MAPPED_SUBRESOURCE _VBMSR; m_pDevCon->Map(m_pVertexBuffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &_VBMSR); memcpy(_VBMSR.pData, _Vertices, (FaceCount * 4) * sizeof(ChunkVertexStruct)); m_pDevCon->Unmap(m_pVertexBuffer, 0); delete[] _Vertices; // Index Buffer erstellen D3D11_BUFFER_DESC _IBDesc; ZeroMemory(&_IBDesc, sizeof(_IBDesc)); _IBDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_INDEX_BUFFER; _IBDesc.ByteWidth = (FaceCount * 6) * sizeof(unsigned int); _IBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE; _IBDesc.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC; m_pDevice->CreateBuffer(&_IBDesc, nullptr, &m_pIndexBuffer); D3D11_MAPPED_SUBRESOURCE _IBMSR; m_pDevCon->Map(m_pIndexBuffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &_IBMSR); memcpy(_IBMSR.pData, _Indices, (FaceCount * 6) * sizeof(unsigned int)); m_pDevCon->Unmap(m_pIndexBuffer, 0); delete[] _Indices; // Shader Laden ID3D10Blob* _pVShaderBlob; ID3D10Blob* _pPShaderBlob; ID3D10Blob* _pErrorBlob; // VertexShader if(D3DX11CompileFromFile("VoxelShader.hlsl", nullptr, nullptr, "VShader", "vs_5_0", 0, 0, nullptr, &_pVShaderBlob, &_pErrorBlob, nullptr) != S_OK) { MessageBox(0, (char*)_pErrorBlob->GetBufferPointer(), "Fehler im Vertexshader", 0); PostQuitMessage(0); return; } m_pDevice->CreateVertexShader(_pVShaderBlob->GetBufferPointer(), _pVShaderBlob->GetBufferSize(), nullptr, &m_pVertexShader); // PixelShader if(S_OK != D3DX11CompileFromFile("VoxelShader.hlsl", nullptr, nullptr, "PShader", "ps_5_0", 0, 0, nullptr, &_pPShaderBlob, &_pErrorBlob, nullptr)) { MessageBox(0, (char*)_pErrorBlob->GetBufferPointer(), "Fehler im Pixelshader", 0); PostQuitMessage(0); return; } m_pDevice->CreatePixelShader(_pPShaderBlob->GetBufferPointer(), _pPShaderBlob->GetBufferSize(), nullptr, &m_pPixelShader); // InputLayout erstellen D3D11_INPUT_ELEMENT_DESC _IED[3]; // Position _IED[0].SemanticName = "POSITION"; _IED[0].SemanticIndex = 0; _IED[0].AlignedByteOffset = 0; _IED[0].Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT; _IED[0].InputSlot = 0; _IED[0].InstanceDataStepRate = 0; _IED[0].InputSlotClass = D3D11_INPUT_CLASSIFICATION::D3D11_INPUT_PER_VERTEX_DATA; // UV _IED[1].SemanticName = "TEXCOORD"; _IED[1].SemanticIndex = 0; _IED[1].AlignedByteOffset = 12; _IED[1].Format = DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT; _IED[1].InputSlot = 0; _IED[1].InstanceDataStepRate = 0; _IED[1].InputSlotClass = D3D11_INPUT_CLASSIFICATION::D3D11_INPUT_PER_VERTEX_DATA; // Normal _IED[2].SemanticName = "NORMAL"; _IED[2].SemanticIndex = 0; _IED[2].AlignedByteOffset = 20; _IED[2].Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT; _IED[2].InputSlot = 0; _IED[2].InstanceDataStepRate = 0; _IED[2].InputSlotClass = D3D11_INPUT_CLASSIFICATION::D3D11_INPUT_PER_VERTEX_DATA; m_pDevice->CreateInputLayout(_IED, 3, _pVShaderBlob->GetBufferPointer(), _pVShaderBlob->GetBufferSize(), &m_pInputLayout); D3DX11CreateShaderResourceViewFromFile(m_pDevice, "Dirt.jpg", nullptr, nullptr, &m_pDirtTexture, nullptr); D3D11_BUFFER_DESC _CBDesc; ZeroMemory(&_CBDesc, sizeof(_CBDesc)); _CBDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_CONSTANT_BUFFER; _CBDesc.ByteWidth = sizeof(D3DXMATRIX); _CBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE; _CBDesc.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC; m_pDevice->CreateBuffer(&_CBDesc, nullptr, &m_pConstantBufferMatrix); D3D11_BUFFER_DESC _CBDescLight; ZeroMemory(&_CBDescLight, sizeof(_CBDescLight)); _CBDescLight.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_CONSTANT_BUFFER; _CBDescLight.ByteWidth = sizeof(ChunkConstantBuffer); _CBDescLight.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE; _CBDescLight.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC; m_pDevice->CreateBuffer(&_CBDescLight, nullptr, &m_pConstantBufferLight); }