Пример #1
0
void AHair::UpdateSegment(AHairSegment* InSegment)
{
	if (!InSegment || InSegment->Spline->GetNumberOfSplinePoints() < 2) return;
	InSegment->ProceduralMesh->ClearAllMeshSections();
	ClearMeshData(InSegment);

	// Update node rotations to match spline
	for (int i = 0; i < InSegment->Spline->GetNumberOfSplinePoints(); i++)
	{
		FRotator Rot = InSegment->Spline->GetRotationAtSplinePoint(i, ESplineCoordinateSpace::World);
		InSegment->Nodes[i]->SetActorRotation(Rot);
	}

	// Populate new data
	if (!MiddleMeshData) return;
	for (int i = 0; i <= InSegment->NumSegments; i++)
	{
		float TotalDistance = InSegment->Spline->GetSplineLength();
		float Distance = (TotalDistance / InSegment->NumSegments)*i;
		float NextDistance = (TotalDistance / InSegment->NumSegments)*i+1;
		AssignPositions(InSegment->Spline->GetLocationAtDistanceAlongSpline(Distance, ESplineCoordinateSpace::Local),
			InSegment->Spline->GetLocationAtDistanceAlongSpline(NextDistance, ESplineCoordinateSpace::Local));

		//Weight = 1.0f - Distance / TotalDistance;
		
		float Displacement = InSegment->FallOff - 1.0f;
		Weight = 1.0f + (Distance / TotalDistance)*Displacement;

		// Interpolate distance to closest spline point index
		float Delta = ((InSegment->Spline->GetNumberOfSplinePoints() - 1)*1.0f) / (InSegment->NumSegments*1.0f);
		int Index = FGenericPlatformMath::RoundToInt(i*Delta);
		if (i == 0)
		{
			AddVertices(0, MiddleMeshData->Vertices, InSegment, Distance);
			AddTriangles(InSegment);
			AddUVs(InSegment, true);
		}
		else
		{
			AddVertices(2, MiddleMeshData->Vertices, InSegment, Distance);
			AddTriangles(InSegment);
			AddUVs(InSegment, false);
		}
	}
	// Create mesh 
	InSegment->ProceduralMesh->CreateMeshSection(0, InSegment->ProceduralMeshData->Vertices,
													InSegment->ProceduralMeshData->Triangles,
													TArray<FVector>(), 
													InSegment->ProceduralMeshData->UVs,
													TArray<FColor>(), TArray<FProcMeshTangent>(), true);
	// Duplicate for outline as custom depth not available for translucent materials
	InSegment->OutlineMesh->CreateMeshSection(0, InSegment->ProceduralMeshData->Vertices,
													InSegment->ProceduralMeshData->Triangles,
													TArray<FVector>(),
													InSegment->ProceduralMeshData->UVs,
													TArray<FColor>(), TArray<FProcMeshTangent>(), true);
}
Пример #2
0
void TriangleTesselationCache::AddQuads(const carray<Vec3f>& pos, const carray<Vec3f>& normal, const carray<Vec2f>& uv, const carray<Vec4i>& quads) {
    // check if they have normals
    if(!normal.empty()) {
        AddTriangles(pos, normal, uv, ElementOperations::QuadsToTriangles(quads));
    } else {
        carray<Vec4i> newQuads;
        ElementOperations::UnshareForFaceNormals(pos, 
            (!uv.empty())?uv:carray<Vec2f>(pos.size(),Vec2f(0,0)), 
            ElementOperations::QuadNormals(pos, quads),
            quads,
            this->pos, this->normal, this->uv, newQuads);
        this->triangles = ElementOperations::QuadsToTriangles(newQuads);
    }

    _UpdateBBox();
}
Пример #3
0
void Collision::Triangles(D3Dmodel* model, XMMATRIX world)
{
	AddTriangles(model->ModelAsTriangles(world));
}
Пример #4
0
  void Mesh::AddData(const Mesh& mesh, const ezTransform& transform)
  {
    ezMat4 transformMat = transform.GetAsMat4();
    ezMat4 normalTransformMat = transformMat.GetInverse(0.0f).GetTranspose();

    // Create new triangles.
    ezUInt32 oldTriangleCount = GetNumTriangles();
    AddTriangles(mesh.GetNumTriangles());

    ezArrayPtr<const Mesh::Triangle> sourceTriangles = mesh.GetTriangles();
    ezArrayPtr<const Mesh::Triangle> targetTriangles = GetTriangles().GetSubArray(oldTriangleCount);
    EZ_ASSERT_DEBUG(sourceTriangles.GetCount() == targetTriangles.GetCount(), "Something is wrong with triangle allocation!");

    for (auto it = mesh.m_VertexDataStreams.GetIterator(); it.IsValid(); ++it)
    {
      const VertexDataStream* sourceStream = it.Value();
      VertexDataStream* targetStream = AddDataStream(static_cast<ezGALVertexAttributeSemantic::Enum>(it.Key()),
                                                     sourceStream->GetNumElementsPerVertex(), sourceStream->GetElementType());
      if (!targetStream)
      {
        ezLog::SeriousWarning("Cannot merge mesh {0} properly since it has a vertex data stream with semantic {1} that uses {2} elements "
                              "instead of 'unkown' which is used by the merge target. Skipping this data stream.",
                              mesh.m_Name, it.Key(), sourceStream->GetNumElementsPerVertex());
        continue;
      }

      // Copy data.
      ezUInt32 targetBaseDataIndex = targetStream->m_Data.GetCount();
      targetStream->m_Data.PushBackRange(sourceStream->m_Data);

      // Transform data.
      if (!transform.IsIdentical(ezTransform::IdentityTransform()))
      {
        const ezUInt32 attributeSize = targetStream->GetAttributeSize();

        // Positions
        if (it.Key() == ezGALVertexAttributeSemantic::Position)
        {
          for (ezUInt32 i = targetBaseDataIndex; i < targetStream->m_Data.GetCount(); i += attributeSize)
          {
            ezVec3& pos = *reinterpret_cast<ezVec3*>(&targetStream->m_Data[i]);
            pos = transformMat.TransformPosition(pos);
          }
        }
        // Directions
        else if (it.Key() == ezGALVertexAttributeSemantic::Normal || it.Key() == ezGALVertexAttributeSemantic::Tangent ||
                 it.Key() == ezGALVertexAttributeSemantic::BiTangent)
        {
          for (ezUInt32 i = targetBaseDataIndex; i < targetStream->m_Data.GetCount(); i += attributeSize)
          {
            ezVec3& dir = *reinterpret_cast<ezVec3*>(&targetStream->m_Data[i]);
            dir = normalTransformMat.TransformDirection(dir);
          }
        }
      }

      // Set mapping
      for (ezUInt32 tri = 0; tri < sourceTriangles.GetCount(); ++tri)
      {
        for (int v = 0; v < 3; ++v)
        {
          VertexDataIndex sourceDataIndex = sourceStream->GetDataIndex(sourceTriangles[tri].m_Vertices[v]);
          if (sourceDataIndex.IsValid())
            targetStream->SetDataIndex(targetTriangles[tri].m_Vertices[v], targetBaseDataIndex + sourceDataIndex.GetValue());
        }
      }
    }

    // Add submeshes.
    ezUInt32 oldSubMeshCount = m_SubMeshes.GetCount();
    m_SubMeshes.PushBackRange(mesh.m_SubMeshes);
    for (ezUInt32 i = oldSubMeshCount; i < m_SubMeshes.GetCount(); ++i)
    {
      m_SubMeshes[i].m_uiFirstTriangle += oldTriangleCount;
    }

    // Add skeleton if existent
    // TODO: What if multiple, incompatible skeletons are found(?)
    // For now: Remove skeleton and import unskinned
    // if (mesh.m_pSkeleton)
    //{
    //  if (m_pSkeleton)
    //  {
    //    if (!m_pSkeleton->IsCompatibleWith(mesh.m_pSkeleton.Borrow()))
    //    {
    //      ezLog::Warning("Found incompatible skeletons during mesh merging in mesh '{0}', import will be without skeletons!",
    //      m_Name.GetData()); m_pSkeleton.Reset();
    //    }
    //  }
    //  else
    //  {
    //    m_pSkeleton = EZ_DEFAULT_NEW(ezSkeleton, *mesh.m_pSkeleton);
    //  }
    //}
  }