2014-09-29 9 views
0

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)를 사용하는 것보다 훨씬 더 많은 충돌이 발생합니다. 왜 이것이 사실일까요?

필자의 코드 재 작성이 약간의 출력을 생성하지만, 전혀 느껴지지 않는다.

답변

1

아쉽게도 데이터를 쉽게 추출 할 수 없습니다. 버텍스 버퍼의 요소는 모델 버텍스 구조에 따라 달라질 수 있습니다 (compiler code 참조, Vector4, Vector3, Vector2 또는 16 비트까지 가질 수 있음).

올바르게 디코딩하려면 런타임에 레이아웃에 액세스하여 정점 버퍼를 디코딩해야합니다.

+0

답변 xoofx를 주셔서 감사합니다. Jitter Physics의 ConvexHullShape()를 구성하기 위해 꼭지점 목록을 구성하는 작업이 있다면 어떻게할까요? https://code.google.com/p/jitterphysics/source/browse/trunk : 이 지터 사용 XNA에서 예 (I 주로 실제로 SharpDX을 개발 한 사람으로부터 통찰력이 요청은) 아래에 연결되어 있습니다 /JitterDemo/JitterDemo/PhysicsObjects/ConvexHullObject.cs 그들이하는 방식과 이것이 SharpDX 솔루션으로 가장 잘 변환되는 방법에 동의합니까? 감사합니다. – lberezy

+0

완벽한 솔루션을 작성할 시간이 없지만 기본적으로 아이디어입니다. XNA 버전과의 차이점은 XNA GetData가 정점 스트림의 일부를 얻을 수 있지만 SharpDX를 사용하면 올바른 정점 요소에 대한 오프셋을 계산하고이를 해독하기 위해 원시 버퍼를 반복해야한다는 것입니다. 코드는 작성하는 데 약간 힘들다. – xoofx

+0

내 솔루션을 작성했을 때 오프셋 부분이 나를 혼란스럽게 만들었습니다 (저는 3D 그래픽을 처음 사용합니다. 실례합니다). 그래서 모델의 각 메쉬의 정점 버퍼를 반복하고 각 정점에 적용 가능한 뼈대 변환을 적용한 다음 버퍼의 정점을 정렬 된 정점 목록에 추가합니다. 본질적으로 많은 메쉬가 하나의 정점 목록으로 스쿼시됩니다. ? 오프셋? 모든 정점 인덱스 정보가없는 점군으로 구성 할 수 있기 때문에 볼록한 선체를 만드는 데 필요한 모든 것이 있지만 대표적인 메쉬를 만들기 위해서는 indices/TriangleVertexElements가 필요합니다. – lberezy