• Home
  • Products
    • Game Engine
      • Base
      • Mathematics
      • Geometry
      • Physics
      • Particles
      • Animation
      • Graphics
      • Game
      • Game UI
    • Windows Forms
      • Docking Windows
      • Text Editor Control
  • Downloads
  • Buy
    • Overview
    • Professional
    • Indie
    • Non-Commercial
  • Support
    • Overview
    • Blog
    • Forum
    • License FAQ
    • Documentation
  • About
    • About Us
      • Services
    • Contact Us
    • Press
    • Legal Terms
      • Imprint (English)
      • Imprint (German)
Select the search type
 
  • Site
  • Web
Search
DigitalRune.com
Login |Register
NEWS News RSS Feed BLOG Blog RSS Feed FORUM News RSS Feed DOCUMENTATION DigitalRune Software on YouTube DigitalRune Software on Twitter
You are here: SupportForum

If you want to contribute to the forum discussions, please Register or Login.

SearchHome
  • 1
  • 2
  • 3
  • 4
  • 5
HomeHomeDigitalRune Sof...DigitalRune Sof...Game EngineGame EngineDigitalRune PhysicsDigitalRune Physics
Previous
 
Next
New Post
11/30/2011 11:01 AM
 
locker
No Ranking

Joined: 11/30/2011
Posts: 2
DigitalRune Physics 

Hi,

I try to explain my problem: I want to create a ConvexPolyhedron from a model part. My model is a Player (like Dude) and I want to create, for example a ConvexPolyhedron of head. The Player has a skeleton and each bone is associated to a mesh. Now, from Car sample, I can create a convexHull from a FBX Model, but not from a single mesh of the model. There is a way?


Thank you.



 
New Post
11/30/2011 11:27 AM
 
HelmutG
6th Level Poster

www.digitalrune.com
Joined: 10/15/2006
Posts: 565
Re: DigitalRune Physics 

Sure, this is possible, but you need to extract the vertex positions yourself. Here is a code snippet from a test project. It iterates of the meshes of a model, extracts the vertices and creates a convex shape for each bone:

private void CreateLimbs()
{
  ModelBoneCollection bones = _model.Bones;
 
  // A list of vertex lists. One vertex list for each bone of the model.
  List<List<Vector3F>> boneVerticesArray;
  boneVerticesArray = bones.Select(bone => new List<Vector3F>()).ToList();
   
  // Loop through the meshes of the model. Extract the vertices and fill the
  // boneVerticesArray.
  foreach (var mesh in _model.Meshes)
  {
    Matrix transform = GetAbsoluteTransform(mesh.ParentBone);
 
    foreach (var meshPart in mesh.MeshParts)
    {
      var vertexDeclaration = meshPart.VertexBuffer.VertexDeclaration;
      var vertexElements = vertexDeclaration.GetVertexElements();
 
      // Get the verex positions.
      var positionElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.Position);
      if (positionElement.VertexElementFormat != VertexElementFormat.Vector3)
        throw new NotSupportedException();
      var positions = new Vector3[meshPart.NumVertices];
      meshPart.VertexBuffer.GetData(
        meshPart.VertexOffset * vertexDeclaration.VertexStride + positionElement.Offset,
        positions,
        0,
        meshPart.NumVertices,
        vertexDeclaration.VertexStride);
      for (int i = 0; i < positions.Length; i++)
        positions[i] = Vector3.Transform(positions[i], transform);
 
      // Get indices.
      var indexElementSize = (meshPart.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits) ? 2 : 4;
      if (indexElementSize != 2)
        throw new NotSupportedException();
      var indices = new short[meshPart.PrimitiveCount * 3];
      meshPart.IndexBuffer.GetData(meshPart.StartIndex * 2, indices, 0, meshPart.PrimitiveCount * 3);
 
      // Get the bone indices.
      var boneIndexElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.BlendIndices);
      if (boneIndexElement.VertexElementFormat != VertexElementFormat.Byte4)
        throw new NotSupportedException();
      var boneIndicesArray = new Byte4[meshPart.NumVertices];
      meshPart.VertexBuffer.GetData(
        meshPart.VertexOffset * vertexDeclaration.VertexStride + boneIndexElement.Offset,
        boneIndicesArray,
        0,
        meshPart.NumVertices,
        vertexDeclaration.VertexStride);
 
      // Get the bone weights.
      var boneWeightElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.BlendWeight);
      if (boneWeightElement.VertexElementFormat != VertexElementFormat.Vector4)
        throw new NotSupportedException();
      var boneWeightsArray = new Vector4[meshPart.NumVertices];
      meshPart.VertexBuffer.GetData(
        meshPart.VertexOffset * vertexDeclaration.VertexStride + boneWeightElement.Offset,
        boneWeightsArray,
        0,
        meshPart.NumVertices,
        vertexDeclaration.VertexStride);    
 
      // Now, we have all the info and can sort the vertices into the boneVerticesArray.
      for (int i = 0; i < meshPart.NumVertices; i++)
      {
        Vector3 position = positions[i];
        Vector4 boneIndices = boneIndicesArray[i].ToVector4();
        Vector4 boneWeights = boneWeightsArray[i];
 
        // A vertex should be in the convex hull of a bone if the bone weight is
        // above a threshold.
        const float threshold = 0.45f;
        if (boneIndices.X >= 0 && boneWeights.X >= threshold)
           boneVerticesArray[(int)boneIndices.X].Add((Vector3F)position);
        if (boneIndices.Y >= 0 && boneWeights.Y >= threshold)
          boneVerticesArray[(int)boneIndices.Y].Add((Vector3F)position);
        if (boneIndices.Z >= 0 && boneWeights.Z >= threshold)
          boneVerticesArray[(int)boneIndices.Z].Add((Vector3F)position);
        if (boneIndices.W >= 0 && boneWeights.W >= threshold)
          boneVerticesArray[(int)boneIndices.W].Add((Vector3F)position);
      }
    }
  }
 
  // We have all the vertices for each bone. Compute a convex hull for each bone.
  int numberOfLimbs = boneVerticesArray.Count;
  _limbs = new LimbGeometricObject[numberOfLimbs];
  for (int i = 0; i < numberOfLimbs; i++)
  {
    var boneVertices = boneVerticesArray[i];
    if (boneVertices.Count > 0)
    {
      // Create a simplified convex hull for the vertices.
      DcelMesh convexHullMesh = GeometryHelper.CreateConvexHull(boneVertices, 64, 0);
 
      // We only need the positions of the vertices in the hull.
      IEnumerable<Vector3F> points = convexHullMesh.Vertices.Select(v => v.Position);
 
      if (!points.Any())
      {
        // Convex hull computation failed? Maybe the mesh is degenerated...
        // --> Use all vertices of this bone.
        points = boneVertices;
      }
 
      // The ConvexPolyhedron shape is the fastest for large convex hulls.
      ConvexPolyhedron shape = new ConvexPolyhedron(points);
 
      _limbs[i] = new LimbGeometricObject(shape, _modelPose);
 
      var collisionObject = new CollisionObject(_limbs[i])
      {
        CollisionGroup = 2,
        Type = CollisionObjectType.Trigger,
      };
 
      _collisionDomain.CollisionObjects.Add(collisionObject);
    }
  }
}

 

Instead of the custom "LimbGeometricObject" you will want to create a RigidBody instance for each bone.

The method handles the general case where each mesh includes several bones. It uses the bone weights to decide if a vertex belongs to a certain bone. If the model is already simplified and contains a separate mesh for each bone, this method can be greatly simplified.

 
 Page 1 of 1
Previous
 
Next
HomeHomeDigitalRune Sof...DigitalRune Sof...Game EngineGame EngineDigitalRune PhysicsDigitalRune Physics


DigitalRune is a trademark of Garstenauer Information Technology OG.

Garstenauer Information Technology OG
Weingartenstrasse 35, 4452 Ternberg
Austria (EUROPE)
office@digitalrune.com

Home Products Downloads Buy Support About Us
Game Engine Particles Windows Forms Professional Blog Services
Base Animation Docking Windows Indie Forum Contact Us
Mathematics Graphics Text Editor Control Non-Commercial License FAQ Press (News)
Geometry Game Documentation Legal Terms
Physics Game UI Imprint
Impressum
Copyright © 2006-2012 Garstenauer Information Technology OG Terms Of UsePrivacy Statement