Browse Source

Add Box collision shape.

aster2013 11 years ago
parent
commit
5bb12f4a2d

+ 0 - 7
Source/Engine/LuaScript/pkgs/Urho2D/CollisionShape2D.pkg

@@ -10,13 +10,6 @@ class CollisionShape2D : Component
     void SetFriction(float friction);
     void SetRestitution(float restitution);
 
-    void SetCircle(float radius, const Vector2& center = Vector2::ZERO);
-    void SetBox(const Vector2& halfSize, const Vector2& center = Vector2::ZERO);
-    void SetBox(float halfWidth, float halfHeight, const Vector2& center = Vector2::ZERO);
-    void SetChain(const PODVector<Vector2>& vertices);
-    void SetPolygon(const PODVector<Vector2>& vertices);
-    void SetEdge(const Vector2& vertex1, const Vector2& vertex2);
-
     bool IsSensor() const;
     unsigned short GetCategoryBits() const;
     unsigned short GetMaskBits() const;

+ 103 - 0
Source/Engine/Urho2D/CollisionBox2D.cpp

@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Context.h"
+#include "CollisionBox2D.h"
+#include "PhysicsUtils2D.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+extern const char* URHO2D_CATEGORY;
+static const Vector2 DEFAULT_BOX_SIZE(0.01f, 0.01f);
+
+CollisionBox2D::CollisionBox2D(Context* context) : CollisionShape2D(context),
+    size_(DEFAULT_BOX_SIZE),
+    center_(Vector2::ZERO)
+{
+    boxShape_.SetAsBox(size_.x_ * 0.5f, size_.y_ * 0.5f);
+    fixtureDef_.shape = &boxShape_;
+}
+
+CollisionBox2D::~CollisionBox2D()
+{
+
+}
+
+void CollisionBox2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<CollisionBox2D>(URHO2D_CATEGORY);
+
+    REF_ACCESSOR_ATTRIBUTE(CollisionBox2D, VAR_VECTOR2, "Size", GetSize, SetSize, Vector2, DEFAULT_BOX_SIZE, AM_DEFAULT);
+    REF_ACCESSOR_ATTRIBUTE(CollisionBox2D, VAR_VECTOR2, "Center", GetCenter, SetCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
+    
+    COPY_BASE_ATTRIBUTES(CollisionBox2D, CollisionShape2D);
+}
+
+void CollisionBox2D::SetSize(const Vector2& size)
+{
+    if (size == size_)
+        return;
+
+    size_ = size;
+
+    MarkNetworkUpdate();
+    RecreateFixture();
+}
+
+void CollisionBox2D::SetSize(float width, float height)
+{
+    SetSize(Vector2(width, height));
+}
+
+void CollisionBox2D::SetCenter(const Vector2& center)
+{
+    if (center == center_)
+        return;
+
+    center_ = center;
+
+    MarkNetworkUpdate();
+    RecreateFixture();
+}
+
+void CollisionBox2D::SetCenter(float x, float y)
+{
+    SetCenter(Vector2(x, y));
+}
+
+void CollisionBox2D::RecreateFixture()
+{
+    ReleaseFixture();
+    
+    if (center_ == Vector2::ZERO)
+        boxShape_.SetAsBox(size_.x_ * 0.5f, size_.y_ * 0.5f);
+    else
+        boxShape_.SetAsBox(size_.x_ * 0.5f, size_.y_ * 0.5f, ToB2Vec2(center_), 0.0f);
+
+    CreateFixture();
+}
+
+}

+ 69 - 0
Source/Engine/Urho2D/CollisionBox2D.h

@@ -0,0 +1,69 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "CollisionShape2D.h"
+
+namespace Urho3D
+{
+
+/// 2D box collision component.
+class URHO3D_API CollisionBox2D : public CollisionShape2D
+{
+    OBJECT(CollisionBox2D);
+
+public:
+    /// Construct.
+    CollisionBox2D(Context* scontext);
+    /// Destruct.
+    virtual ~CollisionBox2D();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Set size.
+    void SetSize(const Vector2& size);
+    /// Set size.
+    void SetSize(float width, float height);
+    /// Set center.
+    void SetCenter(const Vector2& center);
+    /// Set center.
+    void SetCenter(float x, float y);
+
+    /// Return size.
+    const Vector2& GetSize() const { return size_; }
+    /// Return center.
+    const Vector2& GetCenter() const { return center_; }
+
+private:
+    /// Recreate fixture.
+    void RecreateFixture();
+
+    /// Box shape.
+    b2PolygonShape boxShape_;
+    /// Size.
+    Vector2 size_;
+    /// Center
+    Vector2 center_;
+};
+
+}

+ 3 - 100
Source/Engine/Urho2D/CollisionShape2D.cpp

@@ -48,13 +48,10 @@ CollisionShape2D::~CollisionShape2D()
         rigidBody_->RemoveCollisionShape2D(this);
 
     ReleaseFixture();
-    ReleaseFixtureShape();
 }
 
 void CollisionShape2D::RegisterObject(Context* context)
 {
-    context->RegisterFactory<CollisionShape2D>(URHO2D_CATEGORY);
-
     ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_BOOL, "Sensor", IsSensor, SetSensor, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_INT, "Category Bits", GetCategoryBits, SetCategoryBits, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_INT, "Mask Bits", GetMaskBits, SetMaskBits, int, 0, AM_DEFAULT);
@@ -187,100 +184,14 @@ void CollisionShape2D::SetRestitution(float restitution)
     MarkNetworkUpdate();
 }
 
-void CollisionShape2D::SetCircle(float radius, const Vector2& center)
-{
-    ReleaseFixtureShape();
-
-    b2CircleShape* shape = new b2CircleShape;
-    shape->m_radius = radius;
-    shape->m_p = ToB2Vec2(center);
-
-    fixtureDef_.shape = shape;
-
-    fixtureDirty_ = true;
-    MarkNetworkUpdate();
-}
-
-void CollisionShape2D::SetBox(const Vector2& halfSize, const Vector2& center)
-{
-    ReleaseFixtureShape();
-
-    b2PolygonShape* shape = new b2PolygonShape;
-    if (center == Vector2::ZERO)
-        shape->SetAsBox(halfSize.x_, halfSize.y_);
-    else
-        shape->SetAsBox(halfSize.x_, halfSize.y_, ToB2Vec2(center), 0.0f);
-
-    fixtureDef_.shape = shape;
-
-    fixtureDirty_ = true;
-    MarkNetworkUpdate();
-}
-
-void CollisionShape2D::SetBox(float halfWidth, float halfHeight, const Vector2& center)
-{
-    SetBox(Vector2(halfWidth, halfHeight), center);
-}
-
-void CollisionShape2D::SetChain(const PODVector<Vector2>& vertices)
-{
-    ReleaseFixtureShape();
-
-    unsigned count = vertices.Size();
-    if (!count)
-        return;
-    
-    b2ChainShape* shape = new b2ChainShape;
-    b2Vec2* points = new b2Vec2[count];
-    for (unsigned i = 0; i < count; ++i)
-        points[i] = ToB2Vec2(vertices[i]);
-    shape->CreateChain(points, count);
-    delete [] points;
-
-    fixtureDef_.shape = shape;
-
-    fixtureDirty_ = true;
-    MarkNetworkUpdate();
-}
-
-void CollisionShape2D::SetPolygon(const PODVector<Vector2>& vertices)
-{
-    ReleaseFixtureShape();
-
-    unsigned count = Min(b2_maxPolygonVertices, vertices.Size());
-    if (!count)
-        return;
-
-    b2PolygonShape* shape = new b2PolygonShape;
-    b2Vec2* points = new b2Vec2[count];
-    for (unsigned i = 0; i < count; ++i)
-        points[i] = ToB2Vec2(vertices[i]);
-    shape->Set(points, count);
-    delete [] points;
-
-    fixtureDef_.shape = shape;
-
-    fixtureDirty_ = true;
-    MarkNetworkUpdate();
-}
-
-void CollisionShape2D::SetEdge(const Vector2& vertex1, const Vector2& vertex2)
-{
-    ReleaseFixtureShape();
-
-    b2EdgeShape* shape = new b2EdgeShape;
-    shape->Set(ToB2Vec2(vertex1), ToB2Vec2(vertex2));
-    fixtureDef_.shape = shape;
-
-    fixtureDirty_ = true;
-    MarkNetworkUpdate();
-}
-
 void CollisionShape2D::CreateFixture()
 {
     if (fixture_)
         return;
 
+    if (!fixtureDef_.shape)
+        return;
+
     if (!rigidBody_)
         return;
 
@@ -319,14 +230,6 @@ void CollisionShape2D::ReleaseFixture()
     fixture_ = 0;
 }
 
-void CollisionShape2D::ReleaseFixtureShape()
-{
-    if (!fixtureDef_.shape)
-        return;
-    delete fixtureDef_.shape;
-    fixtureDef_.shape = 0;
-}
-
 float CollisionShape2D::GetMass() const
 {
     if (!fixture_)

+ 2 - 17
Source/Engine/Urho2D/CollisionShape2D.h

@@ -61,19 +61,6 @@ public:
     /// Set restitution .
     void SetRestitution(float restitution);
 
-    /// Set circle.
-    void SetCircle(float radius, const Vector2& center = Vector2::ZERO);
-    /// Set box.
-    void SetBox(const Vector2& halfSize, const Vector2& center = Vector2::ZERO);
-    /// Set box.
-    void SetBox(float halfWidth, float halfHeight, const Vector2& center = Vector2::ZERO);
-    /// Set chain.
-    void SetChain(const PODVector<Vector2>& vertices);
-    /// Set polygon.
-    void SetPolygon(const PODVector<Vector2>& vertices);
-    /// Set edge.
-    void SetEdge(const Vector2& vertex1, const Vector2& vertex2);
-    
     /// Create fixture.
     void CreateFixture();
     /// Update fixture.
@@ -107,12 +94,10 @@ public:
     /// Return is fixture dirty.
     bool IsFixtureDirty() const { return fixtureDirty_; }
 
-private:
+protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
-    /// Release fixture shape.
-    void ReleaseFixtureShape();
-
+    
     /// Rigid body.
     WeakPtr<RigidBody2D> rigidBody_;
     /// Fixture def.

+ 2 - 0
Source/Engine/Urho2D/Urho2D.cpp

@@ -23,6 +23,7 @@
 #include "Precompiled.h"
 #include "AnimatedSprite2D.h"
 #include "Animation2D.h"
+#include "CollisionBox2D.h"
 #include "CollisionShape2D.h"
 #include "Drawable2D.h"
 #include "ParticleEmitter2D.h"
@@ -55,6 +56,7 @@ void RegisterUrho2DLibrary(Context* context)
     PhysicsWorld2D::RegisterObject(context);
     RigidBody2D::RegisterObject(context);
     CollisionShape2D::RegisterObject(context);
+    CollisionBox2D::RegisterObject(context);
 }
 
 }

+ 5 - 5
Source/Samples/27_Urho2DPhysics/Urho2DPhysics.cpp

@@ -21,7 +21,7 @@
 //
 
 #include "Camera.h"
-#include "CollisionShape2D.h"
+#include "CollisionBox2D.h"
 #include "CoreEvents.h"
 #include "DebugRenderer.h"
 #include "Engine.h"
@@ -101,8 +101,8 @@ void Urho2DPhysics::CreateScene()
     groundNode->SetPosition(Vector3(0.0f, -3.0f, 0.0f));
     RigidBody2D* groundBody = groundNode->CreateComponent<RigidBody2D>();
 
-    CollisionShape2D* groundShape = groundNode->CreateComponent<CollisionShape2D>();
-    groundShape->SetBox(Vector2(10.0f, 0.05f));
+    CollisionBox2D* groundShape = groundNode->CreateComponent<CollisionBox2D>();
+    groundShape->SetSize(Vector2(20.0f, 0.1f));
     groundShape->SetFriction(0.5f);
 
     for (unsigned i = 0; i < 100; ++i)
@@ -114,8 +114,8 @@ void Urho2DPhysics::CreateScene()
         RigidBody2D* boxBody = boxNode->CreateComponent<RigidBody2D>();
         boxBody->SetBodyType(BT_DYNAMIC);
 
-        CollisionShape2D* boxShape = boxNode->CreateComponent<CollisionShape2D>();
-        boxShape->SetBox(Vector2(0.16f, 0.16f));
+        CollisionBox2D* boxShape = boxNode->CreateComponent<CollisionBox2D>();
+        boxShape->SetSize(Vector2(0.32f, 0.32f));
         // Set the box density to be non-zero, so it will be dynamic.
         boxShape->SetDensity(1.0f);
         // Override the default friction.