Example #1
0
void BaseMesh::CopyMesh(BaseMesh &Copy) const
{
    Copy._GD = _GD;
    Copy.Allocate(VertexCount(), FaceCount());
    memcpy(Copy.Vertices(), Vertices(), sizeof(MeshVertex) * VertexCount());
    memcpy(Copy.Indices(), Indices(), sizeof(DWORD) * IndexCount());
}
Example #2
0
void BaseMesh::AppendVertices(const BaseMesh &O)
{
    int vc = VertexCount(), ic = IndexCount();
    MeshVertex *V = Vertices(), *OldV = new MeshVertex[vc];
    DWORD *I = Indices(), *OldI = new DWORD[ic];

    memcpy(OldV, V, vc * sizeof(MeshVertex));
    memcpy(OldI, I, ic * sizeof(DWORD));            //store all the old vertices/indices

    Allocate(vc + O.VertexCount(), ic/3 + O.FaceCount());    //allocate space for the current vertices/indices and o's vertices/indices

    V = Vertices();
    I = Indices();

    memcpy(V, OldV, vc * sizeof(MeshVertex));
    memcpy(I, OldI, ic * sizeof(DWORD));        //copy the old vertices/indices back into the mesh,

    memcpy(&(V[vc]), O.Vertices(), O.VertexCount() * sizeof(MeshVertex));    //copy the new vertices after the current ones,

    UINT oic = O.IndexCount();
    const DWORD *oI = O.Indices();
    for(UINT i = 0; i < oic; i++)
    {
        I[ic+i] = oI[i] + vc;    //copy o's indices as well, except increasing the index by vc (since o's vertices start at vc, not 0)
    }

    delete[] OldV;
    delete[] OldI;
}
Example #3
0
void D3D9Mesh::CopyMesh(BaseMesh &Copy) const
{
    Copy.SetGD(GetGD());

    int VC = VertexCount();
    int IC = IndexCount();

    if(VC > 0 && IC > 0)
    {
        if(_Vertices == NULL)
        {
            _Mesh->LockVertexBuffer(0,(void**) &_Vertices);
        }
        if(_Indices == NULL)
        {
            _Mesh->LockIndexBuffer(0,(void**) &_Indices);
        }

        Copy.Allocate(VC, IC / 3);                                //allocate space in Copy
        memcpy(Copy.Vertices(), _Vertices, VC * sizeof(MeshVertex));    //insert our vertices into Copy
        memcpy(Copy.Indices(), _Indices, IC * sizeof(DWORD));            //insert our indices into Copy

        Unlock();
    }
}
Example #4
0
void BaseMesh::CreateBox(float w, float h, float d, int refinement)
{
    Allocate(8, 12);

    MeshVertex Temp(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    for(i=0;i<8;i++)
    {
        Temp.Pos = Vec3f(CubeVData[i][0],CubeVData[i][1],CubeVData[i][2]);
        V[i] = Temp;        ///load the vertices
    }
    for(i=0;i<12;i++)
    {
        I[i*3+0] = CubeIData[i][0];
        I[i*3+1] = CubeIData[i][1];
        I[i*3+2] = CubeIData[i][2];    //load the triangles
    }

    for(i=0;i<refinement;i++)
    {
        TwoPatch();                //refine the requested number of times
    }

    Stretch(Vec3f(0.5f*w, 0.5f*h, 0.5f*d));    //stretch to the requested dimensions
    GenerateNormals();
}
void BaseMesh::GenerateNormals()
{
    UINT vc = VertexCount(), ic = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vec3f V1, V2, Normal;

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Normal = Vec3f::Origin;    //zero each normal
    }

    for(UINT i = 0; i < ic; i += 3)            //for every triangle
    {
        V1 = V[I[i+2]].Pos - V[I[i+0]].Pos;
        V2 = V[I[i+1]].Pos - V[I[i+0]].Pos;
        Normal = Vec3f::Cross(V1, V2);            //compute the triangle normal
        V[I[i+0]].Normal += Normal;
        V[I[i+1]].Normal += Normal;
        V[I[i+2]].Normal += Normal;            //each adjacent vertex adds the triangle normal to its summed normal
    }

    NormalizeNormals();
}
Example #6
0
void BaseMesh::WeldVertices(float Epsilon, Vector<UINT> &OldToNewMapping)
{
    PointSet MyPoints;
    MyPoints.LoadFromMesh(*this);
    KDTree3 &Tree = MyPoints.KDTree();
    
    UINT VC = VertexCount(), IC = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    OldToNewMapping.ReSize(VC);
    OldToNewMapping.Clear(VC);
    Vector<UINT> NNResult;
    //MeshVertex *VStorage = new MeshVertex[VC];
    
    for(UINT VertexIndex = 0; VertexIndex < VC; VertexIndex++)
    {
        Vec3f Pos = V[VertexIndex].Pos;
        Tree.WithinDistance(Pos, Epsilon, NNResult);
        bool MatchFound = false;
        //VStorage[VertexIndex] = V[VertexIndex];
        for(UINT ResultIndex = 0; ResultIndex < NNResult.Length() && !MatchFound; ResultIndex++)
        {
            UINT CurIndex = NNResult[ResultIndex];
            if(OldToNewMapping[CurIndex] != VC)
            {
                MatchFound = true;
                OldToNewMapping[VertexIndex] = CurIndex;
            }
        }
        if(!MatchFound)
        {
            OldToNewMapping[VertexIndex] = VertexIndex;
        }
    }

    //DWORD *IStorage = new DWORD[IC];
    for(UINT IndexIndex = 0; IndexIndex < IC; IndexIndex++)
    {
        I[IndexIndex] = OldToNewMapping[UINT(I[IndexIndex])];
    }

    //Allocate(
    //delete[] VStorage;
    
    Vector<UINT> SecondMapping, SplitToUnsplit = OldToNewMapping;
    CleanVerticesAndTriangles(SecondMapping);
    for(UINT VertexIndex = 0; VertexIndex < VC; VertexIndex++)
    {
        OldToNewMapping[VertexIndex] = SecondMapping[SplitToUnsplit[VertexIndex]];
    }
}
Example #7
0
void BaseMesh::UnIndex()
{
    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices(),*OldV = new MeshVertex[vc];
    DWORD *I = Indices(),*OldI = new DWORD[ic];                //create space for all the old vertices and indices

    memcpy(OldV, V, vc * sizeof(MeshVertex));
    memcpy(OldI, I, ic * sizeof(DWORD));        //copy all the old verticse and indices for storage

    Allocate(ic, ic/3);        //allocate space for the new vertices/indices
    vc=VertexCount();
    ic=IndexCount();
    V = Vertices();
    I = Indices();

    for(i=0;i<vc;i++)
    {
        V[i] = OldV[OldI[i]];    //load the new vertex array
        I[i] = i;                //the new indices are trivial; we just take every triplet in the vertex array directly.
    }

    delete[] OldV;
    delete[] OldI;    //free up the storage
}
Example #8
0
void BaseBufferRenderBatch::AddNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node)
{
	auto mesh = node.Mesh();
	const Matrix4& newMatrix = node.WorldMatrix();

	mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex,  newMatrix);
	mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex,  newMatrix);
	mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex);
	mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor());
	mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex);

	uintp vertexCount = mesh->VertexCount();
	uintp indexCount = mesh->IndexCount();
	node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount);
	refVertexIndex += (uint)vertexCount;
	refIndexIndex += (uint)indexCount;
	RenderingStatics::Instance().IncreaseChangedNodeCount();

}
Example #9
0
void BaseMesh::CreateSphere(float radius, int refinement)
{
    //allocate space for the icosahedron
    Allocate(12, 20);

    MeshVertex Temp(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    for(i=0;i<12;i++)
    {
        Temp.Pos = Vec3f(IcosahedronVData[i][0],IcosahedronVData[i][1],IcosahedronVData[i][2]);
        V[i] = Temp;                        //load the icosahedron vertices
    }
    for(i=0;i<20;i++)
    {
        I[i*3+0] = IcosahedronIData[i][1];
        I[i*3+1] = IcosahedronIData[i][0];
        I[i*3+2] = IcosahedronIData[i][2];    //load the icosahedron indices
    }

    for(i=0;i<refinement;i++)
        TwoPatch();                //refine the specified number of times

    vc=VertexCount();
    V = Vertices();

    for(i=0;i<vc;i++)
    {
        V[i].Pos = Vec3f::Normalize(V[i].Pos);
        V[i].Pos *= radius;        //project all the points to lie on a sphere of the specified radius
    }

    GenerateNormals();            //generate normals
    SetColor(RGBColor::White);
}
Example #10
0
void BaseBufferRenderBatch::UpdateNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node, RenderableChangedFlags changedFlags)
{
	auto mesh = node.Mesh();
	if (MEDUSA_FLAG_HAS(changedFlags,RenderableChangedFlags::NewVertex))
	{
		const Matrix4& newMatrix = node.WorldMatrix();
		mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex,  newMatrix);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewNormal))
	{
		const Matrix4& newMatrix = node.WorldMatrix();
		mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex,  newMatrix);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewTexCoord))
	{
		mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewColor))
	{
		mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor());
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewIndex))
	{
		mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex);
	}

	uintp vertexCount = mesh->VertexCount();
	uintp indexCount = mesh->IndexCount();
	node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount);
	refVertexIndex += (uint)vertexCount;
	refIndexIndex += (uint)indexCount;
	RenderingStatics::Instance().IncreaseChangedNodeCount();
}
Example #11
0
VarRef *VarRefParseFromNamespaceAndScope(const char *qualified_name, const char *_ns, const char *_scope, char ns_separator, char scope_separator)
{
    char *ns = NULL;

    const char *indices_start = strchr(qualified_name, '[');

    const char *scope_start = strchr(qualified_name, ns_separator);
    if (scope_start && (!indices_start || scope_start < indices_start))
    {
        ns = xstrndup(qualified_name, scope_start - qualified_name);
        scope_start++;
    }
    else
    {
        scope_start = qualified_name;
    }

    char *scope = NULL;

    const char *lval_start = strchr(scope_start, scope_separator);

    if (lval_start && (!indices_start || lval_start < indices_start))
    {
        lval_start++;
        scope = xstrndup(scope_start, lval_start - scope_start - 1);
    }
    else
    {
        lval_start = scope_start;
    }

    char *lval = NULL;
    char **indices = NULL;
    size_t num_indices = 0;

    if (indices_start)
    {
        indices_start++;
        lval = xstrndup(lval_start, indices_start - lval_start - 1);

        assert("Index brackets in variable expression did not balance" && IndexBracketsBalance(indices_start - 1));

        num_indices = IndexCount(indices_start - 1);
        indices = xmalloc(num_indices * sizeof(char *));

        Buffer *buf = BufferNew();
        size_t cur_index = 0;
        for (const char *c = indices_start; *c != '\0'; c++)
        {
            if (*c == '[')
            {
                cur_index++;
            }
            else if (*c == ']')
            {
                indices[cur_index] = xstrdup(BufferData(buf));
                BufferZero(buf);
            }
            else
            {
                BufferAppend(buf, c, sizeof(char));
            }
        }
        BufferDestroy(&buf);
    }
    else
    {
        lval = xstrdup(lval_start);
    }

    assert(lval);

    if (!scope && !_scope)
    {
        assert(ns == NULL && "A variable missing a scope should not have a namespace");
    }

    VarRef *ref = xmalloc(sizeof(VarRef));

    ref->ns = ns ? ns : (_ns ? xstrdup(_ns) : NULL);
    ref->scope = scope ? scope : (_scope ? xstrdup(_scope) : NULL);
    ref->lval = lval;
    ref->indices = indices;
    ref->num_indices = num_indices;

    ref->hash = VarRefHash(ref);

    return ref;
}
Example #12
0
void BaseMesh::Split(float (*PositionFunction) (Vec3f &), BaseMesh &M1, BaseMesh &M2)
{
    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<MeshVertex> NV1,NV2;
    Vector<TriMeshFace> NT1,NT2;

    SplitVMapper *VMap = new SplitVMapper[vc];
    float Value;

    for(i=0;i<vc;i++)
    {
        Value = PositionFunction(V[i].Pos);
        if(Value < 0.0f)
        {
            VMap[i].Side = 0;
            VMap[i].NVMap1 = NV1.Length();
            VMap[i].NVMap2 = -1;
            NV1.PushEnd(V[i]);
        } else {
            VMap[i].Side = 1;
            VMap[i].NVMap1 = -1;
            VMap[i].NVMap2 = NV2.Length();
            NV2.PushEnd(V[i]);
        }
    }

    int TSide[3];
    TriMeshFace Tri;
    int Oddball,State;

    for(i=0;i<ic;i+=3)
    {
        TSide[0] = VMap[I[i]].Side;
        TSide[1] = VMap[I[i+1]].Side;
        TSide[2] = VMap[I[i+2]].Side;

        if(TSide[0] && TSide[1] && TSide[2]) //all O2
        {            
            Tri.I[0] = VMap[I[i]].NVMap2;
            Tri.I[1] = VMap[I[i+1]].NVMap2;
            Tri.I[2] = VMap[I[i+2]].NVMap2;
            NT2.PushEnd(Tri);
        } else if(!(TSide[0] || TSide[1] || TSide[2])) //all O1
        {
            Tri.I[0] = VMap[I[i]].NVMap1;
            Tri.I[1] = VMap[I[i+1]].NVMap1;
            Tri.I[2] = VMap[I[i+2]].NVMap1;
            NT1.PushEnd(Tri);
        } else {
            if(TSide[0] && TSide[1]) {Oddball = 2; State = 1;}
            if(TSide[0] && TSide[2]) {Oddball = 1; State = 1;}
            if(TSide[1] && TSide[2]) {Oddball = 0; State = 1;}
            if(!(TSide[0] || TSide[1])) {Oddball = 2; State = 2;}
            if(!(TSide[0] || TSide[2])) {Oddball = 1; State = 2;}
            if(!(TSide[1] || TSide[2])) {Oddball = 0; State = 2;}

            if(State == 1)    //Add to Obj2
            {
                if(VMap[I[i+Oddball]].NVMap2 == -1)
                {
                    VMap[I[i+Oddball]].NVMap2 = NV2.Length();
                    NV2.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap2;
                Tri.I[1] = VMap[I[i+1]].NVMap2;
                Tri.I[2] = VMap[I[i+2]].NVMap2;
                NT2.PushEnd(Tri);
            } else {        //Add to Obj1
                if(VMap[I[i+Oddball]].NVMap1 == -1)
                {
                    VMap[I[i+Oddball]].NVMap1 = NV1.Length();
                    NV1.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap1;
                Tri.I[1] = VMap[I[i+1]].NVMap1;
                Tri.I[2] = VMap[I[i+2]].NVMap1;
                NT1.PushEnd(Tri);
            }
        }
    }

    delete[] VMap;

    M1.Allocate(NV1.Length(),NT1.Length());
    M2.Allocate(NV2.Length(),NT2.Length());
    
    memcpy(M1.Vertices(), NV1.CArray(), M1.VertexCount() * sizeof(MeshVertex));
    memcpy(M2.Vertices(), NV2.CArray(), M2.VertexCount() * sizeof(MeshVertex));
    memcpy(M1.Indices(), NT1.CArray(), M1.IndexCount() * sizeof(DWORD));
    memcpy(M2.Indices(), NT2.CArray(), M2.IndexCount() * sizeof(DWORD));
}
Example #13
0
void BaseMesh::ClosedPlaneSplit(const Plane &P, BaseMesh &M1, BaseMesh &M2)
{
    UINT VC = VertexCount(), IC = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<Vec3f> NewVertices[2];
    Vector<TriMeshFace> NewFaces[2];
    Vector<Vec2f> BoundaryVertices;
    Vector<UINT> BoundaryIndices[2];

    Vec3f OrthogonalBasis1, OrthogonalBasis2;
    Vec3f::CompleteOrthonormalBasis(P.Normal(), OrthogonalBasis1, OrthogonalBasis2);

    PerfectSplitVMapper *VMap = new PerfectSplitVMapper[VC];
    
    for(UINT VertexIndex = 0; VertexIndex < VC; VertexIndex++)
    {
        Vec3f Pos = V[VertexIndex].Pos;
        float Value = Plane::DotCoord(P, Pos);
        if(Value < 0.0f)
        {
            VMap[VertexIndex].Side = 0;
            VMap[VertexIndex].NVMap = NewVertices[0].Length();
            NewVertices[0].PushEnd(Pos);
        }
        else
        {
            VMap[VertexIndex].Side = 1;
            VMap[VertexIndex].NVMap = NewVertices[1].Length();
            NewVertices[1].PushEnd(Pos);
        }
    }

    for(UINT IndexIndex = 0; IndexIndex < IC; IndexIndex += 3)
    {
        int TSide[3];
        TSide[0] = VMap[I[IndexIndex + 0]].Side;
        TSide[1] = VMap[I[IndexIndex + 1]].Side;
        TSide[2] = VMap[I[IndexIndex + 2]].Side;

        DWORD LocalTriangleM1[6], LocalTriangleM2[6];
        LocalTriangleM2[0] = LocalTriangleM1[0] = VMap[I[IndexIndex + 0]].NVMap;
        LocalTriangleM2[1] = LocalTriangleM1[1] = VMap[I[IndexIndex + 1]].NVMap;
        LocalTriangleM2[2] = LocalTriangleM1[2] = VMap[I[IndexIndex + 2]].NVMap;

        UINT TriangleType = TSide[0] * 4 + TSide[1] * 2 + TSide[2] * 1;

        for(UINT EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
        {
            if(PerfectEdges[TriangleType][EdgeIndex])
            {
                Vec3f Vtx1 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][0]]].Pos;
                Vec3f Vtx2 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][1]]].Pos;
                Vec3f VtxIntersect = P.IntersectLine(Vtx1, Vtx2);
                
                if(!Vec3f::WithinRect(VtxIntersect, Rectangle3f::ConstructFromTwoPoints(Vtx1, Vtx2)))
                {
                    VtxIntersect = (Vtx1 + Vtx2) * 0.5f;
                }
                
                BoundaryVertices.PushEnd(Vec2f(Vec3f::Dot(VtxIntersect, OrthogonalBasis1), Vec3f::Dot(VtxIntersect, OrthogonalBasis2)));

                LocalTriangleM1[3 + EdgeIndex] = NewVertices[0].Length();
                BoundaryIndices[0].PushEnd(NewVertices[0].Length());
                NewVertices[0].PushEnd(VtxIntersect);

                LocalTriangleM2[3 + EdgeIndex] = NewVertices[1].Length();
                BoundaryIndices[1].PushEnd(NewVertices[1].Length());
                NewVertices[1].PushEnd(VtxIntersect);
            }
        }

        for(UINT LocalTriangleIndex = 0; LocalTriangleIndex < 6; LocalTriangleIndex += 3)
        {
            if(M1Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[0].PushEnd(Tri);
            }
            if(M2Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[1].PushEnd(Tri);
            }
        }
    }

#ifdef DELAUNAY_TRIANGULATOR
    if(BoundaryVertices.Length() > 0)
    {
        Vector<DWORD> BoundaryTriangulation;
        DelaunayTriangulator::Triangulate(BoundaryVertices, BoundaryTriangulation);
        for(UINT TriangleIndex = 0; TriangleIndex < BoundaryTriangulation.Length() / 3; TriangleIndex++)
        {
            for(UINT MeshIndex = 0; MeshIndex < 2; MeshIndex++)
            {
                TriMeshFace Tri;
                Vec3f V[3];
                for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++)
                {
                    Tri.I[LocalVertexIndex] = BoundaryIndices[MeshIndex][UINT(BoundaryTriangulation[TriangleIndex * 3 + LocalVertexIndex])];
                    V[LocalVertexIndex] = NewVertices[MeshIndex][UINT(Tri.I[LocalVertexIndex])];
                }
                //Utility::Swap(Tri.I[0], Tri.I[1]);
                //if(Math::TriangleArea(V[0], V[1], V[2]) > 1e-5f)
                {
                    NewFaces[MeshIndex].PushEnd(Tri);
                }
            }
        }
    }
#endif

    delete[] VMap;

    M1.SetGD(GetGD());
    M2.SetGD(GetGD());
    M1.Allocate(NewVertices[0].Length(), NewFaces[0].Length());
    M2.Allocate(NewVertices[1].Length(), NewFaces[1].Length());
    
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[0].Length(); VertexIndex++)
    {
        M1.Vertices()[VertexIndex].Pos = NewVertices[0][VertexIndex];
    }
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[1].Length(); VertexIndex++)
    {
        M2.Vertices()[VertexIndex].Pos = NewVertices[1][VertexIndex];
    }
    
    if(NewFaces[0].Length() > 0)
    {
        memcpy(M1.Indices(), NewFaces[0].CArray(), M1.IndexCount() * sizeof(DWORD));
    }
    if(NewFaces[1].Length() > 0)
    {
        memcpy(M2.Indices(), NewFaces[1].CArray(), M2.IndexCount() * sizeof(DWORD));
    }
}
Example #14
0
void D3D9Mesh::GenerateAdj(DWORD *& Adj)
{
    Adj = new DWORD[IndexCount()];
    PersistentAssert(Adj != NULL, "GenerateAdj failed");
    D3DAlwaysValidate(_Mesh->GenerateAdjacency(0.0f, Adj), "GenerateAdjacency");
}
Example #15
0
UINT64 BaseMesh::Hash64() const
{
    return Utility::Hash64((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) +
           Utility::Hash64((const BYTE *)Indices(), IndexCount() * sizeof(DWORD));
}
Example #16
0
void BaseMesh::TwoPatch()
{
    Vector<MeshVertex> NewVertices;    //list of new vertices in the mesh
    Vector<TriMeshFace> NewFaces;      //list of new faces in the mesh

    UINT vc = VertexCount(), ic = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<MeshTwoPatchEdge>* HashVertices = new Vector<MeshTwoPatchEdge>[vc];
    //HashVertices is a hash table that stores all edges incident on an edge.
    //a given edge's location in the hash table is HashVertices[Q], where Q is the index
    //of the smallest of the edge's two indices.
    
    DWORD LocalTIndices[6];     //we take each face and add 3 new vertices in the middle of each edge.
                                //LocalTIndices represents these 6 vertices (the 3 new ones and the 3 origional ones.)
                                //these 6 vertices then become 4 triangles that exactly match the origional triangle.

    DWORD VertexIndex;           //the index of the vertex we're looking for
    MeshVertex NewVertex;        //the new vertex we're going to add to the mesh
    TriMeshFace NewTriangle;     //the new triangle we're going to add to the mesh
    MeshTwoPatchEdge NewEdge;    //the edge we're going to add to the hash table

    for(UINT i = 0; i < vc; i++)
    {
        NewVertices.PushEnd(V[i]);    //all old vertices will be in the new mesh
    }

    for(UINT i = 0; i < ic; i+=3)
    {
        LocalTIndices[0] = I[i+0];
        LocalTIndices[1] = I[i+1];
        LocalTIndices[2] = I[i+2];    //the origional 3 triangles are always in LocalTIndices

        //now it remains to get the vertices at the middle of each edge
        //if these aren't already in the mesh we just add a new vertex to the final mesh, otherwise we need to use our hash table to find
        //their position in the mesh and use those indices.

        for(UINT i2=0;i2<3;i2++)
        {
            int EdgeVtx1, EdgeVtx2;    //the indices we're looking for
            if(i2 == 0)
            {
                EdgeVtx1 = I[i+0];
                EdgeVtx2 = I[i+1];
            }
            if(i2 == 1)
            {
                EdgeVtx1 = I[i+1];
                EdgeVtx2 = I[i+2];
            }
            if(i2 == 2)
            {
                EdgeVtx1 = I[i+0];
                EdgeVtx2 = I[i+2];
            }
            if(EdgeVtx2 < EdgeVtx1) Utility::Swap(EdgeVtx1, EdgeVtx2);    //we want EdgeVtx1 to be the smallest
            if(SearchTwoPatchEdge(HashVertices[EdgeVtx1], VertexIndex, EdgeVtx2))    //search for the corresponding edge to see if it's already in the mesh
            {
                LocalTIndices[3+i2] = VertexIndex;    //if it is we just choose the found index as our entry in LocalTIndices.  No need to add another vertex to the mesh; it's already there
            } else 
            {
                Interpolate(V[EdgeVtx1],V[EdgeVtx2],NewVertex,0.5f);    //otherwise make a new vertex at the middle of the edge,
                NewEdge.v2 = EdgeVtx2;
                NewEdge.v1 = NewVertices.Length();
                LocalTIndices[3+i2] = NewVertices.Length();        //this new vertex is our LocalTIndices entry
                HashVertices[EdgeVtx1].PushEnd(NewEdge);           //we need to add it to the hash table...
                NewVertices.PushEnd(NewVertex);                       //and add it to the new mesh
            }
        }

        //Now we have all 6 of our LocalTIndices.  This was one triangle in the origional mesh and is now 4 triangles in the new mesh.
        //we add those 4 new triangles now.

        NewTriangle.I[0] = LocalTIndices[0];
        NewTriangle.I[1] = LocalTIndices[3];
        NewTriangle.I[2] = LocalTIndices[5];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[3];
        NewTriangle.I[1] = LocalTIndices[1];
        NewTriangle.I[2] = LocalTIndices[4];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[5];
        NewTriangle.I[1] = LocalTIndices[4];
        NewTriangle.I[2] = LocalTIndices[2];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[5];
        NewTriangle.I[1] = LocalTIndices[3];
        NewTriangle.I[2] = LocalTIndices[4];
        NewFaces.PushEnd(NewTriangle);
    }

    for(UINT i = 0; i <vc; i++)
    {
        HashVertices[i].FreeMemory();
    }

    delete[] HashVertices;                //free the hash table up

    Allocate(NewVertices.Length(), NewFaces.Length());    //allocate space for the new mesh (deleting the old mesh)

    MeshVertex *VNew = Vertices();
    DWORD *INew = Indices();
    vc = VertexCount();
    ic = IndexCount();

    for(UINT i = 0; i < vc; i++)
    {
        VNew[i] = NewVertices[i];
    }

    for(UINT i = 0; i < ic / 3; i++)
    {
        INew[i * 3 + 0] = NewFaces[i].I[0];
        INew[i * 3 + 1] = NewFaces[i].I[1];
        INew[i * 3 + 2] = NewFaces[i].I[2];
    }
}
Example #17
0
void D3D9Mesh::GenerateAdj(Vector<DWORD> &Adjacency)
{
    Adjacency.Allocate(IndexCount());
    D3DAlwaysValidate(_Mesh->GenerateAdjacency(0.0f, Adjacency.CArray()), "GenerateAdjacency");
}