SunBurn and LOD models

rated by 0 users
This post has 6 Replies | 2 Followers

Top 10 Contributor
Posts 1,214
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee
Philippe Da Silva Posted: 03-01-2010 3:56 PM

Hi all,

I am in the process of adding Level of details to my game and I was wondering how you would fit this into the newly SceneObject and ObjectManager classes and design pattern?

With SceneObject asking for one unique Model or ModelMesh to be instantiated, I'm likely to inherit from it and add some additional RenderableMesh instances as private members that would replace the SceneObject ones depending on some camera distance properties for instance.

How would you do?

Thanks

Philippe

Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

Hi Philippe,

Philippe Da Silva:
I'm likely to inherit from it and add some additional RenderableMesh instances as private members that would replace the SceneObject ones depending on some camera distance properties for instance.

That's our current plan for implementing lod down the road, I personally think this is a very good way to go - it keeps both the internal and external rendering very simple (just render the RenderableMeshes without worrying about which lod level to use or how to access them).  It also allows you to override the lod code per-object and per-descendant class.

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 1,214
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

Hi John,

I'm starting to implement the LOD feature and I was wondering if I would need to recreate the BoudingSphere list you seem to use for the current SceneObject unique Model?

As lower polygon count meshes would still use the same scale Matrix, would it work if I just replace the RenderableMeshCollection with my owns and keeping the BoudingSphere collection as it is?

I'm going to give it a try but wondered to know if that would break something in the way the ObjectManager works :)

Top 10 Contributor
Posts 1,214
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

Ok, I've made my own implementation for a LOD and I thought I would share it with the community if you want to give it a try ;)

Cheers,

Philippe

// Enumeration to declare how many LODs you'll have
public enum MeshLod
    {
        Main,
        Low,
        Med,
    };

public class SceneEntity : SceneObject
    {
        #region Fields
        private RenderableMeshCollection __LowRenderableMeshes = new RenderableMeshCollection(new List<RenderableMesh>());
        private RenderableMeshCollection __MedRenderableMeshes = new RenderableMeshCollection(new List<RenderableMesh>());
        private RenderableMeshCollection __MainRenderableMeshes = new RenderableMeshCollection(new List<RenderableMesh>());
        #endregion

        #region Properties
        private MeshLod _Lod;
        public MeshLod Lod
        {
            get { return this._Lod; }
            set
            {
                if (this._Lod != value)
                {
                    this._Lod = value;
                    switch (value)
                    {
                        case MeshLod.Low:
                            {
                                this.RenderableMeshes = __LowRenderableMeshes;
                                break;
                            }
                        case MeshLod.Med:
                            {
                                this.RenderableMeshes = __MedRenderableMeshes;
                                break;
                            }
                        case MeshLod.Main:
                        default:
                            {
                                this.RenderableMeshes = __MainRenderableMeshes;
                                break;
                            }
                    }

// This is a hack required to correct Word positioning when creating yourself your
// RenderableMeshes for a SceneObject
// (see https://www.synapsegaming.com/forums/p/904/4418.aspx#4418)
                    Matrix worldtoobj = Matrix.Invert(this.World);
                    for (int i = 0; i < RenderableMeshes.Count; i++)
                        RenderableMeshes[i].SetWorldAndWorldToObject(this.World, worldtoobj);
                }
            }
        }

// This is a hack required to correct Word positioning when creating yourself your
// RenderableMeshes for a SceneObject
// (see https://www.synapsegaming.com/forums/p/904/4418.aspx#4418)
        public new Matrix World
        {
            get { return base.World; }
            set
            {
                if (base.World.Equals(value))
                    return;

                Matrix worldtoobj = Matrix.Invert(value);
                SetWorldAndWorldToObject(value, worldtoobj);

                for (int i = 0; i < RenderableMeshes.Count; i++)
                    RenderableMeshes[i].SetWorldAndWorldToObject(value, worldtoobj);
            }
        }
        #endregion

        #region Initialization
        public SceneEntity(Model mainMesh, Model lowMesh, string name)
            : base(mainMesh, name)
        {
            __MainRenderableMeshes = this.RenderableMeshes;
            __LowRenderableMeshes = new RenderableMeshCollection(this.CreateRenderableMeshes(lowMesh));
            this.Lod = MeshLod.Main;
        }

        public SceneEntity(Model mainMesh, Model lowMesh, Model medMesh, string name)
            : this(mainMesh, lowMesh, name)
        {
            __MedRenderableMeshes = new RenderableMeshCollection(this.CreateRenderableMeshes(medMesh));
        }

        public SceneEntity(Model mainMesh, Model lowMesh)
            : this(mainMesh, lowMesh, string.Empty)
        {
        }

        public SceneEntity(Model mainMesh, Model lowMesh, Model medMesh)
            : this(mainMesh, lowMesh, medMesh, string.Empty)
        {
        }
        #endregion

        #region Methods
        // This is where everything happens ;)
        private List<RenderableMesh> CreateRenderableMeshes(Model model)
        {
            List<RenderableMesh> meshes = new List<RenderableMesh>();

            for (int i = 0; i < model.Meshes.Count; i++)
            {
                Matrix identity = Matrix.Identity;
                for (ModelBone bone = model.Meshes[i].ParentBone; bone != null; bone = bone.Parent)
                {
                    identity *= bone.Transform;
                }

                for (int j = 0; j < model.Meshes[i].MeshParts.Count; j++)
                {
                    ModelMeshPart part = model.Meshes[i].MeshParts[j];
                    RenderableMesh item = new RenderableMesh(
                        this,
                        part.Effect,
                        identity,
                        model.Meshes[i].IndexBuffer,
                        model.Meshes[i].VertexBuffer,
                        part.VertexDeclaration,
                        part.StartIndex,
                        PrimitiveType.TriangleList,
                        part.PrimitiveCount,
                        part.BaseVertex,
                        part.NumVertices,
                        part.StreamOffset,
                        part.VertexStride);

                    meshes.Add(item);
                }
            }

            return meshes;
        }
        #endregion
    }

Top 10 Contributor
Posts 337
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

cool :)

Top 10 Contributor
Posts 4,854
Employee
SunBurn_Studio_Licensee

Hi Philippe,

Wow looks awesome!  Do you mind if we add this to the Community Resources section?

Philippe Da Silva:
As lower polygon count meshes would still use the same scale Matrix, would it work if I just replace the RenderableMeshCollection with my owns and keeping the BoudingSphere collection as it is?

Yes - we only use the bounding sphere list when processing xna models, to aggregate all bounds and generate a single complete bounding sphere for the entire object.  If you're able to provide the bounds without this step it's actually better (makes your code cleaner).

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 1,214
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

JohnK "bobthecbuilder":

Hi Philippe,
Wow looks awesome!  Do you mind if we add this to the Community Resources section?

No problem John. I was actually looking for some time to write down an article there but within a real case where I would extend this sample with the required code to use these classes ;)

But if you're on it, feel free to do so as I don't know when I'll have the time.

Page 1 of 1 (7 items) | RSS