/AAEngine.Box2D/Box2DSpatialComponent.cs
C# | 399 lines | 339 code | 47 blank | 13 comment | 57 complexity | 478bcae7c17712c68ccae037a96f178c MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- /*******************************************************************************
- * AAEngine
- * Copyright (c) 2010 Mike Jarosch
- *
- * Original source PushButton Engine:
- * Copyright (C) 2009 PushButton Labs, LLC
- * For more information see http://www.pushbuttonengine.com
- *
- * This file is licensed under the terms of the MIT license, which is included
- * in the "MIT License.txt" file at the root directory of this SDK.
- ******************************************************************************/
-
- using System;
- using Microsoft.Xna.Framework;
- using Box2D.XNA;
- using AAEngine.Engine;
- using AAEngine.Engine.Core;
- using AAEngine.Engine.Debug;
- using AAEngine.Engine.Entities;
- using AAEngine.Rendering2D;
-
- namespace AAEngine.Box2D
- {
- public class Box2DSpatialComponent : EntityComponent, IMobileSpatialObject2D
- {
- public Action<Box2DSpatialComponent> OnAddedCallback { get; set; }
-
- private Box2DManagerComponent _manager;
- private ObjectType _collidesWithTypes;
- private ObjectType _collisionType;
-
- private Vector2 _size = new Vector2(10, 10);
-
- private bool _canMove = true;
- private bool _canRotate = true;
-
- private Vector2 _linearVelocity = Vector2.Zero;
- private float _angularVelocity = 0;
- private bool _canSleep = true;
-
- private CollisionShape[] _collisionShapes;
-
- private Body _body;
- private BodyDef _bodyDef = new BodyDef();
-
- public Box2DManagerComponent SpatialManager
- {
- get { return _manager; }
- set
- {
- if (_body != null)
- {
- Logger.Warn(this, "set_SpatialManager", "The manager can only be set before the component is registered.");
- return;
- }
- _manager = value;
- }
- }
-
- public Body Body { get { return _body; } }
-
- public ObjectType ObjectMask { get { return _collidesWithTypes; } }
-
- public Box WorldExtents
- {
- get
- {
- Vector2 halfSize = _size * 0.5f;
-
- Vector2 min = new Vector2(Position.X - halfSize.X, Position.Y - halfSize.Y);
- Vector2 max = new Vector2(Position.X + halfSize.X, Position.Y + halfSize.Y);
-
- return new Box(min, max);
- }
- }
-
- public bool CastRay(Vector2 start, Vector2 end, ObjectType mask, ref RayHitInfo result)
- {
- throw new NotImplementedException();
- }
-
- public bool PointOccupied(Vector2 position, ObjectType mask, IScene2D scene)
- {
- ContainmentType contains = WorldExtents.Contains(position);
- return contains == ContainmentType.Contains || contains == ContainmentType.Intersects;
- }
-
- public ObjectType CollisionType
- {
- get { return _collisionType; }
- set
- {
- _collisionType = value;
- if (_body != null)
- {
- BuildCollisionShapes();
- }
- }
- }
-
- public ObjectType CollidesWithTypes
- {
- get { return _collidesWithTypes; }
- set
- {
- _collidesWithTypes = value;
- if (_body != null)
- {
- BuildCollisionShapes();
- }
- }
- }
-
- public Vector2 Position
- {
- get
- {
- if (_body != null)
- {
- Vector2 pos = _body.GetPosition();
- return new Vector2(pos.X * _manager.Scale, pos.Y * _manager.Scale);
- }
- return _bodyDef.position;
- }
- set
- {
- _bodyDef.position = value;
-
- if (_body != null)
- {
- value *= _manager.InverseScale;
- _body.SetTransform(value, _body.GetAngle());
- }
- }
- }
-
- public float Rotation
- {
- get
- {
- float rotation = _bodyDef.angle;
- if (_body != null)
- {
- rotation = _body.GetAngle();
- }
-
- return MathHelper.ToDegrees(rotation);
- }
- set
- {
- float rotation = MathHelper.ToRadians(value);
- _bodyDef.angle = rotation;
- if (_body != null)
- {
- _body.SetTransform(_body.GetPosition(), rotation);
- }
- }
- }
-
- public Vector2 Size
- {
- get { return _size; }
- set
- {
- _size = value;
- if (_body != null)
- {
- BuildCollisionShapes();
- }
- }
- }
-
- public Vector2 LinearVelocity
- {
- get
- {
- if (_body != null)
- {
- _linearVelocity = _body.GetLinearVelocity() * _manager.Scale;
- }
- return _linearVelocity;
- }
- set
- {
- _linearVelocity = value;
-
- if (_body != null)
- {
- Vector2 velocity = _linearVelocity * _manager.InverseScale;
- _body.SetLinearVelocity(velocity);
- }
- }
- }
-
- public float AngularVelocity
- {
- get
- {
- if (_body != null)
- {
- _angularVelocity = MathHelper.ToDegrees(_body.GetAngularVelocity());
- }
-
- return _angularVelocity;
- }
- set
- {
- _angularVelocity = value;
-
- if (_body != null)
- {
- _body.SetAngularVelocity(MathHelper.ToRadians(value));
- }
- }
- }
-
- public bool CanMove
- {
- get { return _canMove; }
- set
- {
- _canMove = value;
-
- //_bodyDef.type = _canMove ? BodyType.Dynamic : BodyType.Static;
- if (_body != null)
- {
- UpdateMass();
- //_body.SetType(_canMove ? BodyType.Dynamic : BodyType.Static);
- }
- }
- }
-
- public bool CanRotate
- {
- get { return _canRotate; }
- set
- {
- _canRotate = value;
- if (_body != null)
- {
- UpdateMass();
- }
- }
- }
-
- public bool CanSleep
- {
- get { return _canSleep; }
- set
- {
- _canSleep = value;
- _bodyDef.allowSleep = value;
- if (_body != null)
- {
- _body.AllowSleeping(value);
- }
- }
- }
-
- public bool CollidesContinuously
- {
- get
- {
- if (_body != null)
- {
- return _body.IsBullet;
- }
- return _bodyDef.bullet;
- }
- set
- {
- _bodyDef.bullet = value;
- if (_body != null)
- {
- _body.SetBullet(value);
- }
- }
- }
-
- public BodyType BodyType
- {
- get
- {
- if (_body != null)
- {
- return _body.GetType();
- }
- return _bodyDef.type;
- }
- set
- {
- _bodyDef.type = value;
- if (_body != null)
- {
- _body.SetType(value);
- }
- }
- }
-
- public CollisionShape[] CollisionShapes
- {
- get { return _collisionShapes; }
- set
- {
- _collisionShapes = value;
- if (_body != null)
- {
- BuildCollisionShapes();
- }
- }
- }
-
- public void BuildCollisionShapes()
- {
- if (_body == null)
- {
- Logger.Warn(this, "BuildCollisionShapes", "Cannot build collision shapes prior to registration.");
- return;
- }
-
- Fixture fixture = _body.GetFixtureList();
- while (fixture != null)
- {
- Fixture nextFixture = fixture.GetNext();
- _body.DestroyFixture(fixture);
- fixture = nextFixture;
- }
-
- if (_collisionShapes != null)
- {
- foreach (CollisionShape shape in _collisionShapes)
- {
- _body.CreateFixture(shape.CreateFixture(this));
- }
- }
-
- UpdateMass();
- }
-
- public void UpdateMass()
- {
- _body.ResetMassData();
- if (!_canMove || !_canRotate)
- {
- MassData mass = new MassData();
- mass.center = _body.GetLocalCenter();
- if (_canMove)
- {
- mass.mass = _body.GetMass();
- }
- else
- {
- mass.mass = 0;
- }
-
- if (_canRotate)
- {
- mass.I = _body.GetInertia();
- }
- else
- {
- mass.I = 0;
- }
- _body.SetMassData(ref mass);
- }
- }
-
- public override void OnAdd()
- {
- if (_manager == null)
- {
- Logger.Warn(this, "OnAdd", "A Box2DSpatialComponent cannot be registered without a manager.");
- return;
- }
-
- _bodyDef.position *= _manager.InverseScale;
- _bodyDef.userData = this;
-
- _manager.Add(_bodyDef, (Body body) =>
- {
- _body = body;
- _bodyDef.position *= _manager.Scale;
-
- BuildCollisionShapes();
-
- if (OnAddedCallback != null)
- {
- OnAddedCallback(this);
- }
- });
- }
-
- public override void OnRemove()
- {
- _manager.Remove(_body);
- _body = null;
- }
- }
- }