Hi,

I altered the ModelOcTree class in the JigLibX example to support rotating and scaling. It seems to work perfect with the fbx and x files i use for models…….. Below is the class, but i'll tell you right now what the difference is………

First off, there is already a method:

public void ExtractData(List<Vector3> vertices, List<TriangleVertexIndices> indices, Model model)

that method is essentially what builds the ocTree from the model. Fine.

The problem is, it does a literal translation of all the verticies, so you are stuck putting your model in the center of your world (Vector.Zero). For me, this was not OK, because i use MANY ocTrees in my scene, not just one for the entire scene.

So i updated the contructor…. notice i take the position, rotation, and scale, and create a local property called "WORLD"

public ModelOctree(Game game, string path, Quaternion rotation, Vector3 position, Vector3 scale, bool drawWireFrame)

: base(game)

{

ModelPath = path;

DrawWireFrame = drawWireFrame;

body = new Body();

collision = new CollisionSkin(body);

collision.CollisionType = (int)CollisionTypes.NonMovingStructure;

if (DrawWireFrame)

wireFrameDrawer = new DebugDrawer(game);

modelScale = Matrix.CreateScale(scale);

world = modelScale * Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(position);

Rotation = rotation;

Position = position;

}

then, inside the ExtractData method, which is called internally, while it is looping through the verticies and doing whatever, i take the opportunity to UPDATE the verticies by simply replacing with "What the vertex position WOULD be if scaling rotation and position were applied……. All these new verticies combined make the model you WANT.

Matrix m = (Matrix.CreateTranslation(a[i]) * world);

a[i] = m.Translation;

You see, i take the position from the array, and replace it.

Here is the whole class… Use it. No warranties. Works perfect for me.

It DOES inherit from 'PhysicsObject' class, which is part of the JibLibX sample game, so if you don't like the idea of using a little of that code…. then too bad, ha.

Happy Coding ;)

-Mike Tsouris

http://giveup-games.com

using System;

using System.Collections.Generic;

using System.Text;

using JigLibX.Collision;

using JigLibX.Physics;

using Microsoft.Xna.Framework;

using JigLibX.Geometry;

using Microsoft.Xna.Framework.Graphics;

using JigLibX.Math;

using GiveUp.Core;

namespace GiveUp.Physics

{

public class ModelOctree : PhysicObject

{

TriangleMesh triangleMesh;

Vector3 Position;

Quaternion Rotation;

Matrix world;

Matrix modelScale;

Matrix[] bones;

DebugDrawer wireFrameDrawer;

bool DrawWireFrame = false;

string ModelPath;

Model model;

private void Load()

{

model = Game.Content.Load<Model>(ModelPath);

bones = new Matrix[model.Bones.Count];

triangleMesh = new TriangleMesh();

List<Vector3> vertexList = new List<Vector3>();

List<TriangleVertexIndices> indexList = new List<TriangleVertexIndices>();

ExtractData(vertexList, indexList, this.model);

triangleMesh.CreateMesh(vertexList, indexList, 4, 1.0f);

collision.AddPrimitive(triangleMesh, (int)MaterialTable.MaterialID.NormalRough);

PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision);

body.MoveTo(Position, Matrix.Identity);

body.Immovable = true;

}

public ModelOctree(Game game, string path, Quaternion rotation, Vector3 position, Vector3 scale, bool drawWireFrame)

: base(game)

{

ModelPath = path;

DrawWireFrame = drawWireFrame;

body = new Body();

collision = new CollisionSkin(body);

collision.CollisionType = (int)CollisionTypes.NonMovingStructure;

if (DrawWireFrame)

wireFrameDrawer = new DebugDrawer(game);

modelScale = Matrix.CreateScale(scale);

world = modelScale * Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(position);

Rotation = rotation;

Position = position;

}

protected override void LoadContent()

{

base.LoadContent();

Load();

}

*/ <summary>*

/ Helper Method to get the vertex and index List from the model.

*/ </summary>*

/ <param name="vertices"></param>

*/ <param name="indices"></param>*

/ <param name="model"></param>

public void ExtractData(List<Vector3> vertices, List<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]);

// move the vertice point from 0-space to our desired world position

Vector3 p = a[i];

Matrix m = (Matrix.CreateTranslation(a[i]) * world);

a[i] = m.Translation;

}

vertices.AddRange(a);

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);

JigLibX.Geometry.TriangleVertexIndices[] tvi = new JigLibX.Geometry.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);

}

}

}

public override void Draw(GameTime gameTime)

{

model.CopyAbsoluteBoneTransformsTo(bones);

foreach (ModelMesh mesh in model.Meshes)

{

foreach (BasicEffect effect in mesh.Effects)

{

effect.World = bones[mesh.ParentBone.Index] * this.world;

effect.View = Global3dGame.CurrentCamera.View;

effect.Projection = Global3dGame.CurrentCamera.Projection;

//ApplyEffects(effect);

effect.EnableDefaultLighting();

effect.PreferPerPixelLighting = true;

}

mesh.Draw();

}

if (DrawWireFrame)

{

VertexPositionColor[] v = this.collision.GetLocalSkinWireframe();

body.TransformWireframe(v);

wireFrameDrawer.DrawShape(v);

}

}

public override void Initialize()

{

base.Initialize();

if (DrawWireFrame)

wireFrameDrawer.Initialize();

}

}

}