public static void UpdateMeshMatrix(GameObjectReference gm) { if (gm.PhysicsObj == null) { return; } Model model = gm.BaseGameObject as Model; if (model.StaticMesh) { Cell c = WorldData.GetObject(gm.CellContainerId) as Cell; AffineTransform entityMatrix = new AffineTransform(gm.Scale, Quaternion.RotationMatrix(gm.Rotation), WorldSpace.GetRealWorldPos(gm.Position, c)); InstancedMesh sm = gm.PhysicsObj as InstancedMesh; sm.WorldTransform = entityMatrix; gm.EntityTransform = entityMatrix.Matrix; sm.UpdateBoundingBox(); } else { if (!Paused) { return; } Cell c = WorldData.GetObject(gm.CellContainerId) as Cell; Matrix entityMatrix = gm.Rotation * Matrix.Translation(WorldSpace.GetRealWorldPos(gm.Position, c)); Entity mm = gm.PhysicsObj as Entity; mm.WorldTransform = entityMatrix; gm.EntityTransform = entityMatrix; } }
public static void AddMeshToSpace(GameObjectReference m, Cell c) { Model model = m.BaseGameObject as Model; if (model.StaticMesh) { InstancedMeshShape sms = null; if (staticMeshShapeCache.ContainsKey(model.Mesh3d.meshFileName)) { sms = staticMeshShapeCache[model.Mesh3d.meshFileName]; } else { Vector3[] verts = model.Mesh3d.GetMeshVertices(); int[] indecies = model.Mesh3d.GetMeshIndices(); sms = new InstancedMeshShape(verts, indecies); staticMeshShapeCache.Add(model.Mesh3d.meshFileName, sms); } AffineTransform entityMatrix = new AffineTransform(m.Scale, Quaternion.RotationMatrix(m.Rotation), WorldSpace.GetRealWorldPos(m.Position, c)); InstancedMesh mm = new InstancedMesh(sms, entityMatrix); mm.Tag = m; mm.ImproveBoundaryBehavior = true; mm.Sidedness = BEPUphysics.CollisionShapes.ConvexShapes.TriangleSidedness.Clockwise; PhysicsEngine.Space.Add(mm); m.PhysicsObj = mm; m.EntityTransform = entityMatrix.Matrix; } else { MobileMeshShape mms = null; ShapeDistributionInformation shapeInfo; if (mobileMeshShapeCache.ContainsKey(model.Mesh3d.meshFileName)) { mms = mobileMeshShapeCache[model.Mesh3d.meshFileName]; shapeInfo = mobileMeshInfoCache[model.Mesh3d.meshFileName]; } else { Vector3[] verts = model.Mesh3d.GetMeshVertices(); int[] indecies = model.Mesh3d.GetMeshIndices(); mms = new MobileMeshShape(verts, indecies, AffineTransform.Identity, MobileMeshSolidity.Solid, out shapeInfo); mobileMeshShapeCache.Add(model.Mesh3d.meshFileName, mms); mobileMeshInfoCache.Add(model.Mesh3d.meshFileName, shapeInfo); } mms.Sidedness = BEPUphysics.CollisionShapes.ConvexShapes.TriangleSidedness.Clockwise; Matrix mWorld = m.Rotation * Matrix.Translation(WorldSpace.GetRealWorldPos(m.Position, c)); Entity e = new Entity(mms, 10); e.CollisionInformation.LocalPosition = shapeInfo.Center; e.WorldTransform = mWorld; e.Tag = m; e.PositionUpdateMode = PositionUpdateMode.Continuous; PhysicsEngine.Space.Add(e); m.PhysicsObj = e; m.EntityTransform = mWorld; } }
public InstancedMesh AddBlockType(String blockType, ModelMeshPart meshData, Matrix transform, int maxAmountOfInstances) { InstancedMesh instancedMesh = new InstancedMesh(device, meshData, transform, maxAmountOfInstances); blockInstancedMeshes.Add(blockType, instancedMesh); return(instancedMesh); }
public void AddBlock(String blockType, Matrix transform) { // Obtain instanced mesh for the block InstancedMesh instancedMesh = blockInstancedMeshes[blockType]; int instanceIndex = instancedMesh.AppendInstance(transform); }
public Particle CreateParticle() { Particle particle = null; if (particlesPool.Count() > 0) { particle = particlesPool[0]; particlesPool.RemoveAt(0); particle.Position = Vector3.Zero; particle.Direction = Vector3.Zero; particle.Force = Vector3.Zero; } else { particle = new Particle(); } // Create mesh for the particle InstancedMesh <VertexData> .Instance instance = instancedMesh.AppendInstance(Matrix.Identity); particle.Instance = instance; particles.Add(particle); return(particle); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { instancedMesh = entryA as InstancedMesh; convex = entryB as ConvexCollidable; if (instancedMesh == null || convex == null) { instancedMesh = entryB as InstancedMesh; convex = entryA as ConvexCollidable; if (instancedMesh == null || convex == null) throw new Exception("Inappropriate types used to initialize pair."); } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = instancedMesh; UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, instancedMesh.material); base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { instancedMesh = entryA as InstancedMesh; convex = entryB as ConvexCollidable; if (instancedMesh == null || convex == null) { instancedMesh = entryB as InstancedMesh; convex = entryA as ConvexCollidable; if (instancedMesh == null || convex == null) { throw new ArgumentException("Inappropriate types used to initialize pair."); } } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = instancedMesh; UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, instancedMesh.material); base.Initialize(entryA, entryB); }
public Block(BlockType blockType, InstancedMesh <VertexData> .Instance instance, CompoundChild entity) { BlockType = blockType; Instance = instance; Entity = entity; HitPoints = blockType.HitPoints; }
/// <summary> /// Creates and instance of InstancedTriangleMesh /// Call the Static Method GetInstacedMesh to get the InstancedMeshShape obj /// </summary> /// <param name="InstancedMeshShape">The instanced mesh shape.</param> /// <param name="pos">The pos.</param> /// <param name="rotation">The rotation.</param> /// <param name="scale">The scale.</param> /// <param name="materialDescription">The material description.</param> /// <param name="TriangleSidedness">The triangle sidedness.</param> public InstancedTriangleMeshObject(InstancedMeshShape InstancedMeshShape, Vector3 pos, Matrix rotation, Vector3 scale, MaterialDescription materialDescription, TriangleSidedness TriangleSidedness = TriangleSidedness.Counterclockwise) { instancedMesh = new InstancedMesh(InstancedMeshShape, new BEPUphysics.MathExtensions.AffineTransform(scale, Quaternion.CreateFromRotationMatrix(rotation), pos)); instancedMesh.Material = new BEPUphysics.Materials.Material(materialDescription.StaticFriction, materialDescription.DynamicFriction, materialDescription.Bounciness); instancedMesh.Sidedness = TriangleSidedness; this.rotation = rotation; this.scale = scale; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); mesh = null; }
public override void Init() { base.Init(); if (MeshAsset == null || MeshAsset.GetAsset() == null || !MeshAsset.GetAsset().IsLoaded) { m_physicsMesh = new InstancedMesh(PhysicsStatics.DummyInstancedMesh); m_physicsMesh.Sidedness = TriangleSidedness.Clockwise; } InvalidateCollider(); m_transform.OnPositionChanged += OnPositionChanged; m_transform.OnRotationChanged += OnRotationChanged; }
protected void SetPhysicsFromLoadedMesh() { if (m_physicsMesh != null) { m_physicsMesh.Shape = m_meshAssetReference.GetAsset().GetPhysicsInstancedMesh(); m_physicsMesh.Sidedness = TriangleSidedness.Clockwise; } else { m_physicsMesh = new InstancedMesh(m_meshAssetReference.GetAsset().GetPhysicsInstancedMesh()); } m_physicsMesh.WorldTransform = new AffineTransform(WorldScale.ToBepu(), WorldRotation.ToBepu(), WorldPosition.ToBepu()); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { mesh = entryA as InstancedMesh; if (mesh == null) { mesh = entryB as InstancedMesh; if (mesh == null) { throw new ArgumentException("Inappropriate types used to initialize pair."); } } base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { mesh = entryA as InstancedMesh; if (mesh == null) { mesh = entryB as InstancedMesh; if (mesh == null) { throw new Exception("Inappropriate types used to initialize pair."); } } base.Initialize(entryA, entryB); }
public void RemoveBlock(Block block) { // Move block's physics entity to group of removed blocks // so it will not collide with the balls block.Entity.CollisionInformation.CollisionRules.Group = removedBlocksGroup; // Remove graphical representation of the block String blockTypeName = block.BlockType.Name; InstancedMesh <VertexData> instancedMesh = blockInstancedMeshes[blockTypeName]; instancedMesh.RemoveInstance(block.Instance); // Remove block from the list of blocks blocks.Remove(block); }
///<summary> /// Initializes the manifold. ///</summary> ///<param name="newCollidableA">First collidable.</param> ///<param name="newCollidableB">Second collidable.</param> public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { convex = newCollidableA as ConvexCollidable; mesh = newCollidableB as InstancedMesh; if (convex == null || mesh == null) { convex = newCollidableB as ConvexCollidable; mesh = newCollidableA as InstancedMesh; if (convex == null || mesh == null) { throw new ArgumentException("Inappropriate types used to initialize contact manifold."); } } }
public ParticleSystem(Model model, Texture2D texture, int maxAmountOfParticles, Game game, Camera camera) : base(game) { Matrix transform = Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f)); transform *= Matrix.CreateScale(0.75f); instancedMesh = new InstancedMesh <VertexData>(game.GraphicsDevice, model.Meshes[0].MeshParts[0], transform, maxAmountOfParticles); instancedMesh.Effect.Texture = texture; instancedMesh.Effect.TextureEnabled = true; instancedMesh.Effect.LightingEnabled = false; //instancedMesh.Effect.Alpha = 0.5f; this.camera = camera; }
private BlockType LoadBlockType(String blockTypeName, int maxBlocks) { // Load block type data BlockTypeData blockTypeData = Game.Content.Load <BlockTypeData>(@"Game\BlockTypes\" + blockTypeName); // Create block type instance BlockType blockType = new BlockType(blockTypeName, this); // Populate type instance with data blockType.HitPoints = blockTypeData.HitPoints; blockType.ScoresPerHitPoint = blockTypeData.ScoresPerHitPoint; blockType.Events = blockTypeData.Events; // Load model for this block type Model model = Game.Content.Load <Model>(@"Models\" + blockTypeData.Appearance.Model); blockType.Model = model; blockType.Color = blockTypeData.Appearance.Color.ToVector3(); // Create instance mesh for blocks of this type // TODO: Think about how mane instances this InstancedMesh should have InstancedMesh <VertexData> instancedMesh = new InstancedMesh <VertexData>(Game.GraphicsDevice, model.Meshes[0].MeshParts[0], Matrix.Identity, maxBlocks); if (String.IsNullOrEmpty(blockTypeData.Appearance.Texture) == false) { Texture2D texture = Game.Content.Load <Texture2D>(@"Images\" + blockTypeData.Appearance.Texture); instancedMesh.Effect.Texture = texture; instancedMesh.Effect.TextureEnabled = true; blockType.Texture = texture; } // Set color for instance mesh effect instancedMesh.Effect.DiffuseColor = blockTypeData.Appearance.Color.ToVector3(); // Associate instance mesh with block type blockInstancedMeshes.Add(blockType.Name, instancedMesh); // Store block type by its name blockTypes.Add(blockTypeName, blockType); return(blockType); }
public void AddBlock(String blockType, int x, int y, int z) { // Obtain compound child for the block int index = x + y * GAME_FIELD_SIZE + z * GAME_FIELD_SIZE * GAME_FIELD_SIZE; CompoundChild child = compoundBody.CollisionInformation.Children[index]; child.CollisionInformation.CollisionRules.Group = null; // Obtain instanced mesh for the block InstancedMesh instancedMesh = blockInstancedMeshes[blockType]; // Create instance of the block in instanced mesh Matrix transform = child.Entry.LocalTransform.Matrix; //Matrix.CreateTranslation(x + BLOCK_SIZE * 0.5f, y + BLOCK_SIZE * 0.5f, z + BLOCK_SIZE * 0.5f); int instanceIndex = instancedMesh.AppendInstance(transform); // Store new instance to the list Block block = new Block(instancedMesh, instanceIndex, child); blocks.Add(block); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public InstancedMeshDemo(DemosGame game) : base(game) { Vector3[] vertices; int[] indices; ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("guy"), out vertices, out indices); var meshShape = new InstancedMeshShape(vertices, indices); var random = new Random(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { //Create a transform and the instance of the mesh. var transform = new AffineTransform( new Vector3((Fix64)random.NextDouble() * 6 + .5m, (Fix64)random.NextDouble() * 6 + .5m, (Fix64)random.NextDouble() * 6 + .5m), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((Fix64)random.NextDouble(), (Fix64)random.NextDouble(), (Fix64)random.NextDouble())), (Fix64)random.NextDouble() * 100), new Vector3(i * 2, 3, j * 2)); var mesh = new InstancedMesh(meshShape, transform); //Making the triangles one-sided makes collision detection a bit more robust, since the backsides of triangles won't try to collide with things //and 'pull' them back into the mesh. mesh.Sidedness = TriangleSidedness.Counterclockwise; Space.Add(mesh); game.ModelDrawer.Add(mesh); } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { //Drop a box on the mesh. Space.Add(new Box(new Vector3((i + 1) * 4, 10, (j + 1) * 4), 1, 1, 1, 10)); } } Space.Add(new Box(new Vector3(10, 0, 10), 20, 1, 20)); game.Camera.Position = new Vector3(10, 6, 30); }
public void Load() { InitRenderer(); _resourceManager.Configure(_renderer); var materialInstancing = _resourceManager.GetMaterial("redSpecularInstanced"); var shape = _scene.Shapes.First(); var mesh = shape.Shape as IMesh; var instancedMesh = new InstancedMesh(mesh.Name, mesh); instancedMesh.Material = materialInstancing; for (float i = 0; i < 1; i += 0.1f) { instancedMesh.AddInstance(Matrix4.CreateTranslation(new Vector3(i, 0, 0))); } shape.Shape = instancedMesh; _scene.Configure(_renderer); }
public void ChangleBlockType(Block block, String newBlockTypeName) { // Obtain new block type for the block BlockType newBlockType = null; try { newBlockType = blockTypes[newBlockTypeName]; } catch (KeyNotFoundException exc) { // New block type does not exists in the game, try to load it newBlockType = LoadBlockType(newBlockTypeName, Blocks.Count); } if (newBlockType == null) { // If not able to load new block type, just do nothing. // TODO: handle this error properly return; } // Remove graphical representation of the block String blockTypeName = block.BlockType.Name; InstancedMesh <VertexData> instancedMesh = blockInstancedMeshes[blockTypeName]; instancedMesh.RemoveInstance(block.Instance); // Add new graphical representation of the block InstancedMesh <VertexData> newInstancedMesh = blockInstancedMeshes[newBlockTypeName]; Matrix localPosTransform = Matrix.CreateTranslation(compoundBody.CollisionInformation.LocalPosition); InstancedMesh <VertexData> .Instance instance = newInstancedMesh.AppendInstance(Matrix.CreateScale(block.Scale) * block.Entity.Entry.LocalTransform.Matrix * localPosTransform); // Make changes in block instance block.ChangeBlockType(newBlockType, instance); }
public CStaticModelColliderEntry(InstancedMesh mesh, in Vector3 pos, in Vector3 scale, in Quaternion rot)
///<summary> /// Cleans up the manifold. ///</summary> public override void CleanUp() { mesh = null; convex = null; base.CleanUp(); }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); instancedMesh = null; convex = null; }
public void LoadLevel(String fileName) { // Load level data GameLevelContent levelData = Game.Content.Load <GameLevelContent>(fileName); int blocksCount = levelData.BlocksCount(); // List of blocks chapes for compound body List <CompoundShapeEntry> shapes = new List <CompoundShapeEntry>(); // Create block groups and block physics foreach (BlockGroupData blockGroup in levelData.BlockGroups) { // Create block group LoadBlockType(blockGroup.BlockTypeName, blocksCount); // Create physical representation of blocks in this group Vector3 scale; Quaternion rotation; Vector3 translation; foreach (BlockData blockData in blockGroup.Blocks) { // Extract size, position and orientation values from block data transform blockData.Transform.Decompose(out scale, out rotation, out translation); blockData.Scale = scale; // Create physical shape of the block to be part of compound body of blocks BoxShape blockShape = new BoxShape(scale.X, scale.Y, scale.Z); // Create compound shape entry for compund body of blocks CompoundShapeEntry entry = new CompoundShapeEntry(blockShape, new RigidTransform(translation, rotation)); shapes.Add(entry); } } // Create compound body compoundBody = new CompoundBody(shapes, COMPOUND_BODY_MASS); compoundBody.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous; compoundBody.AngularDamping = COMPOUND_BODY_ANGULAR_DAMPING; // Compound body has Position and LocalPosition (in Collision information) // Position property is position of mass center in global space - it is calculated automatically. // LocalPosition property is position of geometry of the body in its local space. // So in order to create compound body which is rotated around desired position ((0,0,0) for now) // We should switch Position and LocalPosition properties of our compound body. compoundBody.CollisionInformation.LocalPosition = compoundBody.Position; compoundBody.Position = Vector3.Zero; // Add constraint prevents compound body from moving constraint = new MaximumLinearSpeedConstraint(compoundBody, 0.0f); // Create collision group for removed blocks removedBlocksGroup = new CollisionGroup(); // Create blocks int childCollidableIndex = 0; foreach (BlockGroupData blockGroup in levelData.BlockGroups) { Matrix localPosTransform = Matrix.CreateTranslation(compoundBody.CollisionInformation.LocalPosition); foreach (BlockData blockData in blockGroup.Blocks) { // Obtain block type and instanced mesh for the block BlockType blockType = blockTypes[blockGroup.BlockTypeName]; InstancedMesh <VertexData> instancedMesh = blockInstancedMeshes[blockGroup.BlockTypeName]; // Obtain physics body (a part of compound body) for the block CompoundChild child = compoundBody.CollisionInformation.Children[childCollidableIndex]; // Create instance of the block in instanced mesh InstancedMesh <VertexData> .Instance instance = instancedMesh.AppendInstance(Matrix.CreateScale(blockData.Scale) * child.Entry.LocalTransform.Matrix * localPosTransform); // Store new block instance to the list Block block = new Block(blockType, instance, child); blocks.Add(block); block.Scale = blockData.Scale; childCollidableIndex++; } } // Add compound body and its constraints to physics space space.Add(compoundBody); space.Add(constraint); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public StaticGroupDemo(DemosGame game) : base(game) { //Creating a bunch of separate StaticMeshes or kinematic Entity objects for an environment can pollute the broad phase. //This is because the broad phase implementation doesn't have guarantees about what elements can collide, so it has to //traverse the acceleration structure all the way down to pairs to figure it out. That can get expensive! //Individual objects, like StaticMeshes, can have very complicated geometry without hurting the broad phase because the broad phase //has no knowledge of the thousands of triangles in the mesh. The StaticMesh itself knows that the triangles within the mesh //never need to collide, so it never needs to test them against each other. //Similarly, the StaticGroup can be given a bunch of separate collidables. The broad phase doesn't directly know about these child collidables- //it only sees the StaticGroup. The StaticGroup knows that the things inside it can't ever collide with each other, so no tests are needed. //This avoids the performance problem! //To demonstrate, we'll be creating a set of static objects and giving them to a group to manage. var collidables = new List <Collidable>(); //Start with a whole bunch of boxes. These are entity collidables, but without entities! float xSpacing = 6; float ySpacing = 6; float zSpacing = 6; //NOTE: You might notice this demo takes a while to start, especially on the Xbox360. Do not fear! That's due to the creation of the graphics data, not the physics. //The physics can handle over 100,000 static objects pretty easily. The graphics, not so much :) //Try disabling the game.ModelDrawer.Add() lines and increasing the number of static objects. int xCount = 15; int yCount = 7; int zCount = 15; var random = new Random(); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { for (int k = 0; k < zCount; k++) { //Create a transform and the instance of the mesh. var collidable = new ConvexCollidable <BoxShape>(new BoxShape((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f)); //This EntityCollidable isn't associated with an entity, so we must manually tell it where to sit by setting the WorldTransform. //This also updates its bounding box. collidable.WorldTransform = new RigidTransform( new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 3, k * zSpacing - zCount * zSpacing * .5f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100)); collidables.Add(collidable); game.ModelDrawer.Add(collidable); } } } //Now create a bunch of instanced meshes too. xSpacing = 6; ySpacing = 6; zSpacing = 6; xCount = 10; yCount = 2; zCount = 10; Vector3[] vertices; int[] indices; ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("fish"), out vertices, out indices); var meshShape = new InstancedMeshShape(vertices, indices); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { for (int k = 0; k < zCount; k++) { //Create a transform and the instance of the mesh. var transform = new AffineTransform( new Vector3((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100), new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 50, k * zSpacing - zCount * zSpacing * .5f)); var mesh = new InstancedMesh(meshShape, transform); //Making the triangles one-sided makes collision detection a bit more robust, since the backsides of triangles won't try to collide with things //and 'pull' them back into the mesh. mesh.Sidedness = TriangleSidedness.Counterclockwise; collidables.Add(mesh); game.ModelDrawer.Add(mesh); } } } var ground = new ConvexCollidable <BoxShape>(new BoxShape(200, 1, 200)); ground.WorldTransform = new RigidTransform(new Vector3(0, -3, 0), Quaternion.Identity); collidables.Add(ground); game.ModelDrawer.Add(ground); var group = new StaticGroup(collidables); Space.Add(group); //Create a bunch of dynamic boxes to drop on the staticswarm. xCount = 8; yCount = 3; zCount = 8; xSpacing = 3f; ySpacing = 5f; zSpacing = 3f; for (int i = 0; i < xCount; i++) { for (int j = 0; j < zCount; j++) { for (int k = 0; k < yCount; k++) { Space.Add(new Box(new Vector3( xSpacing * i - (xCount - 1) * xSpacing / 2f, 100 + k * (ySpacing), 2 + zSpacing * j - (zCount - 1) * zSpacing / 2f), 1, 1, 1, 10)); } } } game.Camera.Position = new Vector3(0, 60, 90); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public CharacterAddRemoveStressTestDemo(DemosGame game) : base(game) { //Load in mesh data and create the group. Vector3[] staticTriangleVertices; int[] staticTriangleIndices; var playgroundModel = game.Content.Load <Model>("playground"); //This is a little convenience method used to extract vertices and indices from a model. //It doesn't do anything special; any approach that gets valid vertices and indices will work. ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices); var meshShape = new InstancedMeshShape(staticTriangleVertices, staticTriangleIndices); var meshes = new List <Collidable>(); var xSpacing = 400; var ySpacing = 400; var xCount = 3; var yCount = 3; for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { var staticMesh = new InstancedMesh(meshShape, new AffineTransform(Matrix3x3.Identity, new Vector3(-xSpacing * (xCount - 1) / 2 + i * xSpacing, 0, -ySpacing * (yCount - 1) / 2 + j * ySpacing))); staticMesh.Sidedness = TriangleSidedness.Counterclockwise; Space.Add(staticMesh); //meshes.Add(staticMesh); game.ModelDrawer.Add(staticMesh); } } //var group = new StaticGroup(meshes); //Space.Add(group); //Now drop the characters on it! var numColumns = 8; var numRows = 8; var numHigh = 8; float separation = 8; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { for (int k = 0; k < numHigh; k++) { var character = new CharacterController(); character.Body.Position = new Vector3( separation * i - numRows * separation / 2, 40f + k * separation, separation * j - numColumns * separation / 2); characters.Add(character); Space.Add(character); } } } //Now drop the ball-characters on it! numColumns = 8; numRows = 8; numHigh = 8; separation = 8; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { for (int k = 0; k < numHigh; k++) { var character = new SphereCharacterController(); character.Body.Position = new Vector3( separation * i - numRows * separation / 2, 48f + k * separation, separation * j - numColumns * separation / 2); sphereCharacters.Add(character); Space.Add(character); } } } game.Camera.Position = new Vector3(0, 10, 40); //Dump some boxes on top of the characters for fun. numColumns = 8; numRows = 8; numHigh = 8; separation = 8; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { for (int k = 0; k < numHigh; k++) { var toAdd = new Box( new Vector3( separation * i - numRows * separation / 2, 52f + k * separation, separation * j - numColumns * separation / 2), 0.8f, 0.8f, 0.8f, 15); toAdd.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous; Space.Add(toAdd); } } } }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public CharacterStressierTestDemo(DemosGame game) : base(game) { //Load in mesh data and create the group. Vector3[] staticTriangleVertices; int[] staticTriangleIndices; var playgroundModel = game.Content.Load <Model>("playground"); //This is a little convenience method used to extract vertices and indices from a model. //It doesn't do anything special; any approach that gets valid vertices and indices will work. ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices); var meshShape = new InstancedMeshShape(staticTriangleVertices, staticTriangleIndices); var meshes = new List <Collidable>(); var xSpacing = 400; var ySpacing = 400; var xCount = 11; var yCount = 11; for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { var staticMesh = new InstancedMesh(meshShape, new AffineTransform(Matrix3x3.Identity, new Vector3(-xSpacing * (xCount - 1) / 2 + i * xSpacing, 0, -ySpacing * (yCount - 1) / 2 + j * ySpacing))); staticMesh.Sidedness = TriangleSidedness.Counterclockwise; Space.Add(staticMesh); //meshes.Add(staticMesh); game.ModelDrawer.Add(staticMesh); } } //var group = new StaticGroup(meshes); //Space.Add(group); //To demonstrate, we'll be creating a set of static objects and giving them to a group to manage. var collidables = new List <Collidable>(); //Start with a whole bunch of boxes. These are entity collidables, but without entities! xSpacing = 25; ySpacing = 16; float zSpacing = 25; xCount = 25; yCount = 7; int zCount = 25; var random = new Random(); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { for (int k = 0; k < zCount; k++) { //Create a transform and the instance of the mesh. var collidable = new ConvexCollidable <BoxShape>(new BoxShape((float)random.NextDouble() * 25 + 5.5f, (float)random.NextDouble() * 25 + 5.5f, (float)random.NextDouble() * 25 + 5.5f)); //This EntityCollidable isn't associated with an entity, so we must manually tell it where to sit by setting the WorldTransform. //This also updates its bounding box. collidable.WorldTransform = new RigidTransform( new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + -50, k * zSpacing - zCount * zSpacing * .5f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100)); collidables.Add(collidable); game.ModelDrawer.Add(collidable); } } } var group = new StaticGroup(collidables); Space.Add(group); //Now drop the characters on it! var numColumns = 16; var numRows = 16; var numHigh = 16; float separation = 24; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { for (int k = 0; k < numHigh; k++) { var character = new CharacterController(); character.Body.Position = new Vector3( separation * i - numRows * separation / 2, 50f + k * separation, separation * j - numColumns * separation / 2); characters.Add(character); Space.Add(character); } } } game.Camera.Position = new Vector3(0, 10, 40); //Dump some boxes on top of the characters for fun. numColumns = 16; numRows = 16; numHigh = 8; separation = 24; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { for (int k = 0; k < numHigh; k++) { var toAdd = new Box( new Vector3( separation * i - numRows * separation / 2, 52f + k * separation, separation * j - numColumns * separation / 2), 0.8f, 0.8f, 0.8f, 15); toAdd.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous; Space.Add(toAdd); } } } }
public void ChangeBlockType(BlockType blockType, InstancedMesh <VertexData> .Instance instance) { BlockType = blockType; Instance = instance; HitPoints = blockType.HitPoints; }