Exemplo n.º 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());
}
Exemplo n.º 2
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];
        }
    }
}
Exemplo n.º 3
0
void BaseMesh::RotateFaces()
{
    DWORD *_Indices = Indices();
    UINT _FaceCount = FaceCount();
    for(UINT FaceIndex = 0; FaceIndex < _FaceCount; FaceIndex++)
    {
        Utility::Swap(_Indices[FaceIndex * 3 + 0], _Indices[FaceIndex * 3 + 1]);
    }
    GenerateNormals();
}
Exemplo n.º 4
0
float BaseMesh::SidedSurfaceArea(const Plane &P)
{
    float Result = 0.0f;
    DWORD *MyIndices = Indices();
    MeshVertex *MyVertices = Vertices();
    UINT TriangleCount = FaceCount();
    for(UINT TriangleIndex = 0; TriangleIndex < TriangleCount; TriangleIndex++)
    {
        Vec3f LocalTriangle[6];
        UINT TSide[3];
        for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++)
        {
            LocalTriangle[LocalVertexIndex] = MyVertices[MyIndices[TriangleIndex * 3 + LocalVertexIndex]].Pos;
            if(Plane::DotCoord(P, LocalTriangle[LocalVertexIndex]) < 0.0f)
            {
                TSide[LocalVertexIndex] = 0;
            }
            else
            {
                TSide[LocalVertexIndex] = 1;
            }
        }
        UINT TriangleType = TSide[0] * 4 + TSide[1] * 2 + TSide[2] * 1;

        for(UINT EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
        {
            if(PerfectEdges[TriangleType][EdgeIndex])
            {
                Vec3f Vtx1 = MyVertices[MyIndices[TriangleIndex * 3 + PerfectEdgeList[EdgeIndex][0]]].Pos;
                Vec3f Vtx2 = MyVertices[MyIndices[TriangleIndex * 3 + PerfectEdgeList[EdgeIndex][1]]].Pos;
                Vec3f VtxIntersect = P.IntersectLine(Vtx1, Vtx2);
                if(!Vec3f::WithinRect(VtxIntersect, Rectangle3f::ConstructFromTwoPoints(Vtx1, Vtx2)))
                {
                    VtxIntersect = (Vtx1 + Vtx2) * 0.5f;
                }
                
                LocalTriangle[3 + EdgeIndex] = VtxIntersect;
            }
        }

        for(UINT LocalTriangleIndex = 0; LocalTriangleIndex < 6; LocalTriangleIndex += 3)
        {
            if(M1Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                Vec3f V[3];
                V[0] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 0]];
                V[1] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 1]];
                V[2] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 2]];
                Result += Math::TriangleArea(V[0], V[1], V[2]);
            }
        }
    }
    return Result;
}
Exemplo n.º 5
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];
        }
    }
}
	inline storage load_dds(const std::vector<char>& content) {
		std::stringstream FileIn(std::string(content.data(), content.size()));
		assert(!FileIn.fail());

		if(FileIn.fail())
			return storage();

		detail::ddsHeader HeaderDesc;
		detail::ddsHeader10 HeaderDesc10;
		char Magic[4];

		//* Read magic number and check if valid .dds file
		FileIn.read((char*)&Magic, sizeof(Magic));

		assert(strncmp(Magic, "DDS ", 4) == 0);

		// Get the surface descriptor
		FileIn.read((char*)&HeaderDesc, sizeof(HeaderDesc));
		if(HeaderDesc.format.flags & detail::DDPF_FOURCC && HeaderDesc.format.fourCC == detail::D3DFMT_DX10)
			FileIn.read((char*)&HeaderDesc10, sizeof(HeaderDesc10));

		gli::format Format(gli::FORMAT_NULL);
		if(HeaderDesc.format.fourCC == detail::D3DFMT_DX10)
			Format = detail::format_dds2gli_cast(HeaderDesc10.Format);
		else if(HeaderDesc.format.flags & detail::DDPF_FOURCC)
			Format = detail::format_fourcc2gli_cast(HeaderDesc.format.flags, HeaderDesc.format.fourCC);
		else if(HeaderDesc.format.flags & detail::DDPF_RGB)
		{
			switch(HeaderDesc.format.bpp)
			{
			case 8:
				Format = R8_UNORM;
				break;
			case 16:
				Format = RG8_UNORM;
				break;
			case 24:
				Format = RGB8_UNORM;
				break;
			case 32:
				Format = RGBA8_UNORM;
				break;
			}
		}
		else
			assert(0);

		std::streamoff Curr = FileIn.tellg();
		FileIn.seekg(0, std::ios_base::end);
		std::streamoff End = FileIn.tellg();
		FileIn.seekg(Curr, std::ios_base::beg);

		storage::size_type const MipMapCount = (HeaderDesc.flags & detail::DDSD_MIPMAPCOUNT) ?
			HeaderDesc.mipMapLevels : 1;

		storage::size_type FaceCount(1);
		if(HeaderDesc.cubemapFlags & detail::DDSCAPS2_CUBEMAP)
			FaceCount = int(glm::bitCount(HeaderDesc.cubemapFlags & detail::DDSCAPS2_CUBEMAP_ALLFACES));

		storage::size_type DepthCount = 1;
		if(HeaderDesc.cubemapFlags & detail::DDSCAPS2_VOLUME)
				DepthCount = HeaderDesc.depth;

		storage Storage(
			HeaderDesc10.arraySize,
			FaceCount,
			MipMapCount,
			Format,
			storage::dimensions_type(HeaderDesc.width, HeaderDesc.height, DepthCount));

		FileIn.read((char*)Storage.data(), std::size_t(End - Curr));

		return Storage;
	}
Exemplo n.º 7
0
void D3D9Mesh::SimplifyToPercentFaces(float NewPercent)
{
    SimplifyToFaces(UINT(FaceCount() * NewPercent));
}
Exemplo n.º 8
0
ON_SubD* ON_SubDSectorType::SectorRingSubD(
  double radius,
  double sector_angle_radians,
  ON_SubD* subd
  ) const
{
  if (subd)
    *subd = ON_SubD::Empty;

  if (!IsValid())
    return ON_SUBD_RETURN_ERROR(nullptr);

  const unsigned int R = PointRingCount();
  if (R < 3)
    return ON_SUBD_RETURN_ERROR(nullptr);

  const unsigned int F = FaceCount();
  if ( F < 1)
    return ON_SUBD_RETURN_ERROR(nullptr);

  const unsigned int N = EdgeCount();
  if (N < 2)
    return ON_SUBD_RETURN_ERROR(nullptr);

  if (F != N && F + 1 != N)
    return ON_SUBD_RETURN_ERROR(nullptr);

  const ON_SubD::SubDType subdivision_type = SubDType();
  const ON_SubD::VertexTag vertex_tag = VertexTag();

  const unsigned f_edge_count = ON_SubD::FacetEdgeCount(subdivision_type);
  if (3 != f_edge_count && 4 != f_edge_count)
    return ON_SUBD_RETURN_ERROR(nullptr);

  const unsigned int ring_ei_delta = f_edge_count - 2;

  if (nullptr == subd)
    subd = new ON_SubD;

  ON_SubD::VertexTag vertex_tag0;
  ON_SubD::VertexTag vertex_tag1;
  ON_SubD::EdgeTag edge_tag0;
  ON_SubD::EdgeTag edge_tag1;

  switch (vertex_tag)
  {
  case ON_SubD::VertexTag::Smooth:
    sector_angle_radians = 2.0*ON_PI;
    vertex_tag0 = ON_SubD::VertexTag::Smooth;
    vertex_tag1 = ON_SubD::VertexTag::Smooth;
    edge_tag0 = ON_SubD::EdgeTag::Smooth;
    edge_tag1 = ON_SubD::EdgeTag::Smooth;
    break;

  case ON_SubD::VertexTag::Crease:
    if ( !(sector_angle_radians > 0.0 && sector_angle_radians < 2.0*ON_PI) )
      sector_angle_radians = 0.5*ON_PI;
    vertex_tag0 = ON_SubD::VertexTag::Crease;
    vertex_tag1 = ON_SubD::VertexTag::Crease;
    edge_tag0 = ON_SubD::EdgeTag::Crease;
    edge_tag1 = ON_SubD::EdgeTag::Crease;
    break;

  case ON_SubD::VertexTag::Corner:
    sector_angle_radians = CornerSectorAngleRadians();
    vertex_tag0 = ON_SubD::VertexTag::Crease;
    vertex_tag1 = ON_SubD::VertexTag::Crease;
    edge_tag0 = ON_SubD::EdgeTag::Crease;
    edge_tag1 = ON_SubD::EdgeTag::Crease;
    break;

  case ON_SubD::VertexTag::Dart:
    sector_angle_radians = 2.0*ON_PI;
    vertex_tag0 = ON_SubD::VertexTag::Crease;
    vertex_tag1 = ON_SubD::VertexTag::Smooth;
    edge_tag0 = ON_SubD::EdgeTag::Crease;
    edge_tag1 = ON_SubD::EdgeTag::Smooth;
    break;

  default:
    return ON_SUBD_RETURN_ERROR(nullptr);
    break;
  }

  unsigned int sector_angle_index = ON_SubDSectorType::AngleIndexFromAngleRadians(sector_angle_radians);
  if (sector_angle_index <= ON_SubDSectorType::MaximumAngleIndex
    && fabs(ON_SubDSectorType::AngleRadiansFromAngleIndex(sector_angle_index) - sector_angle_radians) <= 1.0e-6
    )
  {
    sector_angle_radians = ON_SubDSectorType::AngleRadiansFromAngleIndex(sector_angle_index);
  }
  else
  {
    sector_angle_radians = ON_UNSET_UINT_INDEX;
  }
  
  const double smooth_edge_w0 = this->SectorWeight();

  ON_SimpleArray< ON_SubDVertex* > V(R);
  ON_SimpleArray< ON_SubDEdge* > E(N);

  ON_3dPoint vertexP = ON_3dPoint::Origin;

  for (unsigned int vi = 0; vi < R; vi++)
  {
    ON_SubD::VertexTag vertex_tag_vi;
    if ( 0 == vi )
      vertex_tag_vi = vertex_tag; // center vertex
    else if ( 1 == vi )
      vertex_tag_vi = vertex_tag0; // first edge
    else if ( R == vi+1 && N > F )
      vertex_tag_vi = vertex_tag1; // last edge
    else
      vertex_tag_vi = ON_SubD::VertexTag::Smooth; // interior edge or an outer face vertex

    if (radius > 0.0)
    {
      double cos_a, sin_a;
      if (sector_angle_index == ON_UNSET_UINT_INDEX)
      {
        double a = (vi / ((double)(R-1)))*sector_angle_radians;
        cos_a = cos(a);
        sin_a = sin(a);
      }
      else
      {
        ON_SubDMatrix::EvaluateCosAndSin(2*sector_angle_index*vi, (R-1)*ON_SubDSectorType::MaximumAngleIndex,&cos_a,&sin_a);
      }
      const double r = (3 == f_edge_count) || (1 == (vi%2)) ? radius : (2.0*radius);
      vertexP.x = r*cos_a;
      vertexP.y = r*sin_a;
    }
    ON_SubDVertex* vertex = subd->AddVertex( vertex_tag_vi, vertexP);
    V.Append(vertex);
  }
  //V[0]->m_vertex_edge_order = ON_SubD::VertexEdgeOrder::radial;
  
  for (unsigned int vei = 0; vei < N; vei++)
  {
    ON_SubD::EdgeTag edge_tag_vei;
    if ( 0 == vei )
      edge_tag_vei = edge_tag0; // first edge
    else if ( vei+1 == N )
      edge_tag_vei = edge_tag1; // last edge
    else
      edge_tag_vei = ON_SubD::EdgeTag::Smooth; // interior edge

    double w0 = (ON_SubD::EdgeTag::Smooth == edge_tag_vei) ? smooth_edge_w0 : ON_SubDSectorType::IgnoredSectorWeight;
    unsigned int ev1i = 1 + vei*ring_ei_delta;
    E.Append(
      subd->AddEdgeWithSectorCoefficients(
        edge_tag_vei,
        V[0], w0,
        V[ev1i], ON_SubDSectorType::IgnoredSectorWeight)
        );
  }

  ON_SubDVertex* f_vertex[4] = {};
  ON_SubDEdge* f_edge[4] = {};
  ON_SubDEdgePtr f_edgeptr[4] = {};

  f_vertex[0] = V[0];
  f_vertex[f_edge_count - 1] = const_cast<ON_SubDVertex*>(E[0]->m_vertex[1]);
  f_edge[f_edge_count - 1] = E[0];
  for (unsigned int vfi = 0; vfi < F; vfi++)
  {
    f_edge[0] = f_edge[f_edge_count - 1];
    f_edge[f_edge_count-1] = E[(vfi + 1) % N];
    f_vertex[1] = const_cast<ON_SubDVertex*>(f_edge[0]->m_vertex[1]);
    f_vertex[f_edge_count - 1] = const_cast<ON_SubDVertex*>(f_edge[f_edge_count - 1]->m_vertex[1]);

    f_edgeptr[0] = ON_SubDEdgePtr::Create(f_edge[0], 0);
    f_edgeptr[f_edge_count - 1] = ON_SubDEdgePtr::Create(f_edge[f_edge_count - 1], 1);
    if (4 == f_edge_count)
    {
      f_vertex[2] = V[2 + 2 * vfi];
      f_edge[1] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[1], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight);
      f_edge[2] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[3], ON_SubDSectorType::IgnoredSectorWeight);
      f_edgeptr[1] = ON_SubDEdgePtr::Create(f_edge[1], 0);
      f_edgeptr[2] = ON_SubDEdgePtr::Create(f_edge[2], 0);
    }
    else
    {
      f_edge[1] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[1], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight);
      f_edgeptr[1] = ON_SubDEdgePtr::Create(f_edge[1], 0);
    }
    subd->AddFace(f_edge_count, f_edgeptr);
  }

  return subd;
}
Exemplo n.º 9
0
void BaseMesh::CreateClosedCylinder(float radius, float height, UINT slices, UINT stacks)
{
    //this code is almost identical to CreateCylinder(radius, height slices, stacks) except it 
    //adds on a cap (like CreateLantern.)
    Allocate(slices * (stacks + 1),2 * stacks * slices + 2*(slices-2));
    
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    float Theta;

    int vc=0,ic=0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(UINT i=0;i <= stacks;i++)
    {
        for(UINT i2=0;i2 < slices;i2++)
        {
            Theta = float(i2+0.5f*i) * PI2_Slices;
            MVtx.Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), height * (float(i) / stacks - 0.5f));
            V[vc++] = MVtx;
        }
    }

    for(UINT i=0;i < FaceCount();i++)
    {
        I[i*3+0] = 0;
        I[i*3+1] = 1;
        I[i*3+2] = 2;
    }

    for(UINT i=0;i < stacks-1;i++)
        for(UINT i2=0;i2 < slices;i2++)
        {
            UINT i2m1 = i2 - 1;
            if(i2m1 == -1) i2m1 = slices-1;
            
            I[ic++] = i * slices + i2;
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = (i+1) * slices + i2m1;
            
            I[ic++] = (i+1) * slices + i2m1;
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = (i+2) * slices + i2m1;
        }

    UINT i = 0;
    for(UINT i2=0;i2 < slices;i2++)
    {
        UINT i2m1 = i2 - 1;
        if(i2m1 == -1)
        {
            i2m1 = slices-1;
        }

        I[ic++] = i * slices + i2m1;
        I[ic++] = i * slices + i2;
        I[ic++] = (i+1) * slices + i2m1;
    }

    i = stacks - 1;
    for(UINT i2 = 0; i2 < slices; i2++)
    {
        UINT i2m1 = i2 - 1;
        if(i2m1 == -1)
        {
            i2m1 = slices-1;
        }

        I[ic++] = (i+1) * slices + i2m1;
        I[ic++] = i * slices + i2;
        I[ic++] = (i+1) * slices + i2;
    }

    i = 0;
    for(UINT i2 = 1; i2 < slices - 1; i2++)
    {
        I[ic++] = i * slices + 0;
        I[ic++] = i * slices + i2+1;
        I[ic++] = i * slices + i2;
    }

    i = stacks;
    for(UINT i2 = 1; i2 < slices - 1; i2++)
    {
        I[ic++] = i * slices + 0;
        I[ic++] = i * slices + i2;
        I[ic++] = i * slices + i2+1;
    }

    GenerateNormals();
}
Exemplo n.º 10
0
void BaseMesh::CreateLantern(float radius, float height, UINT slices, UINT stacks)
{
    //this code is almost identical to CreateCylinder(radius, height slices, stacks) except it flips all non-border
    //edges; this is a much worse triangulation of the surface and does not behave well numerically (which was the
    //goal for the project I was working on at the time.)
    //it also has a cap on the top/bottom.

    Allocate(slices * (stacks + 1),2 * stacks * slices + 2*(slices-2));
    
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    float Theta;

    int vc=0, ic=0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(UINT i = 0; i <= stacks; i++)
    {
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Theta = float(i2+0.5f*i) * PI2_Slices;
            MVtx.Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), height * (float(i) / stacks - 0.5f));
            V[vc++] = MVtx;
        }
    }

    for(UINT i = 0; i < FaceCount(); i++)
    {
        I[i*3+0] = 0;
        I[i*3+1] = 1;
        I[i*3+2] = 2;
    }

    int i2m1;
    for(UINT i = 0; i < stacks - 1; i++)
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            i2m1 = int(i2) - 1;
            if(i2m1 == -1) i2m1 = slices-1;
            
            I[ic++] = i * slices + i2;
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = (i+2) * slices + i2m1;
            
            I[ic++] = i * slices + i2;
            I[ic++] = (i+2) * slices + i2m1;
            I[ic++] = (i+1) * slices + i2m1;
        }

    UINT i = 0;
    for(UINT i2 = 0; i2 < slices; i2++)
    {
        i2m1 = i2 - 1;
        if(i2m1 == -1) i2m1 = slices-1;

        I[ic++] = i * slices + i2m1;
        I[ic++] = i * slices + i2;
        I[ic++] = (i+1) * slices + i2m1;
    }

    i = stacks - 1;
    for(UINT i2 = 0; i2 < slices; i2++)
    {
        i2m1 = i2 - 1;
        if(i2m1 == -1)
        {
            i2m1 = slices - 1;
        }

        I[ic++] = (i + 1) * slices + i2m1;
        I[ic++] = i * slices + i2;
        I[ic++] = (i + 1) * slices + i2;
    }

    i = 0;
    for(UINT i2 = 1; i2 < slices - 1; i2++)
    {
        I[ic++] = i * slices + 0;
        I[ic++] = i * slices + i2 + 1;
        I[ic++] = i * slices + i2;
    }

    i = stacks;
    for(UINT i2 = 1; i2 < slices - 1; i2++)
    {
        I[ic++] = i * slices + 0;
        I[ic++] = i * slices + i2;
        I[ic++] = i * slices + i2 + 1;
    }

    GenerateNormals();
}