mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
expose bullet slider constraint to javascript
This commit is contained in:
parent
fa25493a8a
commit
b196dd082b
9 changed files with 489 additions and 11 deletions
|
@ -17,6 +17,7 @@
|
|||
#include <ObjectActionSpring.h>
|
||||
#include <ObjectActionTravelOriented.h>
|
||||
#include <ObjectConstraintHinge.h>
|
||||
#include <ObjectConstraintSlider.h>
|
||||
#include <LogHandler.h>
|
||||
|
||||
#include "InterfaceDynamicFactory.h"
|
||||
|
@ -38,6 +39,8 @@ EntityDynamicPointer interfaceDynamicFactory(EntityDynamicType type, const QUuid
|
|||
return std::make_shared<ObjectConstraintHinge>(id, ownerEntity);
|
||||
case DYNAMIC_TYPE_FAR_GRAB:
|
||||
return std::make_shared<AvatarActionFarGrab>(id, ownerEntity);
|
||||
case DYNAMIC_TYPE_SLIDER:
|
||||
return std::make_shared<ObjectConstraintSlider>(id, ownerEntity);
|
||||
}
|
||||
|
||||
Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown entity dynamic type");
|
||||
|
|
|
@ -117,6 +117,9 @@ EntityDynamicType EntityDynamicInterface::dynamicTypeFromString(QString dynamicT
|
|||
if (normalizedDynamicTypeString == "fargrab") {
|
||||
return DYNAMIC_TYPE_FAR_GRAB;
|
||||
}
|
||||
if (normalizedDynamicTypeString == "slider") {
|
||||
return DYNAMIC_TYPE_SLIDER;
|
||||
}
|
||||
|
||||
qCDebug(entities) << "Warning -- EntityDynamicInterface::dynamicTypeFromString got unknown dynamic-type name"
|
||||
<< dynamicTypeString;
|
||||
|
@ -139,6 +142,8 @@ QString EntityDynamicInterface::dynamicTypeToString(EntityDynamicType dynamicTyp
|
|||
return "hinge";
|
||||
case DYNAMIC_TYPE_FAR_GRAB:
|
||||
return "far-grab";
|
||||
case DYNAMIC_TYPE_SLIDER:
|
||||
return "slider";
|
||||
}
|
||||
assert(false);
|
||||
return "none";
|
||||
|
|
|
@ -31,7 +31,8 @@ enum EntityDynamicType {
|
|||
DYNAMIC_TYPE_HOLD = 3000,
|
||||
DYNAMIC_TYPE_TRAVEL_ORIENTED = 4000,
|
||||
DYNAMIC_TYPE_HINGE = 5000,
|
||||
DYNAMIC_TYPE_FAR_GRAB = 6000
|
||||
DYNAMIC_TYPE_FAR_GRAB = 6000,
|
||||
DYNAMIC_TYPE_SLIDER = 7000
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return VERSION_ENTITIES_HINGE_CONSTRAINT;
|
||||
return VERSION_ENTITIES_SLIDER_CONSTRAINT;
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -207,6 +207,7 @@ const PacketVersion VERSION_ENTITIES_SERVER_SCRIPTS = 66;
|
|||
const PacketVersion VERSION_ENTITIES_PHYSICS_PACKET = 67;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68;
|
||||
const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69;
|
||||
const PacketVersion VERSION_ENTITIES_SLIDER_CONSTRAINT = 70;
|
||||
|
||||
enum class EntityQueryPacketVersion: PacketVersion {
|
||||
JSONFilter = 18,
|
||||
|
|
|
@ -54,7 +54,7 @@ void ObjectConstraintHinge::prepareForPhysicsSimulation() {
|
|||
// https://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7020
|
||||
|
||||
if (!isMine()) {
|
||||
// XXX
|
||||
// TODO
|
||||
// don't activate motor for someone else's action?
|
||||
// maybe don't if this interface isn't the sim owner?
|
||||
return;
|
||||
|
@ -77,11 +77,6 @@ void ObjectConstraintHinge::prepareForPhysicsSimulation() {
|
|||
float t = (float)(now - _startMotorTime) / (float)USECS_PER_SECOND;
|
||||
float motorTarget = _motorVelocity * t;
|
||||
|
||||
// // bring motorTarget into the range of [-PI, PI]
|
||||
// motorTarget += PI;
|
||||
// motorTarget = fmodf(motorTarget, 2.0f * PI);
|
||||
// motorTarget -= PI;
|
||||
|
||||
if (!_motorEnabled) {
|
||||
constraint->enableMotor(true);
|
||||
_motorEnabled = true;
|
||||
|
@ -90,7 +85,7 @@ void ObjectConstraintHinge::prepareForPhysicsSimulation() {
|
|||
constraint->setMotorTarget(motorTarget, dt);
|
||||
|
||||
} else if (_motorTargetTimeScale > 0.0f) {
|
||||
// XXX
|
||||
// TODO -- we probably want a spring-like action here
|
||||
} else if (_motorEnabled) {
|
||||
constraint->enableMotor(false);
|
||||
_motorEnabled = false;
|
||||
|
|
|
@ -44,8 +44,8 @@ protected:
|
|||
glm::vec3 _pivotInB;
|
||||
glm::vec3 _axisInB;
|
||||
|
||||
float _low { -2.0f * PI };
|
||||
float _high { 2.0f * PI };
|
||||
float _low { -TWO_PI };
|
||||
float _high { TWO_PI };
|
||||
|
||||
// https://gamedev.stackexchange.com/questions/71436/what-are-the-parameters-for-bthingeconstraintsetlimit
|
||||
//
|
||||
|
|
410
libraries/physics/src/ObjectConstraintSlider.cpp
Normal file
410
libraries/physics/src/ObjectConstraintSlider.cpp
Normal file
|
@ -0,0 +1,410 @@
|
|||
//
|
||||
// ObjectConstraintSlider.cpp
|
||||
// libraries/physics/src
|
||||
//
|
||||
// Created by Seth Alves 2017-4-23
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "QVariantGLM.h"
|
||||
|
||||
#include "EntityTree.h"
|
||||
#include "ObjectConstraintSlider.h"
|
||||
#include "PhysicsLogging.h"
|
||||
|
||||
|
||||
const uint16_t ObjectConstraintSlider::constraintVersion = 1;
|
||||
|
||||
|
||||
ObjectConstraintSlider::ObjectConstraintSlider(const QUuid& id, EntityItemPointer ownerEntity) :
|
||||
ObjectConstraint(DYNAMIC_TYPE_SLIDER, id, ownerEntity),
|
||||
_pointInA(glm::vec3(0.0f)),
|
||||
_axisInA(glm::vec3(0.0f))
|
||||
{
|
||||
#if WANT_DEBUG
|
||||
qCDebug(physics) << "ObjectConstraintSlider::ObjectConstraintSlider";
|
||||
#endif
|
||||
}
|
||||
|
||||
ObjectConstraintSlider::~ObjectConstraintSlider() {
|
||||
#if WANT_DEBUG
|
||||
qCDebug(physics) << "ObjectConstraintSlider::~ObjectConstraintSlider";
|
||||
#endif
|
||||
}
|
||||
|
||||
QList<btRigidBody*> ObjectConstraintSlider::getRigidBodies() {
|
||||
QList<btRigidBody*> result;
|
||||
result += getRigidBody();
|
||||
QUuid otherEntityID;
|
||||
withReadLock([&]{
|
||||
otherEntityID = _otherEntityID;
|
||||
});
|
||||
if (!otherEntityID.isNull()) {
|
||||
result += getOtherRigidBody(otherEntityID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ObjectConstraintSlider::prepareForPhysicsSimulation() {
|
||||
}
|
||||
|
||||
void ObjectConstraintSlider::updateSlider() {
|
||||
btSliderConstraint* constraint { nullptr };
|
||||
|
||||
withReadLock([&]{
|
||||
// TODO -- write this
|
||||
constraint = static_cast<btSliderConstraint*>(_constraint);
|
||||
});
|
||||
|
||||
if (!constraint) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// constraint->setFrames (const btTransform &frameA, const btTransform &frameB);
|
||||
constraint->setLowerLinLimit(_linearLow);
|
||||
constraint->setUpperLinLimit(_linearHigh);
|
||||
constraint->setLowerAngLimit(_angularLow);
|
||||
constraint->setUpperAngLimit(_angularHigh);
|
||||
|
||||
}
|
||||
|
||||
|
||||
btTypedConstraint* ObjectConstraintSlider::getConstraint() {
|
||||
btSliderConstraint* constraint { nullptr };
|
||||
QUuid otherEntityID;
|
||||
glm::vec3 pointInA;
|
||||
glm::vec3 axisInA;
|
||||
glm::vec3 pointInB;
|
||||
glm::vec3 axisInB;
|
||||
|
||||
withReadLock([&]{
|
||||
constraint = static_cast<btSliderConstraint*>(_constraint);
|
||||
pointInA = _pointInA;
|
||||
axisInA = _axisInA;
|
||||
otherEntityID = _otherEntityID;
|
||||
pointInB = _pointInB;
|
||||
axisInB = _axisInB;
|
||||
});
|
||||
if (constraint) {
|
||||
return constraint;
|
||||
}
|
||||
|
||||
btRigidBody* rigidBodyA = getRigidBody();
|
||||
if (!rigidBodyA) {
|
||||
qCDebug(physics) << "ObjectConstraintSlider::getConstraint -- no rigidBodyA";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!otherEntityID.isNull()) {
|
||||
// This slider is between two entities... find the other rigid body.
|
||||
|
||||
glm::quat rotA = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA));
|
||||
glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInB));
|
||||
|
||||
btTransform frameInA(glmToBullet(rotA), glmToBullet(pointInA));
|
||||
btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB));
|
||||
|
||||
btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID);
|
||||
if (!rigidBodyB) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
constraint = new btSliderConstraint(*rigidBodyA, *rigidBodyB, frameInA, frameInB, true);
|
||||
} else {
|
||||
// This slider is between an entity and the world-frame.
|
||||
|
||||
glm::quat rot = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA));
|
||||
|
||||
btTransform frameInA(glmToBullet(rot), glmToBullet(pointInA));
|
||||
|
||||
constraint = new btSliderConstraint(*rigidBodyA, frameInA, true);
|
||||
}
|
||||
|
||||
withWriteLock([&]{
|
||||
_constraint = constraint;
|
||||
});
|
||||
|
||||
// if we don't wake up rigidBodyA, we may not send the dynamicData property over the network
|
||||
forceBodyNonStatic();
|
||||
activateBody();
|
||||
|
||||
// updateSlider();
|
||||
|
||||
return constraint;
|
||||
}
|
||||
|
||||
|
||||
bool ObjectConstraintSlider::updateArguments(QVariantMap arguments) {
|
||||
glm::vec3 pointInA;
|
||||
glm::vec3 axisInA;
|
||||
QUuid otherEntityID;
|
||||
glm::vec3 pointInB;
|
||||
glm::vec3 axisInB;
|
||||
float linearLow;
|
||||
float linearHigh;
|
||||
float angularLow;
|
||||
float angularHigh;
|
||||
float linearTarget;
|
||||
float linearTimeScale;
|
||||
bool linearTargetSet;
|
||||
float angularTarget;
|
||||
float angularTimeScale;
|
||||
bool angularTargetSet;
|
||||
|
||||
|
||||
bool needUpdate = false;
|
||||
bool somethingChanged = ObjectDynamic::updateArguments(arguments);
|
||||
withReadLock([&]{
|
||||
bool ok = true;
|
||||
pointInA = EntityDynamicInterface::extractVec3Argument("slider constraint", arguments, "point", ok, false);
|
||||
if (!ok) {
|
||||
pointInA = _pointInA;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
axisInA = EntityDynamicInterface::extractVec3Argument("slider constraint", arguments, "axis", ok, false);
|
||||
if (!ok) {
|
||||
axisInA = _axisInA;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
otherEntityID = QUuid(EntityDynamicInterface::extractStringArgument("slider constraint",
|
||||
arguments, "otherEntityID", ok, false));
|
||||
if (!ok) {
|
||||
otherEntityID = _otherEntityID;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
pointInB = EntityDynamicInterface::extractVec3Argument("slider constraint", arguments, "otherPoint", ok, false);
|
||||
if (!ok) {
|
||||
pointInB = _pointInB;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
axisInB = EntityDynamicInterface::extractVec3Argument("slider constraint", arguments, "otherAxis", ok, false);
|
||||
if (!ok) {
|
||||
axisInB = _axisInB;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
linearLow = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments, "linearLow", ok, false);
|
||||
if (!ok) {
|
||||
linearLow = _linearLow;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
linearHigh = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments, "linearHigh", ok, false);
|
||||
if (!ok) {
|
||||
linearHigh = _linearHigh;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
angularLow = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments, "angularLow", ok, false);
|
||||
if (!ok) {
|
||||
angularLow = _angularLow;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
angularHigh = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments, "angularHigh", ok, false);
|
||||
if (!ok) {
|
||||
angularHigh = _angularHigh;
|
||||
}
|
||||
|
||||
|
||||
ok = true;
|
||||
linearTarget = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments,
|
||||
"linearTarget", ok, false);
|
||||
if (!ok) {
|
||||
linearTarget = _linearTarget;
|
||||
linearTargetSet = _linearTargetSet;
|
||||
} else {
|
||||
linearTargetSet = true;
|
||||
}
|
||||
|
||||
|
||||
ok = true;
|
||||
linearTimeScale = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments,
|
||||
"linearTimeScale", ok, false);
|
||||
if (!ok) {
|
||||
linearTimeScale = _linearTimeScale;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
angularTarget = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments,
|
||||
"angularTarget", ok, false);
|
||||
if (!ok) {
|
||||
angularTarget = _angularTarget;
|
||||
angularTargetSet = _angularTargetSet;
|
||||
} else {
|
||||
angularTargetSet = true;
|
||||
}
|
||||
|
||||
|
||||
ok = true;
|
||||
angularTimeScale = EntityDynamicInterface::extractFloatArgument("slider constraint", arguments,
|
||||
"angularTimeScale", ok, false);
|
||||
if (!ok) {
|
||||
angularTimeScale = _angularTimeScale;
|
||||
}
|
||||
|
||||
|
||||
if (somethingChanged ||
|
||||
pointInA != _pointInA ||
|
||||
axisInA != _axisInA ||
|
||||
otherEntityID != _otherEntityID ||
|
||||
pointInB != _pointInB ||
|
||||
axisInB != _axisInB ||
|
||||
linearLow != _linearLow ||
|
||||
linearHigh != _linearHigh ||
|
||||
angularLow != _angularLow ||
|
||||
angularHigh != _angularHigh ||
|
||||
linearTarget != _linearTarget ||
|
||||
linearTimeScale != _linearTimeScale ||
|
||||
linearTargetSet != _linearTargetSet ||
|
||||
angularTarget != _angularTarget ||
|
||||
angularTimeScale != _angularTimeScale ||
|
||||
angularTargetSet != _angularTargetSet) {
|
||||
// something changed
|
||||
needUpdate = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (needUpdate) {
|
||||
withWriteLock([&] {
|
||||
_pointInA = pointInA;
|
||||
_axisInA = axisInA;
|
||||
_otherEntityID = otherEntityID;
|
||||
_pointInB = pointInB;
|
||||
_axisInB = axisInB;
|
||||
_linearLow = linearLow;
|
||||
_linearHigh = linearHigh;
|
||||
_angularLow = angularLow;
|
||||
_angularHigh = angularHigh;
|
||||
_linearTarget = linearTarget;
|
||||
_linearTimeScale = linearTimeScale;
|
||||
_linearTargetSet = linearTargetSet;
|
||||
_angularTarget = angularTarget;
|
||||
_angularTimeScale = angularTimeScale;
|
||||
_angularTargetSet = angularTargetSet;
|
||||
|
||||
_active = true;
|
||||
|
||||
auto ownerEntity = _ownerEntity.lock();
|
||||
if (ownerEntity) {
|
||||
ownerEntity->setDynamicDataDirty(true);
|
||||
ownerEntity->setDynamicDataNeedsTransmit(true);
|
||||
}
|
||||
});
|
||||
|
||||
updateSlider();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariantMap ObjectConstraintSlider::getArguments() {
|
||||
QVariantMap arguments = ObjectDynamic::getArguments();
|
||||
withReadLock([&] {
|
||||
if (_constraint) {
|
||||
arguments["point"] = glmToQMap(_pointInA);
|
||||
arguments["axis"] = glmToQMap(_axisInA);
|
||||
arguments["otherEntityID"] = _otherEntityID;
|
||||
arguments["otherPoint"] = glmToQMap(_pointInB);
|
||||
arguments["otherAxis"] = glmToQMap(_axisInB);
|
||||
arguments["linearLow"] = _linearLow;
|
||||
arguments["linearHigh"] = _linearHigh;
|
||||
arguments["angularLow"] = _angularLow;
|
||||
arguments["angularHigh"] = _angularHigh;
|
||||
arguments["linearTarget"] = _linearTarget;
|
||||
arguments["linearTimeScale"] = _linearTimeScale;
|
||||
arguments["linearTargetSet"] = _linearTargetSet;
|
||||
arguments["angularTarget"] = _angularTarget;
|
||||
arguments["angularTimeScale"] = _angularTimeScale;
|
||||
arguments["angularTargetSet"] = _angularTargetSet;
|
||||
arguments["linearPosition"] = static_cast<btSliderConstraint*>(_constraint)->getLinearPos();
|
||||
arguments["angularPosition"] = static_cast<btSliderConstraint*>(_constraint)->getAngularPos();
|
||||
}
|
||||
});
|
||||
return arguments;
|
||||
}
|
||||
|
||||
QByteArray ObjectConstraintSlider::serialize() const {
|
||||
QByteArray serializedConstraintArguments;
|
||||
QDataStream dataStream(&serializedConstraintArguments, QIODevice::WriteOnly);
|
||||
|
||||
dataStream << DYNAMIC_TYPE_SLIDER;
|
||||
dataStream << getID();
|
||||
dataStream << ObjectConstraintSlider::constraintVersion;
|
||||
|
||||
withReadLock([&] {
|
||||
dataStream << localTimeToServerTime(_expires);
|
||||
dataStream << _tag;
|
||||
|
||||
dataStream << _pointInA;
|
||||
dataStream << _axisInA;
|
||||
dataStream << _otherEntityID;
|
||||
dataStream << _pointInB;
|
||||
dataStream << _axisInB;
|
||||
dataStream << _linearLow;
|
||||
dataStream << _linearHigh;
|
||||
dataStream << _angularLow;
|
||||
dataStream << _angularHigh;
|
||||
dataStream << _linearTarget;
|
||||
dataStream << _linearTimeScale;
|
||||
dataStream << _linearTargetSet;
|
||||
dataStream << _angularTarget;
|
||||
dataStream << _angularTimeScale;
|
||||
dataStream << _angularTargetSet;
|
||||
});
|
||||
|
||||
return serializedConstraintArguments;
|
||||
}
|
||||
|
||||
void ObjectConstraintSlider::deserialize(QByteArray serializedArguments) {
|
||||
QDataStream dataStream(serializedArguments);
|
||||
|
||||
EntityDynamicType type;
|
||||
dataStream >> type;
|
||||
assert(type == getType());
|
||||
|
||||
QUuid id;
|
||||
dataStream >> id;
|
||||
assert(id == getID());
|
||||
|
||||
uint16_t serializationVersion;
|
||||
dataStream >> serializationVersion;
|
||||
if (serializationVersion != ObjectConstraintSlider::constraintVersion) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
withWriteLock([&] {
|
||||
quint64 serverExpires;
|
||||
dataStream >> serverExpires;
|
||||
_expires = serverTimeToLocalTime(serverExpires);
|
||||
dataStream >> _tag;
|
||||
|
||||
dataStream >> _pointInA;
|
||||
dataStream >> _axisInA;
|
||||
dataStream >> _otherEntityID;
|
||||
dataStream >> _pointInB;
|
||||
dataStream >> _axisInB;
|
||||
dataStream >> _linearLow;
|
||||
dataStream >> _linearHigh;
|
||||
dataStream >> _angularLow;
|
||||
dataStream >> _angularHigh;
|
||||
dataStream >> _linearTarget;
|
||||
dataStream >> _linearTimeScale;
|
||||
dataStream >> _linearTargetSet;
|
||||
dataStream >> _angularTarget;
|
||||
dataStream >> _angularTimeScale;
|
||||
dataStream >> _angularTargetSet;
|
||||
|
||||
_active = true;
|
||||
});
|
||||
}
|
63
libraries/physics/src/ObjectConstraintSlider.h
Normal file
63
libraries/physics/src/ObjectConstraintSlider.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// ObjectConstraintSlider.h
|
||||
// libraries/physics/src
|
||||
//
|
||||
// Created by Seth Alves 2017-4-23
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ObjectConstraintSlider_h
|
||||
#define hifi_ObjectConstraintSlider_h
|
||||
|
||||
#include "ObjectConstraint.h"
|
||||
|
||||
// http://bulletphysics.org/Bullet/BulletFull/classbtSliderConstraint.html
|
||||
|
||||
class ObjectConstraintSlider : public ObjectConstraint {
|
||||
public:
|
||||
ObjectConstraintSlider(const QUuid& id, EntityItemPointer ownerEntity);
|
||||
virtual ~ObjectConstraintSlider();
|
||||
|
||||
virtual void prepareForPhysicsSimulation() override;
|
||||
|
||||
virtual bool updateArguments(QVariantMap arguments) override;
|
||||
virtual QVariantMap getArguments() override;
|
||||
|
||||
virtual QByteArray serialize() const override;
|
||||
virtual void deserialize(QByteArray serializedArguments) override;
|
||||
|
||||
virtual QList<btRigidBody*> getRigidBodies() override;
|
||||
virtual btTypedConstraint* getConstraint() override;
|
||||
|
||||
protected:
|
||||
static const uint16_t constraintVersion;
|
||||
|
||||
void updateSlider();
|
||||
|
||||
glm::vec3 _pointInA;
|
||||
glm::vec3 _axisInA;
|
||||
|
||||
EntityItemID _otherEntityID;
|
||||
glm::vec3 _pointInB;
|
||||
glm::vec3 _axisInB;
|
||||
|
||||
float _linearLow { std::numeric_limits<float>::max() };
|
||||
float _linearHigh { std::numeric_limits<float>::min() };
|
||||
|
||||
float _angularLow { -TWO_PI };
|
||||
float _angularHigh { TWO_PI };
|
||||
|
||||
float _linearTarget { 0.0f };
|
||||
float _linearTimeScale { 0.0f };
|
||||
bool _linearTargetSet { false };
|
||||
|
||||
float _angularTarget { 0.0f };
|
||||
float _angularTimeScale { 0.0f };
|
||||
bool _angularTargetSet { false };
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_ObjectConstraintSlider_h
|
Loading…
Reference in a new issue