Beispiel #1
0
        public Simulator(ConnectionState state, Server server)
        {
            server.ReloadMeshes();

            collidableMaterials = new CollidableProperty <SimpleMaterial>();

            this.connectionState = state;
            this.server          = server;
            bufferPool           = new BufferPool();
            var targetThreadCount = Math.Max(1, Environment.ProcessorCount > 4 ? Environment.ProcessorCount - 2 : Environment.ProcessorCount - 1);

            ThreadDispatcher     = new SimpleThreadDispatcher(targetThreadCount);
            narrowPhaseCallbacks = new QuixNarrowPhaseCallbacks()
            {
                CollidableMaterials = collidableMaterials, simulator = this
            };
            Simulation = Simulation.Create(bufferPool, narrowPhaseCallbacks, new QuixPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper());

            CreateMap();
            // Server.Send(state.workSocket, "Hola desde simulator");
            gameLoop = new GameLoop();
            gameLoop.Load(this);


            //CreateNewt();


            thread = new Thread(new ThreadStart(gameLoop.Start));

            commandReader = new CommandReader(this);
            thread.Start();
        }
Beispiel #2
0
        public DebugCollisionItem(ITypeResolver resolver, Vector2 pos)
            : base(resolver, pos)
        {
            collidable = new CollidableProperty(this, 1);

            AddProperty(collidable);
        }
Beispiel #3
0
        private void InitItem(Vector2 carrier1, Vector2 portable1, Vector2?carrier2, Vector2?portable2)
        {
            Item1       = new DebugCarrierItem(carrier1);
            Moving1     = Item1.GetProperty <WalkingProperty>();
            Collidable1 = Item1.GetProperty <CollidableProperty>();
            Carrier1    = Item1.GetProperty <CarrierProperty>();

            Item3       = new DebugPortableItem(portable1);
            Moving3     = Item3.GetProperty <WalkingProperty>();
            Collidable3 = Item3.GetProperty <CollidableProperty>();
            Portable3   = Item3.GetProperty <PortableProperty>();


            if (carrier2.HasValue)
            {
                Item2       = new DebugCarrierItem(carrier2.Value);
                Moving2     = Item2.GetProperty <WalkingProperty>();
                Collidable2 = Item2.GetProperty <CollidableProperty>();
                Carrier2    = Item2.GetProperty <CarrierProperty>();
            }

            if (portable2.HasValue)
            {
                Item4       = new DebugPortableItem(portable2.Value);
                Moving4     = Item4.GetProperty <WalkingProperty>();
                Collidable4 = Item4.GetProperty <CollidableProperty>();
                Portable4   = Item4.GetProperty <PortableProperty>();
            }
        }
Beispiel #4
0
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(20, 10, 20);
            camera.Yaw      = MathHelper.Pi * -1f / 4;
            camera.Pitch    = MathHelper.Pi * 0.05f;
            var masks = new CollidableProperty <ulong>();

            characters = new CharacterControllers(BufferPool);
            Simulation = Simulation.Create(BufferPool, new CharacterNarrowphaseCallbacks(characters), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper());

            var random = new Random(5);

            for (int i = 0; i < 8192; ++i)
            {
                ref var character = ref characters.AllocateCharacter(
                    Simulation.Bodies.Add(
                        BodyDescription.CreateDynamic(
                            new Vector3(250 * (float)random.NextDouble() - 125, 2, 250 * (float)random.NextDouble() - 125), new BodyInertia {
                    InverseMass = 1
                },
                            new CollidableDescription(Simulation.Shapes.Add(new Capsule(0.5f, 1f)), 0.1f),
                            new BodyActivityDescription(-1))));

                character.CosMaximumSlope                 = .707f;
                character.LocalUp                         = Vector3.UnitY;
                character.MaximumHorizontalForce          = 10;
                character.MaximumVerticalForce            = 10;
                character.MinimumSupportContinuationDepth = -0.1f;
                character.MinimumSupportDepth             = -0.01f;
                character.TargetVelocity                  = new Vector2(4, 0);
                character.ViewDirection                   = new Vector3(0, 0, -1);
                character.JumpVelocity                    = 4;
            }
 public void CleanupEngine()
 {
     Item1       = null;
     Moving1     = null;
     Collidable1 = null;
     Item2       = null;
     Moving2     = null;
     Collidable2 = null;
     Map         = null;
     Engine      = null;
 }
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="item">Related Engine Item</param>
        /// <param name="property">Related Engine Property</param>
        public CollidableState(Item item, CollidableProperty property)
            : base(item, property)
        {
            // Bind Fixed to Item Fixed
            Fixed = property.CollisionFixed;
            property.OnCollisionFixedChanged += (i, v) => { Fixed = v; };

            // Bind Mass to Item Mass
            Mass = property.CollisionMass;
            property.OnCollisionMassChanged += (i, v) => { Mass = v; };
        }
        private void InitItem(Vector2 pos1, Vector2?pos2)
        {
            Item1       = new DebugCollisionItem(new Vector2(pos1.X, pos1.Y));
            Moving1     = Item1.GetProperty <WalkingProperty>();
            Collidable1 = Item1.GetProperty <CollidableProperty>();

            if (pos2.HasValue)
            {
                Item2       = new DebugCollisionItem(new Vector2(pos2.Value.X, pos2.Value.Y));
                Moving2     = Item2.GetProperty <WalkingProperty>();
                Collidable2 = Item2.GetProperty <CollidableProperty>();
            }
        }
Beispiel #8
0
        public PhysicsUnit(Item item, Dictionary <int, PhysicsUnit> items)
        {
            this.item  = item;
            this.items = items;
            moving     = item.GetProperty <WalkingProperty>();
            collidable = item.GetProperty <CollidableProperty>();
            carrier    = item.GetProperty <CarrierProperty>();
            portable   = item.GetProperty <PortableProperty>();

            map = item.Engine.Map;

            mapSize = map.GetSize();

            // Attach Item Stuff
            item.CellChanged += item_CellChanged;

            // Attach Moving Stuff
            if (moving != null)
            {
                moving.OnMaximumMoveSpeedChanged += moving_OnMaximumMoveSpeedChanged;
                moving.OnMoveDirectionChanged    += moving_OnMoveDirectionChanged;
                moving.OnMoveSpeedChanged        += moving_OnMoveSpeedChanged;
                moving.MoveMalus = 1;
            }

            // Attach Collision Stuff
            if (collidable != null)
            {
                collidable.OnCollisionMassChanged  += collidable_OnCollisionMassChanged;
                collidable.OnCollisionFixedChanged += collidable_OnCollisionFixedChanged;
            }

            // Attach Carrier Stuff
            if (carrier != null)
            {
                carrier.OnCarrierLoadChanged     += carrier_OnCarrierLoadChanged;
                carrier.OnCarrierStrengthChanged += carrier_OnCarrierStrengthChanged;
            }

            // Attach Portable Stuff
            if (portable != null)
            {
                portable.OnPortableWeightChanged += portable_OnPortableMassChanged;
                portable.OnNewCarrierItem        += portable_OnNewCarrierItem;
                portable.OnLostCarrierItem       += portable_OnLostCarrierItem;
                clusterUnits = new HashSet <PhysicsUnit>();
            }

            Recalc();
        }
Beispiel #9
0
        public PhysicsUnit(Item item, Dictionary<int, PhysicsUnit> items)
        {
            this.item = item;
            this.items = items;
            moving = item.GetProperty<WalkingProperty>();
            collidable = item.GetProperty<CollidableProperty>();
            carrier = item.GetProperty<CarrierProperty>();
            portable = item.GetProperty<PortableProperty>();

            map = item.Engine.Map;

            mapSize = map.GetSize();

            // Attach Item Stuff
            item.CellChanged += item_CellChanged;

            // Attach Moving Stuff
            if (moving != null)
            {
                moving.OnMaximumMoveSpeedChanged += moving_OnMaximumMoveSpeedChanged;
                moving.OnMoveDirectionChanged += moving_OnMoveDirectionChanged;
                moving.OnMoveSpeedChanged += moving_OnMoveSpeedChanged;
                moving.MoveMalus = 1;
            }

            // Attach Collision Stuff
            if (collidable != null)
            {
                collidable.OnCollisionMassChanged += collidable_OnCollisionMassChanged;
                collidable.OnCollisionFixedChanged += collidable_OnCollisionFixedChanged;
            }

            // Attach Carrier Stuff
            if (carrier != null)
            {
                carrier.OnCarrierLoadChanged += carrier_OnCarrierLoadChanged;
                carrier.OnCarrierStrengthChanged += carrier_OnCarrierStrengthChanged;
            }

            // Attach Portable Stuff
            if (portable != null)
            {
                portable.OnPortableWeightChanged += portable_OnPortableMassChanged;
                portable.OnNewCarrierItem += portable_OnNewCarrierItem;
                portable.OnLostCarrierItem += portable_OnLostCarrierItem;
                clusterUnits = new HashSet<PhysicsUnit>();
            }

            Recalc();
        }
Beispiel #10
0
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public AntMovementInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop)
        {
            // Get Walking Property
            walking = Item.GetProperty <WalkingProperty>();
            if (walking == null)
            {
                throw new NotSupportedException("There is no Walking Property");
            }

            // Get Collision Property
            collidable = Item.GetProperty <CollidableProperty>();
            if (collidable == null)
            {
                throw new NotSupportedException("There is no Collidable Property");
            }

            // Handle Collisions with Walls and Borders.
            walking.OnHitBorder += (i, v) => { if (OnHitWall != null)
                                               {
                                                   OnHitWall(v);
                                               }
            };
            walking.OnHitWall += (i, v) => { if (OnHitWall != null)
                                             {
                                                 OnHitWall(v);
                                             }
            };

            // Kollisionen mit anderen Items füllt die Liste der Kollisionsitems
            // und prüft, ob es sich beim getroffenen Item um das Ziel handelt.
            collidable.OnCollision += (i, v) =>
            {
                // Zur Liste der kollidierten Items hinzufügen.
                collidedItems.Add(v.GetItemInfo(Item));

                // Prüfen, ob es sich um das aktuelle Ziel handelt.
                if (CurrentDestination != null &&
                    Item == Item.GetItemFromInfo(CurrentDestination))
                {
                    // Alles anhalten und Reach melden
                    Stop();
                    if (OnTargetReched != null)
                    {
                        OnTargetReched(i.GetItemInfo(Item));
                    }
                }
            };
        }
Beispiel #11
0
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 9, -40);
            camera.Yaw      = MathHelper.Pi;
            camera.Pitch    = 0;
            var filters = new CollidableProperty <SubgroupCollisionFilter>();

            Simulation = Simulation.Create(BufferPool, new SubgroupFilteredCallbacks {
                CollisionFilters = filters
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)));

            int ragdollIndex = 0;
            var spacing      = new Vector3(1.7f, 1.8f, 0.5f);
            int width        = 4;
            int height       = 4;
            int length       = 44;
            var origin       = -0.5f * spacing * new Vector3(width - 1, 0, length - 1) + new Vector3(0, 5f, 0);

            for (int i = 0; i < width; ++i)
            {
                for (int j = 0; j < height; ++j)
                {
                    for (int k = 0; k < length; ++k)
                    {
                        RagdollDemo.AddRagdoll(origin + spacing * new Vector3(i, j, k), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathHelper.Pi * 0.05f), ragdollIndex++, filters, Simulation);
                    }
                }
            }

            var         tubeCenter      = new Vector3(0, 8, 0);
            const int   panelCount      = 20;
            const float tubeRadius      = 6;
            var         panelShape      = new Box(MathF.PI * 2 * tubeRadius / panelCount, 1, 80);
            var         panelShapeIndex = Simulation.Shapes.Add(panelShape);
            var         builder         = new CompoundBuilder(BufferPool, Simulation.Shapes, panelCount + 1);

            for (int i = 0; i < panelCount; ++i)
            {
                var rotation = QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, i * MathHelper.TwoPi / panelCount);
                QuaternionEx.TransformUnitY(rotation, out var localUp);
                var position = localUp * tubeRadius;
                builder.AddForKinematic(panelShapeIndex, new RigidPose(position, rotation), 1);
            }
            builder.AddForKinematic(Simulation.Shapes.Add(new Box(1, 2, panelShape.Length)), new RigidPose(new Vector3(0, tubeRadius - 1, 0)), 0);
            builder.BuildKinematicCompound(out var children);
            var compound = new BigCompound(children, Simulation.Shapes, BufferPool);

            Simulation.Bodies.Add(BodyDescription.CreateKinematic(tubeCenter, new BodyVelocity(default, new Vector3(0, 0, .25f)), new CollidableDescription(Simulation.Shapes.Add(compound), 0.1f), new BodyActivityDescription()));
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(-5f, 5.5f, 5f);
            camera.Yaw      = MathHelper.Pi / 4;
            camera.Pitch    = MathHelper.Pi * 0.15f;

            var filters = new CollidableProperty <DeformableCollisionFilter>();

            Simulation = Simulation.Create(BufferPool, new DeformableCallbacks {
                Filters = filters
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)));

            var   meshContent = content.Load <MeshContent>("Content\\newt.obj");
            float cellSize    = 0.1f;

            DumbTetrahedralizer.Tetrahedralize(meshContent.Triangles, cellSize, BufferPool,
                                               out var vertices, out var vertexSpatialIndices, out var cellVertexIndices, out var tetrahedraVertexIndices);
            var weldSpringiness   = new SpringSettings(30f, 0);
            var volumeSpringiness = new SpringSettings(30f, 1);

            for (int i = 0; i < 5; ++i)
            {
                NewtDemo.CreateDeformable(Simulation, new Vector3(i * 3, 5 + i * 1.5f, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(1, 0, 0), MathF.PI * (i * 0.55f)), 1f, cellSize, weldSpringiness, volumeSpringiness, i, filters, ref vertices, ref vertexSpatialIndices, ref cellVertexIndices, ref tetrahedraVertexIndices);
            }

            BufferPool.Return(ref vertices);
            vertexSpatialIndices.Dispose(BufferPool);
            BufferPool.Return(ref cellVertexIndices);
            BufferPool.Return(ref tetrahedraVertexIndices);

            Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 100, -.5f), 10, Simulation.Shapes, new Sphere(5)));

            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(1500, 1, 1500)), 0.1f)));
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -1.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Sphere(3)), 0.1f)));

            var bulletShape = new Sphere(0.5f);

            bulletShape.ComputeInertia(.25f, out var bulletInertia);
            bulletDescription = BodyDescription.CreateDynamic(RigidPose.Identity, bulletInertia, new CollidableDescription(Simulation.Shapes.Add(bulletShape), 1f), new BodyActivityDescription(0.01f));

            DemoMeshHelper.LoadModel(content, BufferPool, "Content\\newt.obj", new Vector3(20), out var mesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(200, 0.5f, 120), QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, -3 * MathHelper.PiOver4), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f)));
        }
Beispiel #13
0
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 40, 200);
            camera.Yaw      = 0;
            camera.Pitch    = 0;
            //This type of position-based bounciness requires feedback from position error to drive the corrective impulses that make stuff bounce.
            //The briefer a collision is, the more damped the bounce becomes relative to the physical ideal.
            //To counteract this, a substepping timestepper is used. In the demos, we update the simulation at 60hz, so a substep count of 4 means the solver and integrator will run at 240hz.
            //That allows higher stiffnesses to be used since collisions last longer relative to the solver timestep duration.
            //(Note that substepping tends to be an extremely strong simulation stabilizer, so you can usually get away with lower solver iteration counts for better performance.)
            var collidableMaterials = new CollidableProperty <SimpleMaterial>();

            Simulation = Simulation.Create(BufferPool, new BounceCallbacks()
            {
                CollidableMaterials = collidableMaterials
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new SubsteppingTimestepper(4), solverIterationCount: 2);

            var shape = new Sphere(1);

            shape.ComputeInertia(1, out var inertia);
            var ballDescription = BodyDescription.CreateDynamic(RigidPose.Identity, inertia, new CollidableDescription(Simulation.Shapes.Add(shape), 20f), new BodyActivityDescription(1e-2f));

            for (int i = 0; i < 100; ++i)
            {
                for (int j = 0; j < 100; ++j)
                {
                    //We'll drop balls in a grid. From left to right, we increase stiffness, and from back to front (relative to the camera), we'll increase damping.
                    //Note that higher frequency values tend to result in smaller bounces even at 0 damping. This is not physically realistic; it's a byproduct of the solver timestep being too long to properly handle extremely brief contacts.
                    //(Try increasing the substep count above to higher values and watch how the bounce gets closer and closer to equal height across frequency values.)
                    ballDescription.Pose.Position = new Vector3(i * 3 - 99f * 3f / 2f, 100, j * 3 - 230);
                    collidableMaterials.Allocate(Simulation.Bodies.Add(ballDescription)) = new SimpleMaterial {
                        FrictionCoefficient = 1, MaximumRecoveryVelocity = float.MaxValue, SpringSettings = new SpringSettings(5 + 0.25f * i, j * j / 10000f)
                    };
                }
            }

            collidableMaterials.Allocate(Simulation.Statics.Add(new StaticDescription(new Vector3(0, -15f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(2500, 30, 2500)), 0.1f)))) =
                new SimpleMaterial {
                FrictionCoefficient = 1, MaximumRecoveryVelocity = 2, SpringSettings = new SpringSettings(30, 1)
            };
        }
Beispiel #14
0
 public void CleanupEngine()
 {
     Item1       = null;
     Moving1     = null;
     Collidable1 = null;
     Carrier1    = null;
     Item2       = null;
     Moving2     = null;
     Collidable2 = null;
     Carrier2    = null;
     Item3       = null;
     Moving3     = null;
     Collidable3 = null;
     Portable3   = null;
     Item4       = null;
     Moving4     = null;
     Collidable4 = null;
     Portable4   = null;
     Map         = null;
     Engine      = null;
 }
Beispiel #15
0
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(-32f, 20.5f, 61f);
            camera.Yaw      = MathHelper.Pi * 0.3f;
            camera.Pitch    = MathHelper.Pi * -0.05f;

            filters    = new CollidableProperty <SubgroupCollisionFilter>(BufferPool);
            Simulation = Simulation.Create(BufferPool, new SubgroupFilteredCallbacks()
            {
                CollisionFilters = filters
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)));

            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(1500, 1, 1500)), 0.1f)));
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 10, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(70, 20, 80)), 0.1f)));
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 7.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(80, 15, 90)), 0.1f)));
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 5, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(90, 10, 100)), 0.1f)));
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 2.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(100, 5, 110)), 0.1f)));

            //High fidelity simulation isn't super important on this one.
            Simulation.Solver.IterationCount = 2;

            DemoMeshHelper.LoadModel(content, BufferPool, "Content\\newt.obj", new Vector3(30), out var mesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 20, 0), QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, 0), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f)));
        }
Beispiel #16
0
        /// <summary>
        /// Registers Sugar
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterSugar(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Sugar
            typeMapper.RegisterItem <SugarItem, SugarState, SugarInfo>(this, "Sugar");

            // Collidable
            typeMapper.AttachItemProperty <SugarItem, CollidableProperty>(this, "Sugar Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Define mass (Fixed)
                property.CollisionFixed = true;
                property.CollisionMass  = 0f;

                // Bind Collision Radius to the Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <SugarItem, VisibleProperty>(this, "Sugar Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Collectable
            typeMapper.AttachItemProperty <SugarItem, SugarCollectableProperty>(this, "Sugar Collectable"); // TODO: Amounts (SugarMaxCapacity, Math.Min(SugarMaxCapacity, amount))
        }
Beispiel #17
0
        /// <summary>
        /// Registers Anthills
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterAnthill(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Anthill
            typeMapper.RegisterItem <AnthillItem, AnthillState, AnthillInfo>(this, "Anthill");

            // Collision
            typeMapper.AttachItemProperty <AnthillItem, CollidableProperty>(this, "Anthill Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Collision Mass
                property.CollisionFixed = true;
                property.CollisionMass  = 0f;

                // Bind Radius to the Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <AnthillItem, VisibleProperty>(this, "Anthill Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Attackable
            settings.Set <AnthillItem>("Attackable", false, "Enables the possibility to destroy Anthills");
            settings.Set <AnthillItem>("MaxHealth", 1000, "Maximum Health of an Anthill");
            settings.Set <AnthillItem>("Buildable", false, "Can an Anthill build by ants");
            typeMapper.AttachItemProperty <AnthillItem, AttackableProperty>(this, "Anthill Attackable", (i) =>
            {
                // Check Attackable Switch
                if (!i.Settings.GetBool <AnthillItem>("Attackable").Value)
                {
                    return(null);
                }

                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <AnthillItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <AnthillItem>("MaxHealth").Value;

                return(property);
            });

            // Collectable
            typeMapper.AttachItemProperty <AnthillItem, SugarCollectableProperty>(this, "Anthill Sugarsafe"); // TODO: Radius
            typeMapper.AttachItemProperty <AnthillItem, AppleCollectableProperty>(this, "Anthill Applesafe"); // TODO: Radius
        }
Beispiel #18
0
        protected override void RequestDraw()
        {
            if (_level != null)
            {
                DrawPlayground(_level.Map.GetCellCount(), _level.Map.Tiles);

                foreach (var item in _level.Items)
                {
                    float?bodySpeed       = null;
                    float?bodyDirection   = null;
                    float?bodyRadius      = null;
                    float?smellableRadius = null;
                    float?viewRange       = null;
                    float?viewAngle       = null;
                    float?viewDirection   = null;
                    float?attackRange     = null;

                    // Movement
                    if (item.ContainsProperty <WalkingProperty>())
                    {
                        WalkingProperty prop = item.GetProperty <WalkingProperty>();
                        bodySpeed     = prop.Speed;
                        bodyDirection = prop.Direction;
                    }

                    // Kollisionsradius
                    if (item.ContainsProperty <CollidableProperty>())
                    {
                        CollidableProperty prop = item.GetProperty <CollidableProperty>();
                        bodyRadius = prop.CollisionRadius;
                    }

                    // Sicht
                    if (item.ContainsProperty <SightingProperty>())
                    {
                        SightingProperty prop = item.GetProperty <SightingProperty>();
                        viewRange     = prop.ViewRange;
                        viewDirection = prop.ViewDirection.Radian;
                        viewAngle     = prop.ViewAngle;
                    }

                    // Attack
                    if (item.ContainsProperty <AttackerProperty>())
                    {
                        AttackerProperty prop = item.GetProperty <AttackerProperty>();
                        attackRange = prop.AttackRange;
                    }

                    // Stinkender radius
                    if (item.ContainsProperty <SmellableProperty>())
                    {
                        SmellableProperty prop = item.GetProperty <SmellableProperty>();
                        smellableRadius = prop.SmellableRadius;
                    }

                    Color color       = Color.Gray;
                    Color?borderColor = null;

                    // Farbe
                    if (item is AnthillItem)
                    {
                        color = Color.Brown;
                    }
                    else if (item is SugarItem)
                    {
                        color = Color.White;
                    }
                    else if (item is AppleItem)
                    {
                        color = Color.LightGreen;
                    }
                    else if (item is BugItem)
                    {
                        color = Color.Blue;
                    }
                    else if (item is AntItem)
                    {
                        color = Color.LightGray;
                        AntItem ant = item as AntItem;
                        switch (ant.PlayerIndex)
                        {
                        case 0: borderColor = Color.Orange; break;

                        case 1: borderColor = Color.Red; break;

                        case 2: borderColor = Color.Yellow; break;

                        case 3: borderColor = Color.Green; break;

                        case 4: borderColor = Color.Blue; break;

                        case 5: borderColor = Color.Purple; break;

                        case 6: borderColor = Color.White; break;

                        case 7: borderColor = Color.Black; break;
                        }
                    }
                    else if (item is MarkerItem)
                    {
                        color = Color.LightGray;
                        MarkerItem marker = item as MarkerItem;
                        switch (marker.PlayerIndex)
                        {
                        case 0: borderColor = Color.Orange; break;

                        case 1: borderColor = Color.Red; break;

                        case 2: borderColor = Color.Yellow; break;

                        case 3: borderColor = Color.Green; break;

                        case 4: borderColor = Color.Blue; break;

                        case 5: borderColor = Color.Purple; break;

                        case 6: borderColor = Color.White; break;

                        case 7: borderColor = Color.Black; break;
                        }
                    }

                    // Malen
                    DrawItem(item.Id, item.Position,
                             bodyRadius, bodyDirection, bodySpeed, color,
                             viewRange, viewDirection, viewAngle,
                             attackRange, smellableRadius, borderColor);
                }
            }
        }
Beispiel #19
0
        /// <summary>
        /// Registers classic Bugs
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterClassicBug(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Classic Bug
            typeMapper.RegisterItem <ClassicBugItem, BugState, BugInfo>(this, "Classic Bug");

            // Walking
            settings.Set <ClassicBugItem>("MaxSpeed", 2f, "Maximum Speed of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, WalkingProperty>(this, "Classic Bug Walking", (i) =>
            {
                WalkingProperty property = new WalkingProperty(i);

                // Set Walking Speed
                property.MaximumSpeed = i.Settings.GetFloat <ClassicBugItem>("MaxSpeed").Value;

                // Bind Direction to the Items Orientation
                property.Direction    = i.Orientation;
                i.OrientationChanged += (item, v) => { property.Direction = v; };

                return(property);
            });

            // Collision
            settings.Set <ClassicBugItem>("Mass", 10f, "Collision Mass of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, CollidableProperty>(this, "Classic Bug Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Collision Mass
                property.CollisionFixed = false;
                property.CollisionMass  = i.Settings.GetFloat <ClassicBugItem>("Mass").Value;

                // Bind Collision Radius to the Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <ClassicBugItem, VisibleProperty>(this, "Classic Bug Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Sighting
            settings.Set <ClassicBugItem>("ViewRange", 20f, "View Range of a Classic Bug");
            settings.Set <ClassicBugItem>("ViewAngle", 360, "View Angle of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, SightingProperty>(this, "Classic Bug Sighting", (i) =>
            {
                SightingProperty property = new SightingProperty(i);

                // Set View Range and Angle
                property.ViewRange = i.Settings.GetFloat <ClassicBugItem>("ViewRange").Value;
                property.ViewAngle = i.Settings.GetFloat <ClassicBugItem>("ViewAngle").Value;

                // Bind View Direction to the Item Orientation
                property.ViewDirection = i.Orientation;
                i.OrientationChanged  += (item, v) => { property.ViewDirection = v; };

                return(property);
            });

            // Sniffer
            typeMapper.AttachItemProperty <ClassicBugItem, SnifferProperty>(this, "Classic Bug Sniffer");

            // Attackable
            settings.Set <ClassicBugItem>("MaxHealth", 1000, "Maximum Health of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, AttackableProperty>(this, "Classic Bug Attackable", (i) =>
            {
                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <ClassicBugItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <ClassicBugItem>("MaxHealth").Value;

                return(property);
            });

            // Attacker
            settings.Set <ClassicBugItem>("AttackRange", 5f, "Attack Range for a Classic Bug");
            settings.Set <ClassicBugItem>("RecoveryTime", 5, "Recovery Time in Rounds for a Classic Bug");
            settings.Set <ClassicBugItem>("AttackStrength", 10, "Attach Strength for a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, AttackerProperty>(this, "Classic Bug Attacker", (i) =>
            {
                AttackerProperty property   = new AttackerProperty(i);
                property.AttackRange        = i.Settings.GetFloat <ClassicBugItem>("AttackRange").Value;
                property.AttackRecoveryTime = i.Settings.GetInt <ClassicBugItem>("RecoveryTime").Value;
                property.AttackStrength     = i.Settings.GetInt <ClassicBugItem>("AttackStrength").Value;
                return(property);
            });
        }
 public void CleanupEngine()
 {
     Item1 = null;
     Moving1 = null;
     Collidable1 = null;
     Item2 = null;
     Moving2 = null;
     Collidable2 = null;
     Map = null;
     Engine = null;
 }
Beispiel #21
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 5, 10);
            camera.Yaw      = 0;
            camera.Pitch    = 0;

            var properties = new CollidableProperty <CarBodyProperties>();

            //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep
            //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper.
            //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection.
            Simulation = Simulation.Create(BufferPool, new CarCallbacks()
            {
                Properties = properties
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper());

            var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, 2);

            builder.Add(new Box(1.85f, 0.7f, 4.73f), RigidPose.Identity, 10);
            builder.Add(new Box(1.85f, 0.6f, 2.5f), new RigidPose(new Vector3(0, 0.65f, -0.35f)), 0.5f);
            builder.BuildDynamicCompound(out var children, out var bodyInertia, out _);
            builder.Dispose();
            var bodyShape      = new Compound(children);
            var bodyShapeIndex = Simulation.Shapes.Add(bodyShape);
            var wheelShape     = new Cylinder(0.4f, .18f);

            wheelShape.ComputeInertia(0.25f, out var wheelInertia);
            var wheelShapeIndex = Simulation.Shapes.Add(wheelShape);

            const float x      = 0.9f;
            const float y      = -0.1f;
            const float frontZ = 1.7f;
            const float backZ  = -1.7f;

            playerController = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f,
                                                                        new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f,
                                                                        new SpringSettings(5f, 0.7f), QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)),
                                                       forwardSpeed: 75, forwardForce: 6, zoomMultiplier: 2, backwardSpeed: 30, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f);

            //Create a bunch of AI cars to race against.
            const int aiCount = 384;

            BufferPool.Take(aiCount, out aiControllers);


            const int   planeWidth      = 257;
            const float scale           = 3;
            Vector2     terrainPosition = new Vector2(1 - planeWidth, 1 - planeWidth) * scale * 0.5f;

            raceTrack = new RaceTrack {
                QuadrantRadius = (planeWidth - 32) * scale * 0.25f, Center = default
            };
            var random = new Random(5);

            //Add some building-ish landmarks in the middle of each of the four racetrack quadrants.
            for (int i = 0; i < 4; ++i)
            {
                var landmarkCenter = new Vector3((i & 1) * raceTrack.QuadrantRadius * 2 - raceTrack.QuadrantRadius, -20, (i & 2) * raceTrack.QuadrantRadius - raceTrack.QuadrantRadius);
                var landmarkMin    = landmarkCenter - new Vector3(raceTrack.QuadrantRadius * 0.5f, 0, raceTrack.QuadrantRadius * 0.5f);
                var landmarkSpan   = new Vector3(raceTrack.QuadrantRadius, 0, raceTrack.QuadrantRadius);
                for (int j = 0; j < 25; ++j)
                {
                    var buildingShape = new Box(10 + (float)random.NextDouble() * 10, 20 + (float)random.NextDouble() * 20, 10 + (float)random.NextDouble() * 10);
                    Simulation.Statics.Add(new StaticDescription(
                                               new Vector3(0, buildingShape.HalfHeight, 0) + landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()),
                                               QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI),
                                               new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f)));
                }
            }

            Vector3 min  = new Vector3(-planeWidth * scale * 0.45f, 10, -planeWidth * scale * 0.45f);
            Vector3 span = new Vector3(planeWidth * scale * 0.9f, 15, planeWidth * scale * 0.9f);

            for (int i = 0; i < aiCount; ++i)
            {
                //The AI cars are very similar, except... we handicap them a little to make the player good about themselves.
                var position    = min + span * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
                var orientation = QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * MathF.PI * 2);
                aiControllers[i].Controller = new SimpleCarController(SimpleCar.Create(Simulation, properties, new RigidPose(position, orientation), bodyShapeIndex, bodyInertia, 0.5f, wheelShapeIndex, wheelInertia, 2f,
                                                                                       new Vector3(-x, y, frontZ), new Vector3(x, y, frontZ), new Vector3(-x, y, backZ), new Vector3(x, y, backZ), new Vector3(0, -1, 0), 0.25f,
                                                                                       new SpringSettings(5, 0.7f), QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * 0.5f)),
                                                                      forwardSpeed: 50, forwardForce: 5, zoomMultiplier: 2, backwardSpeed: 10, backwardForce: 4, idleForce: 0.25f, brakeForce: 7, steeringSpeed: 1.5f, maximumSteeringAngle: MathF.PI * 0.23f);
                aiControllers[i].LaneOffset = (float)random.NextDouble() * 20 - 10;
            }


            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth,
                                               (int vX, int vY) =>
            {
                var octave0         = (MathF.Sin((vX + 5f) * 0.05f) + MathF.Sin((vY + 11) * 0.05f)) * 1.8f;
                var octave1         = (MathF.Sin((vX + 17) * 0.15f) + MathF.Sin((vY + 19) * 0.15f)) * 0.9f;
                var octave2         = (MathF.Sin((vX + 37) * 0.35f) + MathF.Sin((vY + 93) * 0.35f)) * 0.4f;
                var octave3         = (MathF.Sin((vX + 53) * 0.65f) + MathF.Sin((vY + 47) * 0.65f)) * 0.2f;
                var octave4         = (MathF.Sin((vX + 67) * 1.50f) + MathF.Sin((vY + 13) * 1.5f)) * 0.125f;
                var distanceToEdge  = planeWidth / 2 - Math.Max(Math.Abs(vX - planeWidth / 2), Math.Abs(vY - planeWidth / 2));
                var edgeRamp        = 25f / (distanceToEdge + 1);
                var terrainHeight   = octave0 + octave1 + octave2 + octave3 + octave4;
                var vertexPosition  = new Vector2(vX * scale, vY * scale) + terrainPosition;
                var distanceToTrack = raceTrack.GetDistance(vertexPosition);
                var trackWeight     = MathF.Min(1f, 3f / (distanceToTrack * 0.1f + 1f));
                var height          = trackWeight * -10f + terrainHeight * (1 - trackWeight);
                return(new Vector3(vertexPosition.X, height + edgeRamp, vertexPosition.Y));
            }, new Vector3(1, 1, 1), BufferPool, out var planeMesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -15, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2),
                                                         new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f)));
        }
Beispiel #22
0
        /// <summary>
        /// Registers Apples
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterApple(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Apple
            typeMapper.RegisterItem <AppleItem, AppleState, AppleInfo>(this, "Apple");

            // Collidable
            settings.Set <AppleItem>("Mass", 200f, "Mass of an Apple");
            typeMapper.AttachItemProperty <AppleItem, CollidableProperty>(this, "Apple Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Define Radius
                property.CollisionRadius = AppleItem.AppleInnerRadius;

                // Define Mass
                property.CollisionFixed = false;
                property.CollisionMass  = i.Settings.GetFloat <AppleItem>("Mass").Value;

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <AppleItem, VisibleProperty>(this, "Apple Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Portable
            settings.Set <AppleItem>("Weight", 200f, "Weight of an Apple");
            typeMapper.AttachItemProperty <AppleItem, PortableProperty>(this, "Apple Portable", (i) =>
            {
                PortableProperty property = new PortableProperty(i);

                // Set Weight
                property.PortableWeight = settings.GetFloat <AppleItem>("Weight").Value;

                // Bind Portable Radius to the Item Radius
                property.PortableRadius = i.Radius;
                i.RadiusChanged        += (item, v) => { property.PortableRadius = v; };

                return(property);
            });

            settings.Set <AppleItem>("Collectable", false, "Will an Apple be collectable");
            settings.Set <AppleItem>("Amount", 250, "Amount of Apple Units");
            typeMapper.AttachItemProperty <AppleItem, AppleCollectableProperty>(this, "Apple Collectable", (i) =>
            {
                if (!i.Settings.GetBool <AppleItem>("Collectable").Value)
                {
                    return(null);
                }

                AppleCollectableProperty property = new AppleCollectableProperty(i);
                property.Capacity = i.Settings.GetInt <AppleItem>("Amount").Value;
                property.Amount   = i.Settings.GetInt <AppleItem>("Amount").Value;
                return(property);
            });
        }
        private void InitItem(Vector2 pos1, Vector2? pos2)
        {
            Item1 = new DebugCollisionItem(new Vector2(pos1.X, pos1.Y));
            Moving1 = Item1.GetProperty<WalkingProperty>();
            Collidable1 = Item1.GetProperty<CollidableProperty>();

            if (pos2.HasValue)
            {
                Item2 = new DebugCollisionItem(new Vector2(pos2.Value.X, pos2.Value.Y));
                Moving2 = Item2.GetProperty<WalkingProperty>();
                Collidable2 = Item2.GetProperty<CollidableProperty>();
            }
        }
Beispiel #24
0
 public void Update(Simulation simulation, CollidableProperty <TankDemoBodyProperties> bodyProperties, Random random, long frameIndex, in Vector2 playAreaMin, in Vector2 playAreaMax, int aiIndex, ref QuickList <AITank> aiTanks, ref int projectileCount)
Beispiel #25
0
 public CollidableInfo(Item item, ItemProperty property, Item observer)
     : base(item, property, observer)
 {
     this.property = property as CollidableProperty;
 }
Beispiel #26
0
        protected override void RequestDraw()
        {
            if (_engine != null)
            {
                DrawPlayground(_engine.Map.GetCellCount(), _engine.Map.Tiles);

                foreach (var item in _engine.Items)
                {
                    float?bodySpeed       = null;
                    float?bodyDirection   = null;
                    float?bodyRadius      = null;
                    float?smellableRadius = null;
                    float?viewRange       = null;
                    float?viewAngle       = null;
                    float?viewDirection   = null;
                    float?attackRange     = null;

                    // Movement
                    if (item.ContainsProperty <WalkingProperty>())
                    {
                        WalkingProperty prop = item.GetProperty <WalkingProperty>();
                        bodySpeed     = prop.Speed;
                        bodyDirection = prop.Direction;
                    }

                    // Kollisionsradius
                    if (item.ContainsProperty <CollidableProperty>())
                    {
                        CollidableProperty prop = item.GetProperty <CollidableProperty>();
                        bodyRadius = prop.CollisionRadius;
                    }

                    // Sicht
                    if (item.ContainsProperty <SightingProperty>())
                    {
                        SightingProperty prop = item.GetProperty <SightingProperty>();
                        viewRange     = prop.ViewRange;
                        viewDirection = prop.ViewDirection.Radian;
                        viewAngle     = prop.ViewAngle;
                    }

                    // Attack
                    if (item.ContainsProperty <AttackerProperty>())
                    {
                        AttackerProperty prop = item.GetProperty <AttackerProperty>();
                        attackRange = prop.AttackRange;
                    }

                    // Stinkender radius
                    if (item.ContainsProperty <SmellableProperty>())
                    {
                        SmellableProperty prop = item.GetProperty <SmellableProperty>();
                        smellableRadius = prop.SmellableRadius;
                    }

                    DrawItem(item.Id, item.Position,
                             bodyRadius, bodyDirection, bodySpeed, Color.White,
                             viewRange, viewDirection, viewAngle,
                             attackRange, smellableRadius, null);
                }
            }
        }
Beispiel #27
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 5, 10);
            camera.Yaw      = 0;
            camera.Pitch    = 0;

            bodyProperties = new CollidableProperty <TankDemoBodyProperties>();
            //We assign velocities outside of the timestep to fire bullets, so using the PositionLastTimestepper avoids integrating those velocities into positions before the solver has a chance to intervene.
            //We could have also modified velocities in the PositionFirstTimestepper's BeforeCollisionDetection callback, but it's just a little simpler to do this with very little cost.
            Simulation = Simulation.Create(BufferPool, new TankCallbacks()
            {
                Properties = bodyProperties
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionLastTimestepper());

            var builder = new CompoundBuilder(BufferPool, Simulation.Shapes, 2);

            builder.Add(new Box(1.85f, 0.7f, 4.73f), RigidPose.Identity, 10);
            builder.Add(new Box(1.85f, 0.6f, 2.5f), new RigidPose(new Vector3(0, 0.65f, -0.35f)), 0.5f);
            builder.BuildDynamicCompound(out var children, out var bodyInertia, out _);
            builder.Dispose();
            var bodyShape      = new Compound(children);
            var bodyShapeIndex = Simulation.Shapes.Add(bodyShape);
            var wheelShape     = new Cylinder(0.4f, .18f);

            wheelShape.ComputeInertia(0.25f, out var wheelInertia);
            var wheelShapeIndex = Simulation.Shapes.Add(wheelShape);

            var projectileShape = new Sphere(0.1f);

            projectileShape.ComputeInertia(0.2f, out var projectileInertia);
            var tankDescription = new TankDescription
            {
                Body         = TankPartDescription.Create(10, new Box(4f, 1, 5), RigidPose.Identity, 0.5f, Simulation.Shapes),
                Turret       = TankPartDescription.Create(1, new Box(1.5f, 0.7f, 2f), new RigidPose(new Vector3(0, 0.85f, 0.4f)), 0.5f, Simulation.Shapes),
                Barrel       = TankPartDescription.Create(0.5f, new Box(0.2f, 0.2f, 3f), new RigidPose(new Vector3(0, 0.85f, 0.4f - 1f - 1.5f)), 0.5f, Simulation.Shapes),
                TurretAnchor = new Vector3(0f, 0.5f, 0.4f),
                BarrelAnchor = new Vector3(0, 0.5f + 0.35f, 0.4f - 1f),
                TurretBasis  = Quaternion.Identity,
                TurretServo  = new ServoSettings(1f, 0f, 40f),
                TurretSpring = new SpringSettings(10f, 1f),
                BarrelServo  = new ServoSettings(1f, 0f, 40f),
                BarrelSpring = new SpringSettings(10f, 1f),

                ProjectileShape            = Simulation.Shapes.Add(projectileShape),
                ProjectileSpeed            = 100f,
                BarrelLocalProjectileSpawn = new Vector3(0, 0, -1.5f),
                ProjectileInertia          = projectileInertia,

                LeftTreadOffset    = new Vector3(-1.9f, 0f, 0),
                RightTreadOffset   = new Vector3(1.9f, 0f, 0),
                SuspensionLength   = 1f,
                SuspensionSettings = new SpringSettings(2.5f, 1.5f),
                WheelShape         = wheelShapeIndex,
                WheelInertia       = wheelInertia,
                WheelFriction      = 2f,
                TreadSpacing       = 1f,
                WheelCountPerTread = 5,
                WheelOrientation   = QuaternionEx.CreateFromAxisAngle(Vector3.UnitZ, MathF.PI * -0.5f),
            };

            playerController = new TankController(Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose(new Vector3(0, 10, 0), Quaternion.Identity), tankDescription), 20, 5, 2, 1, 3.5f);


            const int   planeWidth          = 257;
            const float terrainScale        = 3;
            const float inverseTerrainScale = 1f / terrainScale;
            var         terrainPosition     = new Vector2(1 - planeWidth, 1 - planeWidth) * terrainScale * 0.5f;

            random = new Random(5);

            //Add some building-ish landmarks.
            var landmarkMin  = new Vector3(planeWidth * terrainScale * -0.45f, 0, planeWidth * terrainScale * -0.45f);
            var landmarkMax  = new Vector3(planeWidth * terrainScale * 0.45f, 0, planeWidth * terrainScale * 0.45f);
            var landmarkSpan = landmarkMax - landmarkMin;

            for (int j = 0; j < 25; ++j)
            {
                var buildingShape = new Box(10 + (float)random.NextDouble() * 10, 20 + (float)random.NextDouble() * 20, 10 + (float)random.NextDouble() * 10);
                var position      = landmarkMin + landmarkSpan * new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
                Simulation.Statics.Add(new StaticDescription(
                                           new Vector3(0, buildingShape.HalfHeight - 4f + GetHeightForPosition(position.X, position.Z, planeWidth, inverseTerrainScale, terrainPosition), 0) + position,
                                           QuaternionEx.CreateFromAxisAngle(Vector3.UnitY, (float)random.NextDouble() * MathF.PI),
                                           new CollidableDescription(Simulation.Shapes.Add(buildingShape), 0.1f)));
            }

            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeWidth,
                                               (int vX, int vY) =>
            {
                var position2D = new Vector2(vX, vY) * terrainScale + terrainPosition;
                return(new Vector3(position2D.X, GetHeightForPosition(position2D.X, position2D.Y, planeWidth, inverseTerrainScale, terrainPosition), position2D.Y));
            }, new Vector3(1, 1, 1), BufferPool, out var planeMesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0, 0),
                                                         new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f)));

            explosions = new QuickList <Explosion>(32, BufferPool);

            //Create the AI tanks.
            const int aiTankCount = 100;

            aiTanks     = new QuickList <AITank>(aiTankCount, BufferPool);
            playAreaMin = new Vector2(landmarkMin.X, landmarkMin.Z);
            playAreaMax = new Vector2(landmarkMax.X, landmarkMax.Z);
            var playAreaSpan = playAreaMax - playAreaMin;

            for (int i = 0; i < aiTankCount; ++i)
            {
                var horizontalPosition = playAreaMin + new Vector2((float)random.NextDouble(), (float)random.NextDouble()) * playAreaSpan;
                aiTanks.AllocateUnsafely() = new AITank
                {
                    Controller = new TankController(
                        Tank.Create(Simulation, bodyProperties, BufferPool, new RigidPose(
                                        new Vector3(horizontalPosition.X, 10, horizontalPosition.Y),
                                        QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)random.NextDouble() * 0.1f)),
                                    tankDescription), 20, 5, 2, 1, 3.5f),
                    HitPoints = 5
                };
            }
        }
Beispiel #28
0
        /// <summary>
        /// Registers Ants
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterAnt(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Ant Item
            settings.Set <AntItem>("ZickZackAngle", 10, "Correction Angle after Sprint");
            settings.Set <AntItem>("ZickZackRange", 30f, "Distance to go every Sprint");
            settings.Set <AntItem>("RotationSpeed", 20, "Maximum Rotation Angle per Round");
            settings.Set <AntItem>("DropSugar", false, "Will an Ant leave a small Sugar on Drop");
            settings.Set <AntItem>("MarkerDelay", 10, "Time in Rounds between Marker-Drops");
            typeMapper.RegisterItem <AntItem, AntState, AntInfo>(this, "Ant");

            // Walking
            settings.Set <AntItem>("MaxSpeed", 1f, "Maximum Speed of an Ant");
            typeMapper.AttachItemProperty <AntItem, WalkingProperty>(this, "Ant Walking", (i) =>
            {
                WalkingProperty property = new WalkingProperty(i);

                // Set Maximum Speed based on the current Settings
                // TODO: Check for Castes
                property.MaximumSpeed = i.Settings.GetFloat <AntItem>("MaxSpeed").Value;

                // Bind Item Orientation to Walk-Direction
                property.Direction    = i.Orientation;
                i.OrientationChanged += (item, v) => { property.Direction = v; };

                return(property);
            });

            // Collision
            settings.Set <AntItem>("Mass", 1f, "Collision Mass of an Ant");
            typeMapper.AttachItemProperty <AntItem, CollidableProperty>(this, "Ant Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Mass to Settings
                property.CollisionFixed = false;
                property.CollisionMass  = i.Settings.GetFloat <AntItem>("Mass").Value;

                // Bind Collision Radius to Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <AntItem, VisibleProperty>(this, "Ant Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Sighting
            settings.Set <AntItem>("ViewRange", 20f, "View Range of an Ant");
            settings.Set <AntItem>("ViewAngle", 360, "View Angle of an Ant");
            typeMapper.AttachItemProperty <AntItem, SightingProperty>(this, "Ant Sighting", (i) =>
            {
                SightingProperty property = new SightingProperty(i);

                // Set View Range and Angle
                property.ViewRange = i.Settings.GetFloat <AntItem>("ViewRange").Value;
                property.ViewAngle = i.Settings.GetFloat <AntItem>("ViewAngle").Value;

                // Bind View Direction to the Item Orientation
                property.ViewDirection = i.Orientation;
                i.OrientationChanged  += (item, v) => { property.ViewDirection = v; };

                return(property);
            });

            // Sniffer
            typeMapper.AttachItemProperty <AntItem, SnifferProperty>(this, "Ant Sniffer");

            // Carrier
            settings.Set <AntItem>("CarrierStrength", 10f, "Carrier Strength of an Ant");
            typeMapper.AttachItemProperty <AntItem, CarrierProperty>(this, "Ant Carrier", (i) =>
            {
                CarrierProperty property = new CarrierProperty(i);
                property.CarrierStrength = i.Settings.GetFloat <AntItem>("CarrierStrength").Value;
                return(property);
            });

            // Attackable
            settings.Set <AntItem>("MaxHealth", 100f, "Maximum Health for an Ant");
            typeMapper.AttachItemProperty <AntItem, AttackableProperty>(this, "Ant Attackable", (i) =>
            {
                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <AntItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <AntItem>("MaxHealth").Value;

                return(property);
            });

            // Attacker
            settings.Set <AntItem>("AttackRange", 3f, "Attack Range for a Bug");
            settings.Set <AntItem>("RecoveryTime", 2, "Recovery Time in Rounds for a Bug");
            settings.Set <AntItem>("AttackStrength", 5, "Attach Strength for a Bug");
            typeMapper.AttachItemProperty <AntItem, AttackerProperty>(this, "Ant Attacker", (i) =>
            {
                AttackerProperty property   = new AttackerProperty(i);
                property.AttackRange        = i.Settings.GetFloat <AntItem>("AttackRange").Value;
                property.AttackRecoveryTime = i.Settings.GetInt <AntItem>("RecoveryTime").Value;
                property.AttackStrength     = i.Settings.GetInt <AntItem>("AttackStrength").Value;
                return(property);
            });

            // Collector
            settings.Set <AntItem>("SugarCapacity", 5, "Maximum Capacity for Sugar");
            settings.Set <AntItem>("AppleCapacity", 2, "Maximum Capacity for Apple");
            typeMapper.AttachItemProperty <AntItem, SugarCollectorProperty>(this, "Ant Sugar Collectable", (i) =>
            {
                SugarCollectorProperty property = new SugarCollectorProperty(i);
                property.Capacity = i.Settings.GetInt <AntItem>("SugarCapacity").Value;
                return(property);
            });
            typeMapper.AttachItemProperty <AntItem, AppleCollectorProperty>(this, "Ant Apple Collectable", (i) =>
            {
                AppleCollectorProperty property = new AppleCollectorProperty(i);
                property.Capacity = i.Settings.GetInt <AntItem>("AppleCapacity").Value;
                return(property);
            }); // TODO: Optional, wenn _settings.ANT_APPLECOLLECT | _settings.ANT_APPLE_CAPACITY, 0);
        }
Beispiel #29
0
 public CollidableInfo(Item item, ItemProperty property, Item observer) : base(item, property, observer)
 {
     this.property = property as CollidableProperty;
 }