SharpDX 2.6으로로드 된 모델에서 볼록 선체 및 삼각형 메시를 만드는 중입니다.SharpDX 툴킷 모델에서 정점 및 삼각형 데이터 추출
모델에서 꼭지점과 인덱스를 추출하는 데 필요한 몇 가지 예제 코드를 발견했지만 XNA와 DirectX 9를 기반으로합니다. 내 프로그램에서 DirectX 11 (및 SharpDX 도구 키트)과 함께 SharpDX를 사용하고 있습니다. , 많은 것들이 XNA와 비슷합니다).
코드 나는 (삼각형)을 정점과 인덱스를 추출 발견했습니다 I :
여기public void ExtractData(List<JVector> vertices, List<JOctree.TriangleVertexIndices> indices, Model model)
{
Matrix[] bones_ = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(bones_);
foreach (ModelMesh mm in model.Meshes)
{
Matrix xform = bones_[mm.ParentBone.Index];
foreach (ModelMeshPart mmp in mm.MeshParts)
{
int offset = vertices.Count;
Vector3[] a = new Vector3[mmp.NumVertices];
mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,
a, 0, mmp.NumVertices, mmp.VertexStride);
for (int i = 0; i != a.Length; ++i)
Vector3.Transform(ref a[i], ref xform, out a[i]);
for (int i = 0; i < a.Length; i++) vertices.Add(new JVector(a[i].X, a[i].Y, a[i].Z));
if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
throw new Exception(
String.Format("Model uses 32-bit indices, which are not supported."));
short[] s = new short[mmp.PrimitiveCount * 3];
mm.IndexBuffer.GetData<short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
JOctree.TriangleVertexIndices[] tvi = new JOctree.TriangleVertexIndices[mmp.PrimitiveCount];
for (int i = 0; i != tvi.Length; ++i)
{
tvi[i].I0 = s[i * 3 + 2] + offset;
tvi[i].I1 = s[i * 3 + 1] + offset;
tvi[i].I2 = s[i * 3 + 0] + offset;
}
indices.AddRange(tvi);
}
}
}
내가 (SharpDX 툴킷 쉽게 다이렉트 X 11)로 재 작업 할 수있었습니다 무엇 모델에서 옥트리를 간단히 짓는 것으로 일반화했지만, 파이프 라인의 메인 덩어리는 여전히 동일합니다. 이 코드의 변형을 사용하고
public static Octree BuildOctree(Model model) {
List<JVector> vertices = new List<JVector>();
List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>();
Matrix[] bones = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(bones);
foreach (ModelMesh modelMesh in model.Meshes)
{
JMatrix boneTransform = PhysicsSystem.toJMatrix(bones[modelMesh.ParentBone.Index]);
foreach (ModelMeshPart meshPart in modelMesh.MeshParts)
{
int offset = vertices.Count;
var meshVertices = meshPart.VertexBuffer.Resource.Buffer.GetData<JVector>();
for (int i = 0; i < meshVertices.Length; ++i)
{
JVector.Transform(ref meshVertices[i], ref boneTransform, out meshVertices[i]);
}
vertices.AddRange(meshVertices); // append transformed vertices
var indexElements = meshPart.IndexBuffer.Resource.GetData<short>(); // this is dangerous if the model uses larger integers
// Each TriangleVertexIndices holds the indices that constitute a triangle primitive
TriangleVertexIndices[] tvi = new TriangleVertexIndices[indexElements.Length];
for (int i = 0; i <= tvi.Length - 2; i += 3) {
tvi[i].I0 = indexElements[i + 0] + offset;
tvi[i].I1 = indexElements[i + 1] + offset;
tvi[i].I2 = indexElements[i + 2] + offset;
}
indices.AddRange(tvi); // append triangles
}
}
Octree ot = new Octree(vertices, indices);
//ot.BuildOctree(); // (already happens in Octree constructor)
return ot;
}
(삼각형 계산 단지 정점없이) 유사한 방식으로 볼록 선체 형상을 생성한다.
내 질문은 : 이 코드를 향상시킬 수있는 방법이 있습니까?
이 코드가 맞습니까? 즉각적으로 잘못된 것으로 간주되는 것이 있습니까?
이 메서드를 사용하여 상자 모델 (지터 자습서에서 사용한 것과 동일한 모델)에서 꼭지점을 추출 할 때 상당히 모양이 균일하지 않은 상자가 아닌 표현을 얻습니다. (BoxShape를 사용하는 경우 60fps, 고정 TerrainShape와 충돌하는 단일 상자를 사용하는 경우 ~ 20-30)를 사용하는 것보다 훨씬 더 많은 충돌이 발생합니다. 왜 이것이 사실일까요?
필자의 코드 재 작성이 약간의 출력을 생성하지만, 전혀 느껴지지 않는다.
답변 xoofx를 주셔서 감사합니다. Jitter Physics의 ConvexHullShape()를 구성하기 위해 꼭지점 목록을 구성하는 작업이 있다면 어떻게할까요? https://code.google.com/p/jitterphysics/source/browse/trunk : 이 지터 사용 XNA에서 예 (I 주로 실제로 SharpDX을 개발 한 사람으로부터 통찰력이 요청은) 아래에 연결되어 있습니다 /JitterDemo/JitterDemo/PhysicsObjects/ConvexHullObject.cs 그들이하는 방식과 이것이 SharpDX 솔루션으로 가장 잘 변환되는 방법에 동의합니까? 감사합니다. – lberezy
완벽한 솔루션을 작성할 시간이 없지만 기본적으로 아이디어입니다. XNA 버전과의 차이점은 XNA GetData가 정점 스트림의 일부를 얻을 수 있지만 SharpDX를 사용하면 올바른 정점 요소에 대한 오프셋을 계산하고이를 해독하기 위해 원시 버퍼를 반복해야한다는 것입니다. 코드는 작성하는 데 약간 힘들다. – xoofx
내 솔루션을 작성했을 때 오프셋 부분이 나를 혼란스럽게 만들었습니다 (저는 3D 그래픽을 처음 사용합니다. 실례합니다). 그래서 모델의 각 메쉬의 정점 버퍼를 반복하고 각 정점에 적용 가능한 뼈대 변환을 적용한 다음 버퍼의 정점을 정렬 된 정점 목록에 추가합니다. 본질적으로 많은 메쉬가 하나의 정점 목록으로 스쿼시됩니다. ? 오프셋? 모든 정점 인덱스 정보가없는 점군으로 구성 할 수 있기 때문에 볼록한 선체를 만드는 데 필요한 모든 것이 있지만 대표적인 메쉬를 만들기 위해서는 indices/TriangleVertexElements가 필요합니다. – lberezy