fix(physics): motor joint updates with paramB
This commit is contained in:
parent
3a6fb2ada2
commit
78d2466efd
8 changed files with 84 additions and 28 deletions
|
@ -17,6 +17,9 @@ void JointInstance::OnAncestryChanged(nullable std::shared_ptr<Instance>, nullab
|
|||
Update();
|
||||
}
|
||||
|
||||
void JointInstance::OnPartParamsUpdated() {
|
||||
}
|
||||
|
||||
void JointInstance::Update() {
|
||||
// To keep it simple compared to our previous algorithm, this one is pretty barebones:
|
||||
// 1. Every time we update, (whether our parent changed, or a property), destroy the current joints
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "objects/base/instance.h"
|
||||
#include "../annotation.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include "datatypes/cframe.h"
|
||||
#include "physics/world.h"
|
||||
|
||||
|
@ -12,6 +11,8 @@
|
|||
#include "objects/part/part.h"
|
||||
#endif
|
||||
|
||||
#define DEF_PROP_PHYS DEF_PROP_(on_update=onUpdated)
|
||||
|
||||
class BasePart;
|
||||
class Workspace;
|
||||
|
||||
|
@ -33,12 +34,15 @@ protected:
|
|||
virtual void buildJoint() = 0;
|
||||
public:
|
||||
void Update();
|
||||
virtual void OnPartParamsUpdated();
|
||||
|
||||
DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part0;
|
||||
DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part1;
|
||||
DEF_PROP_(on_update=onUpdated) CFrame c0;
|
||||
DEF_PROP_(on_update=onUpdated) CFrame c1;
|
||||
DEF_PROP_PHYS std::weak_ptr<BasePart> part0;
|
||||
DEF_PROP_PHYS std::weak_ptr<BasePart> part1;
|
||||
DEF_PROP_PHYS CFrame c0;
|
||||
DEF_PROP_PHYS CFrame c1;
|
||||
|
||||
JointInstance(const InstanceType*);
|
||||
~JointInstance();
|
||||
};
|
||||
};
|
||||
|
||||
#undef DEF_PROP_PHYS
|
|
@ -21,8 +21,14 @@ void RotateV::buildJoint() {
|
|||
CFrame newFrame = part0.lock()->cframe * (c0 * c1.Inverse());
|
||||
part1.lock()->cframe = newFrame;
|
||||
// Do NOT use Abs() in this scenario. For some reason that breaks it
|
||||
PhysRotatingJointInfo jointInfo(c0, c1, true);
|
||||
float vel = part0.lock()->GetSurfaceParamB(-c0.LookVector().Unit()) * 6.28;
|
||||
PhysRotatingJointInfo jointInfo(c0, c1, vel);
|
||||
|
||||
this->joint = workspace->CreateJoint(jointInfo, part0.lock(), part1.lock());
|
||||
jointWorkspace = workspace;
|
||||
}
|
||||
|
||||
void RotateV::OnPartParamsUpdated() {
|
||||
float vel = part0.lock()->GetSurfaceParamB(-c0.LookVector().Unit()) * 6.28;
|
||||
this->joint.setAngularVelocity(vel);
|
||||
}
|
|
@ -13,6 +13,8 @@ public:
|
|||
RotateV();
|
||||
~RotateV();
|
||||
|
||||
void OnPartParamsUpdated() override;
|
||||
|
||||
static inline std::shared_ptr<RotateV> New() { return std::make_shared<RotateV>(); };
|
||||
static inline std::shared_ptr<Instance> Create() { return std::make_shared<RotateV>(); };
|
||||
};
|
|
@ -70,6 +70,15 @@ void BasePart::onUpdated(std::string property) {
|
|||
BreakJoints();
|
||||
}
|
||||
|
||||
void BasePart::onParamUpdated(std::string property) {
|
||||
// Send signal to joints to update themselves
|
||||
for (std::weak_ptr<JointInstance> joint : primaryJoints) {
|
||||
if (joint.expired()) continue;
|
||||
|
||||
joint.lock()->OnPartParamsUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
// Expands provided extents to fit point
|
||||
static void expandMaxExtents(Vector3* min, Vector3* max, Vector3 point) {
|
||||
*min = Vector3(glm::min(min->X(), point.X()), glm::min(min->Y(), point.Y()), glm::min(min->Z(), point.Z()));
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include "objects/pvinstance.h"
|
||||
#include "physics/world.h"
|
||||
|
||||
// Common macro for part properties
|
||||
#define DEF_PROP_PHYS DEF_PROP_(on_update=onUpdated)
|
||||
#define DEF_PROP_PHYSPARAM DEF_PROP_(on_update=onParamUpdated)
|
||||
|
||||
// For easy construction from C++. Maybe should be removed?
|
||||
struct PartConstructParams {
|
||||
Vector3 position;
|
||||
|
@ -51,19 +55,20 @@ protected:
|
|||
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
|
||||
void OnAncestryChanged(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent) override;
|
||||
void onUpdated(std::string);
|
||||
void onParamUpdated(std::string);
|
||||
|
||||
BasePart(const InstanceType*);
|
||||
BasePart(const InstanceType*, PartConstructParams params);
|
||||
public:
|
||||
DEF_PROP_CATEGORY(DATA)
|
||||
DEF_PROP_(on_update=onUpdated) Vector3 velocity;
|
||||
DEF_PROP_PHYS Vector3 velocity;
|
||||
[[ def_prop(name="CFrame", on_update=onUpdated), cframe_position_prop(name="Position"), cframe_rotation_prop(name="Rotation") ]]
|
||||
CFrame cframe;
|
||||
|
||||
DEF_PROP_CATEGORY(PART)
|
||||
// Special compatibility changes for this property were made in
|
||||
// Instance::Serialize
|
||||
DEF_PROP_(on_update=onUpdated) Vector3 size;
|
||||
DEF_PROP_PHYS Vector3 size;
|
||||
|
||||
DEF_PROP_CATEGORY(APPEARANCE)
|
||||
DEF_PROP Color3 color;
|
||||
|
@ -71,8 +76,8 @@ public:
|
|||
DEF_PROP float reflectance = 0.f;
|
||||
|
||||
DEF_PROP_CATEGORY(BEHAVIOR)
|
||||
DEF_PROP_(on_update=onUpdated) bool anchored = false;
|
||||
DEF_PROP_(on_update=onUpdated) bool canCollide = true;
|
||||
DEF_PROP_PHYS bool anchored = false;
|
||||
DEF_PROP_PHYS bool canCollide = true;
|
||||
DEF_PROP bool locked = false;
|
||||
|
||||
DEF_PROP_CATEGORY(SURFACE)
|
||||
|
@ -84,19 +89,19 @@ public:
|
|||
DEF_PROP SurfaceType backSurface = SurfaceType::Smooth;
|
||||
|
||||
DEF_PROP_CATEGORY(SURFACE_INPUT)
|
||||
DEF_PROP float topParamA = -0.5;
|
||||
DEF_PROP float bottomParamA = -0.5;
|
||||
DEF_PROP float leftParamA = -0.5;
|
||||
DEF_PROP float rightParamA = -0.5;
|
||||
DEF_PROP float frontParamA = -0.5;
|
||||
DEF_PROP float backParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float topParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float bottomParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float leftParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float rightParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float frontParamA = -0.5;
|
||||
DEF_PROP_PHYSPARAM float backParamA = -0.5;
|
||||
|
||||
DEF_PROP float topParamB = 0.5;
|
||||
DEF_PROP float bottomParamB = 0.5;
|
||||
DEF_PROP float leftParamB = 0.5;
|
||||
DEF_PROP float rightParamB = 0.5;
|
||||
DEF_PROP float frontParamB = 0.5;
|
||||
DEF_PROP float backParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float topParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float bottomParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float leftParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float rightParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float frontParamB = 0.5;
|
||||
DEF_PROP_PHYSPARAM float backParamB = 0.5;
|
||||
|
||||
DEF_SIGNAL SignalSource Touched;
|
||||
DEF_SIGNAL SignalSource TouchEnded;
|
||||
|
@ -117,4 +122,7 @@ public:
|
|||
|
||||
// Calculate size of axis-aligned bounding box
|
||||
Vector3 GetAABB();
|
||||
};
|
||||
};
|
||||
|
||||
#undef DEF_PROP_PHYS
|
||||
#undef DEF_PROP_PHYSPARAM
|
|
@ -229,9 +229,8 @@ PhysJoint PhysWorld::createJoint(PhysJointInfo& type, std::shared_ptr<BasePart>
|
|||
// settings.mMotorSettings = JPH::MotorSettings(1.0f, 1.0f);
|
||||
constraint = settings.Create(*part0->rigidBody.bodyImpl, *part1->rigidBody.bodyImpl);
|
||||
if (info->motorized) {
|
||||
float vel = part0->GetSurfaceParamB(-info->c0.LookVector().Unit()) * 6.28;
|
||||
static_cast<JPH::HingeConstraint*>(constraint)->SetMotorState(JPH::EMotorState::Velocity);
|
||||
static_cast<JPH::HingeConstraint*>(constraint)->SetTargetAngularVelocity(-vel);
|
||||
static_cast<JPH::HingeConstraint*>(constraint)->SetTargetAngularVelocity(-info->initialVelocity);
|
||||
}
|
||||
} else {
|
||||
panic();
|
||||
|
@ -241,6 +240,14 @@ PhysJoint PhysWorld::createJoint(PhysJointInfo& type, std::shared_ptr<BasePart>
|
|||
return { constraint };
|
||||
}
|
||||
|
||||
// WATCH OUT! This should only be called for HingeConstraints.
|
||||
// Can't use dynamic_cast because TwoBodyConstraint is not virtual
|
||||
void PhysJoint::setAngularVelocity(float velocity) {
|
||||
JPH::HingeConstraint* constraint = static_cast<JPH::HingeConstraint*>(jointImpl);
|
||||
if (!constraint) return;
|
||||
constraint->SetTargetAngularVelocity(-velocity);
|
||||
}
|
||||
|
||||
void PhysWorld::destroyJoint(PhysJoint joint) {
|
||||
worldImpl.RemoveConstraint(joint.jointImpl);
|
||||
}
|
||||
|
|
|
@ -17,13 +17,30 @@ class BasePart;
|
|||
class PhysWorld;
|
||||
|
||||
struct PhysJointInfo { virtual ~PhysJointInfo() = default; protected: PhysJointInfo() = default; };
|
||||
struct PhysFixedJointInfo : PhysJointInfo { CFrame c0; CFrame c1; inline PhysFixedJointInfo(CFrame c0, CFrame c1) : c0(c0), c1(c1) {} };
|
||||
struct PhysRotatingJointInfo : PhysJointInfo { CFrame c0; CFrame c1; bool motorized; inline PhysRotatingJointInfo(CFrame c0, CFrame c1, bool motorized = false) : c0(c0), c1(c1), motorized(motorized) {} };
|
||||
|
||||
struct PhysFixedJointInfo : PhysJointInfo {
|
||||
CFrame c0;
|
||||
CFrame c1;
|
||||
|
||||
inline PhysFixedJointInfo(CFrame c0, CFrame c1) : c0(c0), c1(c1) {}
|
||||
};
|
||||
|
||||
struct PhysRotatingJointInfo : PhysJointInfo {
|
||||
CFrame c0;
|
||||
CFrame c1;
|
||||
bool motorized;
|
||||
float initialVelocity;
|
||||
|
||||
inline PhysRotatingJointInfo(CFrame c0, CFrame c1) : c0(c0), c1(c1), motorized(false), initialVelocity(0.f){}
|
||||
inline PhysRotatingJointInfo(CFrame c0, CFrame c1, float initialVelocity) : c0(c0), c1(c1), motorized(true), initialVelocity(initialVelocity) {}
|
||||
};
|
||||
|
||||
class PhysWorld;
|
||||
struct PhysJoint {
|
||||
public:
|
||||
JPH::TwoBodyConstraint* jointImpl;
|
||||
|
||||
void setAngularVelocity(float velocity);
|
||||
};
|
||||
|
||||
struct RaycastResult;
|
||||
|
|
Loading…
Add table
Reference in a new issue