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.
Tvůrce
Odpovedá na vodacek
magic44:11.3.2014 21:35
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)
{
}
}
Odpovedá na vodacek
magic44:11.3.2014 22:51
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.
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ý!