Example #1
0
void RayIntersectorKDTree::Init(const BaseMesh &M)
{
    Console::WriteString("Building RayIntersectorKDTree...");
    FreeMemory();

    _VertexCount = M.VertexCount();
    _TriangleCount = M.FaceCount();

    Console::WriteString(String(_TriangleCount) + String(" base triangles, "));
    

    _Vertices = new Vec3f[_VertexCount];
    _Indices = new UINT[_TriangleCount * 3];
    
    const MeshVertex *MeshVertices = M.Vertices();
    const DWORD *MeshIndices = M.Indices();
    
    for(UINT VertexIndex = 0; VertexIndex < _VertexCount; VertexIndex++)
    {
        _Vertices[VertexIndex] = MeshVertices[VertexIndex].Pos;
    }

    for(UINT IndexIndex = 0; IndexIndex < _TriangleCount * 3; IndexIndex++)
    {
        _Indices[IndexIndex] = MeshIndices[IndexIndex];
    }

    Vector<UINT> TriangleIndices(_TriangleCount);
    for(UINT TriangleIndex = 0; TriangleIndex < _TriangleCount; TriangleIndex++)
    {
        TriangleIndices[TriangleIndex] = TriangleIndex;
    }
    
    Vector<UINT> LeafTrianglesVector;
    _Root = new RayIntersectorKDTreeNode(TriangleIndices, *this, 0, LeafTrianglesVector);
    _LeafTriangleCount = LeafTrianglesVector.Length();
    _LeafTriangles = new UINT[_LeafTriangleCount];
    memcpy(_LeafTriangles, LeafTrianglesVector.CArray(), sizeof(UINT) * _LeafTriangleCount);
    Console::WriteLine(String(_LeafTriangleCount) + String(" leaf triangles."));
}
void IcoSphere::addFace(int index0, int index1, int index2)
{
	faces.push_back(TriangleIndices(index0, index1, index2));
}
void IcoSphere::create(int recursionLevel)
{
	vertices.clear();
	lineIndices.clear();
	triangleIndices.clear();
	faces.clear();
	middlePointIndexCache.clear();
	index = 0;
 
	float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f;
 
	addVertex(Ogre::Vector3(-1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3(-1.0f, -t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f, -t,  0.0f));
 
	addVertex(Ogre::Vector3( 0.0f, -1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f, -1.0f, -t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f, -t));
 
	addVertex(Ogre::Vector3( t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3( t,  0.0f,  1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f,  1.0f));
 
	addFace(0, 11, 5);
	addFace(0, 5, 1);
	addFace(0, 1, 7);
	addFace(0, 7, 10);
	addFace(0, 10, 11);
 
	addFace(1, 5, 9);
	addFace(5, 11, 4);
	addFace(11, 10, 2);
	addFace(10, 7, 6);
	addFace(7, 1, 8);
 
	addFace(3, 9, 4);
	addFace(3, 4, 2);
	addFace(3, 2, 6);
	addFace(3, 6, 8);
	addFace(3, 8, 9);
 
	addFace(4, 9, 5);
	addFace(2, 4, 11);
	addFace(6, 2, 10);
	addFace(8, 6, 7);
	addFace(9, 8, 1);
 
	addLineIndices(1, 0);
	addLineIndices(1, 5);
	addLineIndices(1, 7);
	addLineIndices(1, 8);
	addLineIndices(1, 9);
 
	addLineIndices(2, 3);
	addLineIndices(2, 4);
	addLineIndices(2, 6);
	addLineIndices(2, 10);
	addLineIndices(2, 11);
 
	addLineIndices(0, 5);
	addLineIndices(5, 9);
	addLineIndices(9, 8);
	addLineIndices(8, 7);
	addLineIndices(7, 0);
 
	addLineIndices(10, 11);
	addLineIndices(11, 4);
	addLineIndices(4, 3);
	addLineIndices(3, 6);
	addLineIndices(6, 10);
 
	addLineIndices(0, 11);
	addLineIndices(11, 5);
	addLineIndices(5, 4);
	addLineIndices(4, 9);
	addLineIndices(9, 3);
	addLineIndices(3, 8);
	addLineIndices(8, 6);
	addLineIndices(6, 7);
	addLineIndices(7, 10);
	addLineIndices(10, 0);
 
	for (int i = 0; i < recursionLevel; i++)
	{
		std::list<TriangleIndices> faces2;
 
		for (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++)
		{
			TriangleIndices f = *j;
			int a = getMiddlePoint(f.v1, f.v2);
			int b = getMiddlePoint(f.v2, f.v3);
			int c = getMiddlePoint(f.v3, f.v1);
 
			removeLineIndices(f.v1, f.v2);
			removeLineIndices(f.v2, f.v3);
			removeLineIndices(f.v3, f.v1);
 
			faces2.push_back(TriangleIndices(f.v1, a, c));
			faces2.push_back(TriangleIndices(f.v2, b, a));
			faces2.push_back(TriangleIndices(f.v3, c, b));
			faces2.push_back(TriangleIndices(a, b, c));
 
			addTriangleLines(f.v1, a, c);
			addTriangleLines(f.v2, b, a);
			addTriangleLines(f.v3, c, b);
		}
 
		faces = faces2;
	}
}
    void generate()
    {
        // create 12 vertices of a icosahedron
        double t = (1 + std::sqrt(5)) / 2;

        vertexList_.push_back(utymap::meshing::Vector3(-1, t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(1, t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-1, -t, 0).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(1, -t, 0).normalized());

        vertexList_.push_back(utymap::meshing::Vector3(0, -1, t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0, 1, t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0., -1, -t).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(0, 1, -t).normalized());

        vertexList_.push_back(utymap::meshing::Vector3(t, 0, -1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(t, 0, 1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-t, 0, -1).normalized());
        vertexList_.push_back(utymap::meshing::Vector3(-t, 0, 1).normalized());

        // create 20 triangles of the icosahedron
        std::vector<TriangleIndices> faces;
        // 5 faces around point 0
        faces.push_back(TriangleIndices(0, 11, 5));
        faces.push_back(TriangleIndices(0, 5, 1));
        faces.push_back(TriangleIndices(0, 1, 7));
        faces.push_back(TriangleIndices(0, 7, 10));
        faces.push_back(TriangleIndices(0, 10, 11));

        // 5 adjacent faces
        faces.push_back(TriangleIndices(1, 5, 9));
        faces.push_back(TriangleIndices(5, 11, 4));
        if (!isSemiSphere_)
            faces.push_back(TriangleIndices(11, 10, 2));

        faces.push_back(TriangleIndices(10, 7, 6));
        faces.push_back(TriangleIndices(7, 1, 8));

        // 5 faces around point 3
        if (!isSemiSphere_)
        {
            faces.push_back(TriangleIndices(3, 9, 4));
            faces.push_back(TriangleIndices(3, 4, 2));
            faces.push_back(TriangleIndices(3, 2, 6));
            faces.push_back(TriangleIndices(3, 6, 8));
            faces.push_back(TriangleIndices(3, 8, 9));
        }

        // 5 adjacent faces
        faces.push_back(TriangleIndices(4, 9, 5));
        if (!isSemiSphere_)
        {
            faces.push_back(TriangleIndices(2, 4, 11));
            faces.push_back(TriangleIndices(6, 2, 10));
        }
        faces.push_back(TriangleIndices(8, 6, 7));
        faces.push_back(TriangleIndices(9, 8, 1));

        // refine triangles
        for (int i = 0; i < recursionLevel_; i++)
        {
            std::vector<TriangleIndices> faces2;
            for (const auto& tri : faces)
            {
                // replace triangle by 4 triangles
                auto a = getMiddlePoint(tri.V1, tri.V2);
                auto b = getMiddlePoint(tri.V2, tri.V3);
                auto c = getMiddlePoint(tri.V3, tri.V1);

                faces2.push_back(TriangleIndices(tri.V1, a, c));
                faces2.push_back(TriangleIndices(tri.V2, b, a));
                faces2.push_back(TriangleIndices(tri.V3, c, b));
                faces2.push_back(TriangleIndices(a, b, c));
            }
            faces = faces2;
        }
        generateMesh(faces);

        // clear state to allow reusage
        middlePointIndexCache_.clear();
        vertexList_.clear();
    }