Przeglądaj źródła

Applied physics patch from Magic.Lixin.
Added selection only -mode to editor. This changes the key mappings.

Lasse Öörni 12 lat temu
rodzic
commit
9964055dda

+ 3 - 3
Bin/Data/Scripts/Editor/EditorGizmo.as

@@ -140,7 +140,7 @@ void PositionGizmo()
         lastGizmoMode = editMode;
     }
 
-    gizmo.visible = true;
+    gizmo.visible = editMode != EDIT_SELECT;
 }
 
 void ResizeGizmo()
@@ -176,7 +176,7 @@ void GizmoMoved()
 
 void UseGizmo()
 {
-    if (gizmo is null || !gizmo.visible)
+    if (gizmo is null || !gizmo.visible || editMode == EDIT_SELECT)
         return;
 
     IntVector2 pos = ui.cursorPosition;
@@ -268,7 +268,7 @@ void UseGizmo()
 
 bool IsGizmoSelected()
 {
-    return gizmoAxisX.selected || gizmoAxisY.selected || gizmoAxisZ.selected;
+    return gizmo !is null && gizmo.visible && (gizmoAxisX.selected || gizmoAxisY.selected || gizmoAxisZ.selected);
 }
 
 bool MoveNodes(Vector3 adjust)

+ 6 - 4
Bin/Data/Scripts/Editor/EditorUI.as

@@ -527,21 +527,23 @@ void HandleKeyDown(StringHash eventType, VariantMap& eventData)
             editMode = EDIT_ROTATE;
         else if (key == '3')
             editMode = EDIT_SCALE;
-        else if (key == '4')
-            axisMode = AxisMode(axisMode ^ AXIS_LOCAL);
+        if (key == '4')
+            editMode = EDIT_SELECT;
         else if (key == '5')
+            axisMode = AxisMode(axisMode ^ AXIS_LOCAL);
+        else if (key == '6')
         {
             --pickMode;
             if (pickMode < PICK_GEOMETRIES)
                 pickMode = MAX_PICK_MODES - 1;
         }
-        else if (key == '6')
+        else if (key == '7')
         {
             ++pickMode;
             if (pickMode >= MAX_PICK_MODES)
                 pickMode = PICK_GEOMETRIES;
         }
-        else if (key == '7')
+        else if (key == 'W')
         {
             fillMode = FillMode(fillMode + 1);
             if (fillMode > FILL_POINT)

+ 6 - 4
Bin/Data/Scripts/Editor/EditorView.as

@@ -7,7 +7,8 @@ enum EditMode
 {
     EDIT_MOVE = 0,
     EDIT_ROTATE,
-    EDIT_SCALE
+    EDIT_SCALE,
+    EDIT_SELECT
 }
 
 enum AxisMode
@@ -50,7 +51,8 @@ Array<int> pickModeDrawableFlags = {
 Array<String> editModeText = {
     "Move",
     "Rotate",
-    "Scale"
+    "Scale",
+    "Select"
 };
 
 Array<String> axisModeText = {
@@ -210,7 +212,7 @@ void UpdateView(float timeStep)
     }
 
     // Move/rotate/scale object
-    if (!editNodes.empty && ui.focusElement is null && input.keyDown[KEY_LCTRL])
+    if (!editNodes.empty && editMode != EDIT_SELECT && ui.focusElement is null && input.keyDown[KEY_LCTRL])
     {
         Vector3 adjust(0, 0, 0);
         if (input.keyDown[KEY_UP])
@@ -270,7 +272,7 @@ void UpdateView(float timeStep)
 
 void SteppedObjectManipulation(int key)
 {
-    if (editNodes.empty)
+    if (editNodes.empty || editMode == EDIT_SELECT)
         return;
 
     // Do not react in non-snapped mode, because that is handled in frame update

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar.as

@@ -217,7 +217,7 @@ void CreateOverlays()
     sight.SetSize(height, height);
     ui.root.AddChild(sight);
 
-    Font@ font = cache.GetResource("Font", "Fonts/BlueHighway.ttf");
+    Font@ font = cache.GetResource("Font", "Fonts/Arial.fnt");
 
     scoreText = Text();
     scoreText.SetFont(font, 17);

+ 7 - 6
Docs/GettingStarted.dox

@@ -646,11 +646,11 @@ Right mouse     - Hold down and move mouse to rotate camera
 
 WSAD or arrows  - Move
 Shift+WSAD      - Move faster
-Ctrl+1,2,3      - Select manipulation mode: move/rotate/scale
-Ctrl+4          - Toggle between world and local axes manipulation
-Ctrl+5,6        - Cycle through components to pick: geometries, lights, zones,
+Ctrl+1,2,3      - Object manipulation mode: move/rotate/scale
+Ctrl+4          - Object selection mode, no manipulation
+Ctrl+5          - Toggle between world and local axes manipulation
+Ctrl+6,7        - Cycle through components to pick: geometries, lights, zones,
                   collision shapes
-Ctrl+7          - Cycle through solid, wireframe and point rendering
 Ctrl+arrows     - Manipulate node in X & Z directions
 Ctrl+pgup/pgdn  - Manipulate node in Y direction
 Ctrl+plus/minus - Scale node uniformly (scale mode only)
@@ -660,9 +660,10 @@ Ctrl+Shift+S    - Save scene as
 Ctrl+A          - Select/deselect all root level nodes
 Ctrl+X,C,V      - Cut/copy/paste node or component
 Ctrl+U          - Unparent scene node
-Ctrl+H	        - Open the scene hierarchy window
-Ctrl+N	        - Open the node / component edit window
+Ctrl+H          - Open the scene hierarchy window
+Ctrl+N          - Open the node / component edit window
 Ctrl+P          - Toggle scene update on/off
+Ctrl+W          - Cycle through solid, wireframe and point rendering
 Ctrl+R          - Reload scene resources
 ESC             - Close the file selector or editor settings window
 DEL             - Delete node or component

+ 3 - 1
Engine/Engine/PhysicsAPI.cpp

@@ -157,6 +157,8 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "float get_ccdMotionThreshold() const", asMETHOD(RigidBody, GetCcdMotionThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_useGravity(bool)", asMETHOD(RigidBody, SetUseGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "bool get_useGravity() const", asMETHOD(RigidBody, GetUseGravity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_gravityOverride(const Vector3&in)", asMETHOD(RigidBody, SetGravityOverride), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "const Vector3& get_gravityOverride() const", asMETHOD(RigidBody, GetGravityOverride), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_phantom(bool)", asMETHOD(RigidBody, SetPhantom), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "bool get_phantom() const", asMETHOD(RigidBody, IsPhantom), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_kinematic(bool)", asMETHOD(RigidBody, SetKinematic), asCALL_THISCALL);
@@ -169,7 +171,7 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "void set_collisionEventMode(CollisionEventMode)", asMETHOD(RigidBody, SetCollisionEventMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "CollisionEventMode get_collisionEventMode() const", asMETHOD(RigidBody, GetCollisionEventMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Array<RigidBody@>@ get_collidingBodies() const", asFUNCTION(RigidBodyGetCollidingBodies), asCALL_CDECL_OBJLAST);
-    
+
     // Register Variant GetPtr() for RigidBody
     engine->RegisterObjectMethod("Variant", "RigidBody@+ GetRigidBody() const", asFUNCTION(GetVariantPtr<RigidBody>), asCALL_CDECL_OBJLAST);
 }

+ 8 - 0
Engine/Physics/CollisionShape.cpp

@@ -47,6 +47,7 @@
 #include <BulletCollision/CollisionShapes/btSphereShape.h>
 #include <BulletCollision/CollisionShapes/btTriangleMesh.h>
 #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
+#include <BulletCollision/CollisionShapes/btStaticPlaneShape.h>
 #include <hull.h>
 
 namespace Urho3D
@@ -59,6 +60,7 @@ static const char* typeNames[] =
     "None",
     "Box",
     "Sphere",
+	"StaticPlane",
     "Cylinder",
     "Capsule",
     "Cone",
@@ -725,6 +727,12 @@ void CollisionShape::UpdateShape()
             shape_ = new btSphereShape(size_.x_ * 0.5f);
             shape_->setLocalScaling(ToBtVector3(newWorldScale));
             break;
+
+        case SHAPE_STATICPLANE:
+            /// \todo: plane normal is always hard coded
+            shape_ = new btStaticPlaneShape(btVector3(0,1,0), size_.y_);
+            shape_->setLocalScaling(ToBtVector3(newWorldScale));
+            break;
             
         case SHAPE_CYLINDER:
             shape_ = new btCylinderShape(btVector3(size_.x_ * 0.5f, size_.y_ * 0.5f, size_.x_ * 0.5f));

+ 1 - 0
Engine/Physics/CollisionShape.h

@@ -47,6 +47,7 @@ enum ShapeType
     SHAPE_NONE = 0,
     SHAPE_BOX,
     SHAPE_SPHERE,
+    SHAPE_STATICPLANE,
     SHAPE_CYLINDER,
     SHAPE_CAPSULE,
     SHAPE_CONE,

+ 5 - 1
Engine/Physics/PhysicsWorld.cpp

@@ -104,7 +104,7 @@ PhysicsWorld::PhysicsWorld(Context* context) :
     interpolation_(true),
     applyingTransforms_(false),
     debugRenderer_(0),
-    debugMode_(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints)
+    debugMode_(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)
 {
     collisionConfiguration_ = new btDefaultCollisionConfiguration();
     collisionDispatcher_ = new btCollisionDispatcher(collisionConfiguration_);
@@ -559,6 +559,10 @@ void PhysicsWorld::SendCollisionEvents()
             
             RigidBody* bodyA = static_cast<RigidBody*>(objectA->getUserPointer());
             RigidBody* bodyB = static_cast<RigidBody*>(objectB->getUserPointer());
+			// If it's not a rigidbody, maybe a ghost object
+			if (!bodyA || !bodyB)
+				continue;
+
             WeakPtr<RigidBody> bodyWeakA(bodyA);
             WeakPtr<RigidBody> bodyWeakB(bodyB);
             

+ 44 - 23
Engine/Physics/RigidBody.cpp

@@ -65,6 +65,7 @@ RigidBody::RigidBody(Context* context) :
     Component(context),
     body_(0),
     compoundShape_(0),
+    gravityOverride_(Vector3::ZERO),
     mass_(DEFAULT_MASS),
     collisionLayer_(DEFAULT_COLLISION_LAYER),
     collisionMask_(DEFAULT_COLLISION_MASK),
@@ -73,6 +74,7 @@ RigidBody::RigidBody(Context* context) :
     lastRotation_(Quaternion::IDENTITY),
     kinematic_(false),
     phantom_(false),
+    useGravity_(true),
     hasSmoothedTransform_(false),
     readdBody_(false)
 {
@@ -116,6 +118,7 @@ void RigidBody::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Use Gravity", GetUseGravity, SetUseGravity, bool, true, AM_DEFAULT);
     ATTRIBUTE(RigidBody, VAR_BOOL, "Is Kinematic", kinematic_, false, AM_DEFAULT);
     ATTRIBUTE(RigidBody, VAR_BOOL, "Is Phantom", phantom_, false, AM_DEFAULT);
+    REF_ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Gravity Override", GetGravityOverride, SetGravityOverride, Vector3, Vector3::ZERO, AM_DEFAULT);
 }
 
 void RigidBody::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -380,22 +383,20 @@ void RigidBody::SetCcdMotionThreshold(float threshold)
 
 void RigidBody::SetUseGravity(bool enable)
 {
-    if (physicsWorld_ && body_ && enable != GetUseGravity())
+    if (enable != useGravity_)
     {
-        btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-        
-        int flags = body_->getFlags();
-        if (enable)
-            flags &= ~BT_DISABLE_WORLD_GRAVITY;
-        else
-            flags |= BT_DISABLE_WORLD_GRAVITY;
-        body_->setFlags(flags);
-        
-        if (enable)
-            body_->setGravity(world->getGravity());
-        else
-            body_->setGravity(btVector3(0.0f, 0.0f, 0.0f));
-        
+        useGravity_ = enable;
+        UpdateGravity();
+        MarkNetworkUpdate();
+    }
+}
+
+void RigidBody::SetGravityOverride(const Vector3& gravity)
+{
+    if (gravity != gravityOverride_)
+    {
+        gravityOverride_ = gravity;
+        UpdateGravity();
         MarkNetworkUpdate();
     }
 }
@@ -635,14 +636,6 @@ float RigidBody::GetCcdMotionThreshold() const
         return 0.0f;
 }
 
-bool RigidBody::GetUseGravity() const
-{
-    if (body_)
-        return (body_->getFlags() & BT_DISABLE_WORLD_GRAVITY) == 0;
-    else
-        return true;
-}
-
 bool RigidBody::IsActive() const
 {
     if (body_)
@@ -698,6 +691,32 @@ void RigidBody::UpdateMass()
     }
 }
 
+void RigidBody::UpdateGravity()
+{
+    if (physicsWorld_ && body_)
+    {
+        btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
+        
+        int flags = body_->getFlags();
+        if (useGravity_ && gravityOverride_ == Vector3::ZERO)
+            flags &= ~BT_DISABLE_WORLD_GRAVITY;
+        else
+            flags |= BT_DISABLE_WORLD_GRAVITY;
+        body_->setFlags(flags);
+        
+        if (useGravity_)
+        {
+            // If override vector is zero, use world's gravity
+            if (gravityOverride_ == Vector3::ZERO)
+                body_->setGravity(world->getGravity());
+            else
+                body_->setGravity(ToBtVector3(gravityOverride_));
+        }
+        else
+            body_->setGravity(btVector3(0.0f, 0.0f, 0.0f));
+    }
+}
+
 void RigidBody::SetNetAngularVelocityAttr(const PODVector<unsigned char>& value)
 {
     float maxVelocity = physicsWorld_ ? physicsWorld_->GetMaxNetworkAngularVelocity() : DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY;
@@ -853,6 +872,8 @@ void RigidBody::AddBodyToWorld()
     if (!massUpdated)
         UpdateMass();
     
+    UpdateGravity();
+    
     int flags = body_->getCollisionFlags();
     if (phantom_)
         flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;

+ 12 - 2
Engine/Physics/RigidBody.h

@@ -103,6 +103,8 @@ public:
     void SetCcdMotionThreshold(float threshold);
     /// Set whether gravity is applied to rigid body.
     void SetUseGravity(bool enable);
+    /// Set gravity override. If zero, uses physics world's gravity.
+    void SetGravityOverride(const Vector3& gravity);
     /// Set rigid body kinematic mode. In kinematic mode forces are not applied to the rigid body.
     void SetKinematic(bool enable);
     /// Set rigid body phantom mode. In phantom mode collisions are reported but do not apply forces.
@@ -173,7 +175,9 @@ public:
     /// Return continuous collision detection motion-per-simulation-step threshold.
     float GetCcdMotionThreshold() const;
     /// Return whether rigid body uses gravity.
-    bool GetUseGravity() const;
+    bool GetUseGravity() const { return useGravity_; }
+    /// Return gravity override. If zero (default), uses the physics world's gravity.
+    const Vector3& GetGravityOverride() const { return gravityOverride_; }
     /// Return kinematic mode flag.
     bool IsKinematic() const { return kinematic_; }
     /// Return phantom mode flag.
@@ -191,8 +195,10 @@ public:
     
     /// Apply new world transform after a simulation step. Called internally.
     void ApplyWorldTransform(const Vector3& newWorldPosition, const Quaternion& newWorldRotation);
-    /// Update mass and inertia of rigid body.
+    /// Update mass and inertia to the Bullet rigid body.
     void UpdateMass();
+    /// Update gravity parameters to the Bullet rigid body.
+    void UpdateGravity();
     /// Set network angular velocity attribute.
     void SetNetAngularVelocityAttr(const PODVector<unsigned char>& value);
     /// Return network angular velocity attribute.
@@ -226,6 +232,8 @@ private:
     WeakPtr<PhysicsWorld> physicsWorld_;
     /// Constraints that refer to this rigid body.
     PODVector<Constraint*> constraints_;
+    /// Gravity override vector.
+    Vector3 gravityOverride_;
     /// Mass.
     float mass_;
     /// Attribute buffer for network replication.
@@ -244,6 +252,8 @@ private:
     bool kinematic_;
     /// Phantom flag.
     bool phantom_;
+    /// Use gravity flag.
+    bool useGravity_;
     /// Smoothed transform mode.
     bool hasSmoothedTransform_;
     /// Readd body to world flag.