IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze – Lekce 17 - 3D bludiště v XNA - Instancujeme kolizní objekty

Zpět

Upozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.

Komentáře
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?

Odpovědět
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
Odpovídá na magic44
vodacek:11.3.2014 20:35

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

 
Odpovědět
11.3.2014 20:35
Avatar
magic44
Tvůrce
Avatar
Odpovídá 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)
        {

        }
    }
Odpovědět
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
Odpovídá na magic44
vodacek:11.3.2014 21:40

a vykreslujou se ty kolizní krabice?

 
Odpovědět
11.3.2014 21:40
Avatar
magic44
Tvůrce
Avatar
Odpovídá 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.

Odpovědět
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
Odpovídá na magic44
vodacek:12.3.2014 13:13

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

 
Odpovědět
12.3.2014 13:13
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.