Beispiel #1
0
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;
}
Beispiel #2
0
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();
}
Beispiel #4
0
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);
  }
}
Beispiel #5
0
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;
}
Beispiel #6
0
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();
}
Beispiel #7
0
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;
}
Beispiel #8
0
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
	{
Beispiel #9
0
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);
}