示例#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());
}
void BaseMesh::TextureSphericalMap(int variable)
{
    int i;

    //spherical coordinates have two angles.  This function computes
    //these angles for each vertex and maps these angles into tx and ty.
    //variable exists for the same reason as TextureMapToNormals
    
    int vc = VertexCount();
    MeshVertex *V = Vertices();

    Vec3f Pos;

    for(i=0;i<vc;i++)
    {
        if(variable == 0)
            Pos = Vec3f(V[i].Pos.x,V[i].Pos.y,V[i].Pos.z);

        if(variable == 1)
            Pos = Vec3f(V[i].Pos.x,V[i].Pos.z,V[i].Pos.y);

        V[i].TexCoord.x = (atan2f(Pos.y,Pos.x) + Math::PIf) / (2.0f * Math::PIf);
        V[i].TexCoord.y = 1.0f - (atan2f(Pos.z,sqrtf(Pos.y * Pos.y + Pos.x * Pos.x)) + Math::PIf / 2.0f) / Math::PIf;
    }
}
示例#3
0
void GeneralMesh::AppendQuadIndex()
{
	uint indexBegin = static_cast<uint>(VertexCount()) - 4;
	uint indices[6] = { indexBegin, indexBegin + 1, indexBegin + 2, indexBegin + 2, indexBegin + 3, indexBegin };
	AppendIndices(indices, 6);

}
示例#4
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;
}
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();
}
示例#6
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();
    }
}
void BaseMesh::ColorNormalsGrayScale(RGBColor Color)
{
    int i,vc = VertexCount();
    MeshVertex *V = Vertices();

    for(i=0;i<vc;i++)
    {
        Vec3f normal = V[i].Normal;
        int r = Utility::Bound(int(Math::Abs(normal.x/2.0f+0.5f)*255), 0, 255);
        int g = Utility::Bound(int(Math::Abs(normal.y/2.0f+0.5f)*255), 0, 255);
        int b = Utility::Bound(int(Math::Abs(normal.z/2.0f+0.5f)*255), 0, 255);    //remap each normal's (x, y, z) to (r, g, b)

        const bool UseMaximumValue = false;
        if(UseMaximumValue)
        {
            if(g > r) r = g;
            if(b > r) r = b;
        }
        else
        {
            r = (r + g + b) / 3;        //merge the 3 values into one value via some method
        }
        V[i].Color = RGBColor(r / 255.0f * Vec3f(Color));
    }
}
示例#8
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();
}
示例#9
0
void BaseMesh::CleanVerticesAndTriangles(Vector<UINT> &OldToNewMapping)
{
    UINT NumFaces = FaceCount(), NumVertices = VertexCount();
    DWORD *I = Indices();
    MeshVertex *V = Vertices();

    Vector<DWORD> NewIndices;
    Vector<MeshVertex> NewVertices;
    OldToNewMapping.ReSize(NumVertices);
    OldToNewMapping.Clear(NumVertices);
    
    for(UINT FaceIndex = 0; FaceIndex < NumFaces; FaceIndex++)
    {
        if(I[FaceIndex * 3 + 0] != I[FaceIndex * 3 + 1] &&
           I[FaceIndex * 3 + 1] != I[FaceIndex * 3 + 2] &&
           I[FaceIndex * 3 + 2] != I[FaceIndex * 3 + 0])
        {
            for(UINT i = 0; i < 3; i++)
            {
                UINT SourceIndex = I[FaceIndex * 3 + i];
                if(OldToNewMapping[SourceIndex] == NumVertices)
                {
                    OldToNewMapping[SourceIndex] = NewVertices.Length();
                    NewVertices.PushEnd(V[SourceIndex]);
                }
                NewIndices.PushEnd(OldToNewMapping[SourceIndex]);
            }
        }
    }
    Allocate(NewVertices.Length(), NewIndices.Length() / 3);
    NumFaces = FaceCount();
    NumVertices = VertexCount();
    I = Indices();
    V = Vertices();
    for(UINT VertexIndex = 0; VertexIndex < NumVertices; VertexIndex++)
    {
        V[VertexIndex] = NewVertices[VertexIndex];
    }
    for(UINT FaceIndex = 0; FaceIndex < NumFaces; FaceIndex++)
    {
        for(UINT i = 0; i < 3; i++)
        {
            I[FaceIndex * 3 + i] = NewIndices[FaceIndex * 3 + i];
        }
    }
}
void BaseMesh::RandomizeColors()
{
    int i,vc=VertexCount();
    MeshVertex *V = Vertices();
    for(i=0;i<vc;i++)
    {
        V[i].Color = RGBColor::RandomColor();
    }
}
void BaseMesh::Translate(const Vec3f &v)
{
    UINT vc = VertexCount();
    MeshVertex *V = Vertices();

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Pos += v;
    }
}
void BaseMesh::SetAlpha(BYTE Alpha)
{
    MeshVertex *V = Vertices();
    UINT vc = VertexCount();

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Color.a = Alpha;
    }
}
void BaseMesh::ApplyMatrix(const Matrix4 &M)
{
    UINT vc = VertexCount();
    MeshVertex *V = Vertices();

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Pos = M.TransformPoint(V[i].Pos);
        V[i].Normal = M.TransformNormal(V[i].Normal);
    }
}
void BaseMesh::Stretch(const Vec3f &v)
{
    UINT vc = VertexCount();
    MeshVertex *V = Vertices();

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Pos.x *= v.x;
        V[i].Pos.y *= v.y;
        V[i].Pos.z *= v.z;
    }
}
示例#15
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]];
    }
}
void BaseMesh::NormalizeNormals()
{
    UINT vc = VertexCount();
    MeshVertex *V = Vertices();

    for(UINT i = 0; i < vc; i++)
    {
        if(V[i].Normal.LengthSq() != 0.0f)
        {
            V[i].Normal = Vec3f::Normalize(V[i].Normal);
        }
    }
}
示例#17
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);
}
示例#18
0
void BaseMesh::CullFaces(const BYTE FaceTest[])
{
    Vector<DWORD> NewIndices;
    Vector<MeshVertex> NewVertices;
    UINT NumFaces = FaceCount(), NumVertices = VertexCount();
    DWORD *I = Indices();
    MeshVertex *V = Vertices();
    for(UINT VertexIndex = 0; VertexIndex < NumVertices; VertexIndex++)
    {
        NewVertices.PushEnd(V[VertexIndex]);
    }
    for(UINT FaceIndex = 0; FaceIndex < NumFaces; FaceIndex++)
    {
        if(FaceTest[FaceIndex])
        {
            for(UINT i = 0; i < 3; i++)
            {
                NewIndices.PushEnd(I[FaceIndex * 3 + i]);
            }
        }
    }
    Allocate(NewVertices.Length(), NewIndices.Length() / 3);
    NumFaces = FaceCount();
    NumVertices = VertexCount();
    I = Indices();
    V = Vertices();
    for(UINT VertexIndex = 0; VertexIndex < NumVertices; VertexIndex++)
    {
        V[VertexIndex] = NewVertices[VertexIndex];
    }
    for(UINT FaceIndex = 0; FaceIndex < NumFaces; FaceIndex++)
    {
        for(UINT i = 0; i < 3; i++)
        {
            I[FaceIndex * 3 + i] = NewIndices[FaceIndex * 3 + i];
        }
    }
}
void BaseMesh::ColorNormals(float fr, float fg, float fb)
{
    int i,vc=VertexCount();
    MeshVertex *V = Vertices();

    for(i=0;i<vc;i++)
    {
        Vec3f Normal = V[i].Normal;
        int r = int((Normal.x/2.0f+0.5f)*255*fr);
        int g = int((Normal.y/2.0f+0.5f)*255*fg);
        int b = int((Normal.z/2.0f+0.5f)*255*fb);    //remap each normal's (x, y, z) to (r, g, b)
        V[i].Color = RGBColor(r,g,b);
    }
}
示例#20
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
}
void BaseMesh::SetColor(RGBColor Color)
{
    MeshVertex *V = Vertices();
    UINT vc = VertexCount();

    //
    // rgba to bgra
    //
    Color = Color.FlipBlueAndRed();

    for(UINT i = 0; i < vc; i++)
    {
        V[i].Color = Color;
    }
}
示例#22
0
void GeneralMesh::AppendQuad(const QuadTextureNormalVertex& quad)
{
	mVertices.Append(quad.LeftBottom.Position);
	mVertices.Append(quad.RightBottom.Position);
	mVertices.Append(quad.RightTop.Position);
	mVertices.Append(quad.LeftTop.Position);
	OnVertexChanged(4);

	mNormals.Append(quad.LeftBottom.Normal);
	mNormals.Append(quad.RightBottom.Normal);
	mNormals.Append(quad.RightTop.Normal);
	mNormals.Append(quad.LeftTop.Normal);
	OnNormalChanged();

	mTexcoords.Append(quad.LeftBottom.Texcoord);
	mTexcoords.Append(quad.RightBottom.Texcoord);
	mTexcoords.Append(quad.RightTop.Texcoord);
	mTexcoords.Append(quad.LeftTop.Texcoord);
	OnTexcoordChanged();

	mColors.Append(quad.LeftBottom.Color);
	if (!Math::IsEqual(quad.LeftBottom.Color.A, 1.f))
	{
		mHasAlpha = true;
	}
	mColors.Append(quad.RightBottom.Color);
	if (!Math::IsEqual(quad.RightBottom.Color.A, 1.f))
	{
		mHasAlpha = true;
	}
	mColors.Append(quad.RightTop.Color);
	if (!Math::IsEqual(quad.RightTop.Color.A, 1.f))
	{
		mHasAlpha = true;
	}
	mColors.Append(quad.LeftTop.Color);
	if (!Math::IsEqual(quad.LeftTop.Color.A, 1.f))
	{
		mHasAlpha = true;
	}
	OnColorChanged();

	uint indexBegin = static_cast<uint>(VertexCount()) - 4;
	uint indices[6] = { indexBegin, indexBegin + 1, indexBegin + 2, indexBegin + 2, indexBegin + 3, indexBegin };
	mIndices.AppendRange(indices, 6);
	OnIndexChanged();
}
示例#23
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();

}
示例#24
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();
}
void BaseMesh::TextureMapToNormals(int variable)
{
    int i,vc = VertexCount();
    MeshVertex *V = Vertices();

    //remap the normals into texture coordinates
    //there are three normal components (x, y, z) and only two texture coordinates (x, y),
    //so variable tells us which normal component not to map.

    for(i=0;i<vc;i++)
    {
        if(variable == 0)
        {
            V[i].TexCoord.x = (V[i].Normal.y + 1.0f) / 2.0f;
            V[i].TexCoord.y = (V[i].Normal.z + 1.0f) / 2.0f;
        } else if(variable == 1) {
            V[i].TexCoord.x = (V[i].Normal.x + 1.0f) / 2.0f;
            V[i].TexCoord.y = (V[i].Normal.z + 1.0f) / 2.0f;
        } else {
            V[i].TexCoord.x = (V[i].Normal.x + 1.0f) / 2.0f;
            V[i].TexCoord.y = (V[i].Normal.y + 1.0f) / 2.0f;
        }
    }
}
示例#26
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));
    }
}
示例#27
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];
    }
}
示例#28
0
//-----------------------------------------------------------------------------
// Marks the dictionary as starting defining vertices for a new LOD
//-----------------------------------------------------------------------------
void CVertexDictionary::StartNewLOD()
{
	m_nPrevLODCount = VertexCount();
}
示例#29
0
UINT64 BaseMesh::Hash64() const
{
    return Utility::Hash64((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) +
           Utility::Hash64((const BYTE *)Indices(), IndexCount() * sizeof(DWORD));
}
示例#30
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));
}