IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Diskusia – 17. diel - 3D bludisko v XNA - Instancujeme kolízne objekty

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Avatar
magic44
Tvůrce
Avatar
magic44:11.3.2014 18:57

Ahoj, delam 3D hru a najednou se mi hra zacala v. ob. sekat.. Tak jsem si řekl, že zkusím tohle.. noo možná jsem se měl spokojit s tím co sem měl a to co mi tu hru sekalo tam nedavat :D. Jinak dobrej tutorial.
Akorát mi CollidableInstan­ceModel3D nekoliduje. Zkusil jsem do mé hry dát tvůj kód, ale ani ten tam nefungoval. Nevíš čím by to mohlo být?

Odpovedať
11.3.2014 18:57
Moudrý člověk nechce být lepší než ostatní, ale lepší, než byl sám včera.
Avatar
vodacek
Tvůrce
Avatar
Odpovedá na magic44
vodacek:11.3.2014 20:35

bez toho aniž bych to viděl tak těžko

 
Odpovedať
11.3.2014 20:35
Avatar
magic44
Tvůrce
Avatar
Odpovedá na vodacek
magic44:11.3.2014 21:35

Hm.. tak tady je snad vše co je potřeba k instancování, je tohe ale nějak moc.

public struct InstanceDataVertex:InstanceVertexType
    {
        public Matrix World;
        public Color Color;

        public InstanceDataVertex(Matrix world, Color color)
        {
            World = world;
            Color = color;
        }

        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return InstanceDataVertex.VertexDeclaration; }
        }

        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration(
            new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3),
            new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4),
            new VertexElement(sizeof(float) * 8, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 5),
            new VertexElement(sizeof(float) * 12, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 6),
            new VertexElement(sizeof(float) * 16, VertexElementFormat.Color, VertexElementUsage.Color, 0));

        public static readonly int SizeInBytes = sizeof(float) * (16 + 4);

        Matrix InstanceVertexType.GetWorld()
        {
            return World;
        }
    }
public interface InstanceVertexType:IVertexType
    {
        Matrix GetWorld();
    }
public class InstancedModel3D<T>:Component where T : struct, InstanceVertexType
    {
        public string ModelName;
        public Model Model;
        protected VertexBuffer Verticles;
        protected IndexBuffer Indicies;
        protected Texture2D Texture;

        protected DynamicVertexBuffer Primitives;
        public int MaxCount;
        public int Count;

        protected List<T> PrimitiveList;

        protected string effectName;
        protected Effect Effect;

        private readonly VertexBufferBinding[] binding = new VertexBufferBinding[2];

        public InstancedModel3D(string nazev, int max, string effect)
        {
            ModelName = nazev;
            MaxCount = max;
            this.effectName = effect;
            PrimitiveList = new List<T>(MaxCount);
        }

        protected override void Load()
        {
            Model = Parent.Engine.ContentManager.Load<Model>(ModelName);
            Effect = Parent.Engine.ContentManager.Load<Effect>(effectName);
            List<VertexPositionNormalTexture> vert = new List<VertexPositionNormalTexture>();
            List<ushort> ind = new List<ushort>();

            Matrix[] transforms = new Matrix[Model.Bones.Count];
            Model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in Model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    VertexPositionNormalTexture[] partVerts = new VertexPositionNormalTexture[part.VertexBuffer.VertexCount];
                    part.VertexBuffer.GetData(partVerts);

                    for (int i = 0; i < partVerts.Length; i++)
                    {
                        partVerts[i].Position = Vector3.Transform(partVerts[i].Position, transforms[mesh.ParentBone.Index]);
                    }
                    ushort[] partIndices = new ushort[part.IndexBuffer.IndexCount];

                    part.IndexBuffer.GetData(partIndices);
                    ind.AddRange(partIndices);

                    vert.AddRange(partVerts);
                }
            }

            Verticles = new VertexBuffer(Parent.Engine.GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vert.Count, BufferUsage.WriteOnly);
            Verticles.SetData<VertexPositionNormalTexture>(vert.ToArray());

            Indicies = new IndexBuffer(Parent.Engine.GraphicsDevice, IndexElementSize.SixteenBits, ind.Count, BufferUsage.WriteOnly);
            Indicies.SetData<ushort>(ind.ToArray());

            Texture = ((BasicEffect)Model.Meshes[0].Effects[0]).Texture;

            binding[0] = new VertexBufferBinding(Verticles);
        }

        public override void Draw(Matrix View, Matrix Projection, Vector3 CameraPosition)
        {
            if (Primitives == null || Count == 0)
                return;
            Effect.Parameters["View"].SetValue(View);
            Effect.Parameters["Projection"].SetValue(Projection);
            //Effect.Parameters["TextureEnabled"].SetValue(Texture != null);
            Effect.Parameters["Texture"].SetValue(Texture);

            Effect.CurrentTechnique.Passes[0].Apply();

            Parent.Engine.GraphicsDevice.SetVertexBuffers(binding);
            Parent.Engine.GraphicsDevice.Indices = Indicies;

            Parent.Engine.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, Verticles.VertexCount, 0, Indicies.IndexCount / 3, Count);
        }

        public virtual void Apply()
        {
            if (PrimitiveList.Count == 0)
                return;
            if (Primitives == null)
            {
                MaxCount = Math.Max(MaxCount, PrimitiveList.Count);
                Primitives = new DynamicVertexBuffer(Parent.Engine.GraphicsDevice, PrimitiveList[0].VertexDeclaration, MaxCount, BufferUsage.None);
                binding[1] = new VertexBufferBinding(Primitives, 0, 1);
            }
            if (MaxCount < PrimitiveList.Count)
            {
                MaxCount = PrimitiveList.Count;
                Primitives = new DynamicVertexBuffer(Parent.Engine.GraphicsDevice, PrimitiveList[0].VertexDeclaration, MaxCount, BufferUsage.None);
                binding[1] = new VertexBufferBinding(Primitives, 0, 1);
            }
            /*if (Primitives == null && PrimitiveList.Count > 0)
            {
                Primitives = new DynamicVertexBuffer(Parent.Engine.GraphicsDevice, PrimitiveList[0].VertexDeclaration, MaxCount, BufferUsage.None);
                binding[1] = new VertexBufferBinding(Primitives, 0, 1);
            }*/
            Primitives.SetData<T>(PrimitiveList.ToArray(), 0, PrimitiveList.Count);
            Count = PrimitiveList.Count;
        }

        public virtual void AddPrimitives(T obj)
        {
            PrimitiveList.Add(obj);
        }

        public virtual void RemovePrimitives(T obj)
        {
            PrimitiveList.Remove(obj);
        }
    }
public class CollidableInstanceModel3D<T>: InstancedModel3D<T> where T: struct, InstanceVertexType
    {
        MultipleBoxCillisionSkin Skin;
        protected BoundingBox Box;

        public CollidableInstanceModel3D(string model, int max, string effect)
            : base(model, max, effect)
        {
            Skin = new MultipleBoxCillisionSkin();
        }

        protected override void Load()
        {
            base.Load();
            Matrix[] transformace = new Matrix[Model.Bones.Count];
            Model.CopyAbsoluteBoneTransformsTo(transformace);
            Box = Utility.VypoctiBountingBox(Model, transformace);

            foreach (T obj in PrimitiveList)
            {
                Skin.AddBox(Utility.Transform(Box, obj.GetWorld()));
            }
        }

        public override void OnAdded()
        {
            base.OnAdded();
            if (Parent is CollidableGameScreen)
            {
                CollidableGameScreen cg = Parent as CollidableGameScreen;
                cg.CollisionManager.AddBox(Skin);
            }
        }

        public override void OnRemoved(GameScreen okno)
        {
            base.OnRemoved(okno);
            if (okno is CollidableGameScreen)
            {
                CollidableGameScreen o=okno as CollidableGameScreen;
                o.CollisionManager.RemoveBox(Skin);
            }
        }

        public override void AddPrimitives(T obj)
        {
            base.AddPrimitives(obj);
            if (!Loaded)
                Skin.AddBox(Utility.Transform(Box, obj.GetWorld()));
        }

        public override void RemovePrimitives(T obj)
        {
            int id = PrimitiveList.IndexOf(obj);
            base.RemovePrimitives(obj);
            Skin.RemoveBox(id);
        }
    }
public class MultipleBoxCillisionSkin:CollisionSkin
    {
        protected List<BoundingBox> Boxes;
        BoundingBox Box;

        public MultipleBoxCillisionSkin()
        {
            Boxes = new List<BoundingBox>();
        }

        public void AddBox(BoundingBox b)
        {
            Boxes.Add(b);
        }

        public void RemoveBox(int index)
        {
            Boxes.RemoveAt(index);
        }

        public override bool Intersects(BoundingSphere sp)
        {
            foreach (BoundingBox b in Boxes)
            {
                if (b.Intersects(sp))
                    return true;
            }
            return false;
        }

        public override void Draw()
        {
            foreach (BoundingBox b in Boxes)
            {
                BoundingRenderer.Render(b, Manager.Parent.Kamera.View, Manager.Parent.Kamera.Projection, LastCollision ? Color.Red : Color.Black);
            }
        }

        public override void Transform(Vector3 Meritko, Vector3 Pozice, Matrix Rotace)
        {

        }
    }
Odpovedať
11.3.2014 21:35
Moudrý člověk nechce být lepší než ostatní, ale lepší, než byl sám včera.
Avatar
vodacek
Tvůrce
Avatar
Odpovedá na magic44
vodacek:11.3.2014 21:40

a vykreslujou se ty kolizní krabice?

 
Odpovedať
11.3.2014 21:40
Avatar
magic44
Tvůrce
Avatar
Odpovedá na vodacek
magic44:11.3.2014 22:51

Myslíš, to když je kolize, tak jsou červený? Ne ty se mi nezobrazujou, ale mě se nikdy nezobrazovali ani u CollidableModel3D a ten funguje.

Odpovedať
11.3.2014 22:51
Moudrý člověk nechce být lepší než ostatní, ale lepší, než byl sám včera.
Avatar
vodacek
Tvůrce
Avatar
Odpovedá na magic44
vodacek:12.3.2014 13:13

buď tam prostě nejsou a nebo se nevolá kreslící metoda

 
Odpovedať
12.3.2014 13:13
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!