feat(joint): added motor
This commit is contained in:
parent
e5f543ef4a
commit
47d720f438
9 changed files with 102 additions and 3 deletions
54
core/src/objects/joint/rotatev.cpp
Normal file
54
core/src/objects/joint/rotatev.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "rotatev.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "objects/part.h"
|
||||
#include "objects/workspace.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include <reactphysics3d/constraint/HingeJoint.h>
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
RotateV::RotateV(): JointInstance(&TYPE) {
|
||||
}
|
||||
|
||||
RotateV::~RotateV() {
|
||||
}
|
||||
static CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, 1));
|
||||
|
||||
void RotateV::buildJoint() {
|
||||
// Only if both parts are set, are not the same part, are part of a workspace, and are part of the same workspace, we build the joint
|
||||
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
||||
|
||||
// Don't build the joint if we're not part of either a workspace or JointsService
|
||||
if ((!GetParent() || GetParent().value()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
||||
|
||||
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock()).value();
|
||||
if (!workspace->physicsWorld) return;
|
||||
|
||||
|
||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
||||
// used to be rather than specifying an anchor rotation, so whatever.
|
||||
CFrame newFrame = part0.lock()->cframe * (c0 * c1.Inverse());
|
||||
part1.lock()->cframe = newFrame;
|
||||
workspace->SyncPartPhysics(part1.lock());
|
||||
// Do NOT use Abs() in this scenario. For some reason that breaks it
|
||||
rp::HingeJointInfo jointInfo(part0.lock()->rigidBody, part1.lock()->rigidBody, (part0.lock()->cframe * c0).Position(), -(part0.lock()->cframe * c0).LookVector().Unit());
|
||||
|
||||
jointInfo.isCollisionEnabled = false;
|
||||
|
||||
this->joint = dynamic_cast<rp::HingeJoint*>(workspace->physicsWorld->createJoint(jointInfo));
|
||||
jointWorkspace = workspace;
|
||||
|
||||
|
||||
// part1.lock()->rigidBody->getCollider(0)->setCollideWithMaskBits(0b10);
|
||||
// part1.lock()->rigidBody->getCollider(0)->setCollisionCategoryBits(0b10);
|
||||
// part0.lock()->rigidBody->getCollider(0)->setCollideWithMaskBits(0b01);
|
||||
// part0.lock()->rigidBody->getCollider(0)->setCollisionCategoryBits(0b01);
|
||||
}
|
||||
|
||||
void RotateV::breakJoint() {
|
||||
// If the joint doesn't exist, or its workspace expired (not our problem anymore), then no need to do anything
|
||||
if (!this->joint || jointWorkspace.expired() || !jointWorkspace.lock()->physicsWorld) return;
|
||||
|
||||
jointWorkspace.lock()->physicsWorld->destroyJoint(this->joint);
|
||||
this->joint = nullptr;
|
||||
}
|
21
core/src/objects/joint/rotatev.h
Normal file
21
core/src/objects/joint/rotatev.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/annotation.h"
|
||||
#include "objects/base/instance.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
#include <memory>
|
||||
|
||||
class DEF_INST RotateV : public JointInstance {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
||||
rp::HingeJoint* joint = nullptr;
|
||||
|
||||
virtual void buildJoint() override;
|
||||
virtual void breakJoint() override;
|
||||
public:
|
||||
RotateV();
|
||||
~RotateV();
|
||||
|
||||
static inline std::shared_ptr<RotateV> New() { return std::make_shared<RotateV>(); };
|
||||
static inline std::shared_ptr<Instance> Create() { return std::make_shared<RotateV>(); };
|
||||
};
|
|
@ -1,5 +1,8 @@
|
|||
#include "meta.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
#include "objects/joint/rotate.h"
|
||||
#include "objects/joint/rotatev.h"
|
||||
#include "objects/joint/weld.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "objects/part.h"
|
||||
#include "objects/joint/snap.h"
|
||||
|
@ -14,6 +17,9 @@ std::map<std::string, const InstanceType*> INSTANCE_MAP = {
|
|||
|
||||
{ "Part", &Part::TYPE },
|
||||
{ "Snap", &Snap::TYPE },
|
||||
{ "Weld", &Weld::TYPE },
|
||||
{ "Rotate", &Rotate::TYPE },
|
||||
{ "RotateV", &RotateV::TYPE },
|
||||
{ "JointInstance", &JointInstance::TYPE },
|
||||
{ "Script", &Script::TYPE },
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "datatypes/vector.h"
|
||||
#include "objects/base/member.h"
|
||||
#include "objects/joint/rotate.h"
|
||||
#include "objects/joint/rotatev.h"
|
||||
#include "objects/joint/weld.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
|
@ -214,6 +215,8 @@ std::optional<std::shared_ptr<JointInstance>> makeJointFromSurfaces(SurfaceType
|
|||
return Snap::New();
|
||||
if (a == SurfaceHinge)
|
||||
return Rotate::New();
|
||||
if (a == SurfaceMotor)
|
||||
return RotateV::New();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
@ -257,7 +260,7 @@ void Part::MakeJoints() {
|
|||
SurfaceType otherSurface = surfaceFromFace(faceFromNormal(otherFace));
|
||||
|
||||
// If it is a hinge, only attach if actually touching the "hinge"
|
||||
if (mySurface == SurfaceHinge && !checkSurfacesTouching(surfaceFrame, Vector3(0.4, 0.4, 0.4), myFace, otherFace, otherPart)) continue;
|
||||
if ((mySurface == SurfaceHinge || mySurface == SurfaceMotor) && !checkSurfacesTouching(surfaceFrame, Vector3(0.4, 0.4, 0.4), myFace, otherFace, otherPart)) continue;
|
||||
|
||||
// Create contacts
|
||||
// Contact always occurs at the center of Part0's surface (even if that point does not overlap both surfaces)
|
||||
|
|
|
@ -26,7 +26,7 @@ struct PartConstructParams {
|
|||
bool locked = false;
|
||||
};
|
||||
|
||||
class Snap;
|
||||
class Workspace;
|
||||
|
||||
class DEF_INST_(explorer_icon="part") Part : public Instance {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
@ -46,6 +46,7 @@ protected:
|
|||
bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart);
|
||||
|
||||
friend JointInstance;
|
||||
friend Workspace;
|
||||
|
||||
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override;
|
||||
void onUpdated(std::string);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "objects/jointsservice.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
#include "physics/util.h"
|
||||
#include <memory>
|
||||
#include <reactphysics3d/engine/PhysicsCommon.h>
|
||||
|
||||
rp::PhysicsCommon* Workspace::physicsCommon = new rp::PhysicsCommon;
|
||||
|
@ -102,6 +103,15 @@ void Workspace::PhysicsStep(float deltaTime) {
|
|||
const rp::Transform& transform = part->rigidBody->getTransform();
|
||||
part->cframe = CFrame(transform);
|
||||
part->velocity = part->rigidBody->getLinearVelocity();
|
||||
|
||||
part->rigidBody->enableGravity(true);
|
||||
for (auto& joint : part->secondaryJoints) {
|
||||
if (joint.expired() || !joint.lock()->IsA("RotateV")) continue;
|
||||
|
||||
std::shared_ptr<JointInstance> motor = joint.lock()->CastTo<JointInstance>().expect();
|
||||
part->rigidBody->enableGravity(false);
|
||||
part->rigidBody->setAngularVelocity((motor->part0.lock()->cframe * motor->c0).LookVector() * 10.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class Part;
|
|||
class Snap;
|
||||
class Weld;
|
||||
class Rotate;
|
||||
class RotateV;
|
||||
|
||||
typedef std::function<FilterResult(std::shared_ptr<Part>)> RaycastFilter;
|
||||
|
||||
|
@ -41,6 +42,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {
|
|||
friend Snap;
|
||||
friend Weld;
|
||||
friend Rotate;
|
||||
friend RotateV;
|
||||
protected:
|
||||
void InitService() override;
|
||||
bool initialized = false;
|
||||
|
|
|
@ -17,6 +17,7 @@ enum SurfaceType {
|
|||
SurfaceInlets = 4,
|
||||
SurfaceUniversal = 5,
|
||||
SurfaceHinge = 6,
|
||||
SurfaceMotor = 7,
|
||||
};
|
||||
|
||||
namespace Data { class Vector3; } using Data::Vector3;
|
||||
|
|
|
@ -122,6 +122,7 @@ void PlaceDocument::init() {
|
|||
// part0->backSurface = SurfaceWeld;
|
||||
// part1->frontSurface = SurfaceWeld;
|
||||
|
||||
part0->backSurface = SurfaceHinge;
|
||||
// part0->backSurface = SurfaceHinge;
|
||||
part0->backSurface = SurfaceMotor;
|
||||
// part1->frontSurface = SurfaceHinge;
|
||||
}
|
Loading…
Add table
Reference in a new issue