mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 10:43:45 +02:00
Merge pull request #6796 from AndrewMeadows/collision-groups
entity collision masks can be set via script
This commit is contained in:
commit
6f85ee135f
20 changed files with 261 additions and 106 deletions
|
@ -106,7 +106,7 @@ var GRABBABLE_PROPERTIES = [
|
||||||
"position",
|
"position",
|
||||||
"rotation",
|
"rotation",
|
||||||
"gravity",
|
"gravity",
|
||||||
"ignoreForCollisions",
|
"collisionMask",
|
||||||
"collisionsWillMove",
|
"collisionsWillMove",
|
||||||
"locked",
|
"locked",
|
||||||
"name"
|
"name"
|
||||||
|
@ -117,7 +117,6 @@ var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
|
||||||
|
|
||||||
var DEFAULT_GRABBABLE_DATA = {
|
var DEFAULT_GRABBABLE_DATA = {
|
||||||
grabbable: true,
|
grabbable: true,
|
||||||
invertSolidWhileHeld: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,6 +163,11 @@ var POINT_HAND_STATES = [STATE_NEAR_TRIGGER, STATE_CONTINUE_NEAR_TRIGGER, STATE_
|
||||||
var FAR_GRASP_HAND_STATES = [STATE_DISTANCE_HOLDING, STATE_CONTINUE_DISTANCE_HOLDING];
|
var FAR_GRASP_HAND_STATES = [STATE_DISTANCE_HOLDING, STATE_CONTINUE_DISTANCE_HOLDING];
|
||||||
// otherwise grasp
|
// otherwise grasp
|
||||||
|
|
||||||
|
// collision masks are specified by comma-separated list of group names
|
||||||
|
// the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar
|
||||||
|
var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar";
|
||||||
|
|
||||||
|
|
||||||
function stateToName(state) {
|
function stateToName(state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_OFF:
|
case STATE_OFF:
|
||||||
|
@ -1823,7 +1827,6 @@ function MyController(hand) {
|
||||||
|
|
||||||
this.activateEntity = function(entityID, grabbedProperties) {
|
this.activateEntity = function(entityID, grabbedProperties) {
|
||||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, entityID, DEFAULT_GRABBABLE_DATA);
|
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, entityID, DEFAULT_GRABBABLE_DATA);
|
||||||
var invertSolidWhileHeld = grabbableData["invertSolidWhileHeld"];
|
|
||||||
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
|
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
|
||||||
data["activated"] = true;
|
data["activated"] = true;
|
||||||
data["avatarId"] = MyAvatar.sessionUUID;
|
data["avatarId"] = MyAvatar.sessionUUID;
|
||||||
|
@ -1831,18 +1834,16 @@ function MyController(hand) {
|
||||||
// zero gravity and set ignoreForCollisions in a way that lets us put them back, after all grabs are done
|
// zero gravity and set ignoreForCollisions in a way that lets us put them back, after all grabs are done
|
||||||
if (data["refCount"] == 1) {
|
if (data["refCount"] == 1) {
|
||||||
data["gravity"] = grabbedProperties.gravity;
|
data["gravity"] = grabbedProperties.gravity;
|
||||||
data["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions;
|
data["collisionMask"] = grabbedProperties.collisionMask;
|
||||||
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
||||||
var whileHeldProperties = {
|
var whileHeldProperties = {
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
}
|
},
|
||||||
|
"collisionMask": COLLISION_MASK_WHILE_GRABBED
|
||||||
};
|
};
|
||||||
if (invertSolidWhileHeld) {
|
|
||||||
whileHeldProperties["ignoreForCollisions"] = !grabbedProperties.ignoreForCollisions;
|
|
||||||
}
|
|
||||||
Entities.editEntity(entityID, whileHeldProperties);
|
Entities.editEntity(entityID, whileHeldProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1857,7 +1858,7 @@ function MyController(hand) {
|
||||||
if (data["refCount"] < 1) {
|
if (data["refCount"] < 1) {
|
||||||
Entities.editEntity(entityID, {
|
Entities.editEntity(entityID, {
|
||||||
gravity: data["gravity"],
|
gravity: data["gravity"],
|
||||||
ignoreForCollisions: data["ignoreForCollisions"],
|
collisionMask: data["collisionMask"],
|
||||||
collisionsWillMove: data["collisionsWillMove"]
|
collisionsWillMove: data["collisionsWillMove"]
|
||||||
});
|
});
|
||||||
data = null;
|
data = null;
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <PhysicsHelpers.h>
|
|
||||||
#include <PhysicsCollisionGroups.h>
|
#include <PhysicsCollisionGroups.h>
|
||||||
|
#include <PhysicsEngine.h>
|
||||||
|
#include <PhysicsHelpers.h>
|
||||||
|
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
#include "AvatarMotionState.h"
|
#include "AvatarMotionState.h"
|
||||||
|
@ -143,7 +144,8 @@ QUuid AvatarMotionState::getSimulatorID() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
int16_t AvatarMotionState::computeCollisionGroup() const {
|
void AvatarMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
|
||||||
return COLLISION_GROUP_OTHER_AVATAR;
|
group = BULLET_COLLISION_GROUP_OTHER_AVATAR;
|
||||||
|
mask = PhysicsEngine::getCollisionMask(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
|
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
|
||||||
|
|
||||||
virtual int16_t computeCollisionGroup() const override;
|
virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const;
|
||||||
|
|
||||||
friend class AvatarManager;
|
friend class AvatarManager;
|
||||||
friend class Avatar;
|
friend class Avatar;
|
||||||
|
|
|
@ -64,6 +64,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
_angularDamping(ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
|
_angularDamping(ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
|
||||||
_visible(ENTITY_ITEM_DEFAULT_VISIBLE),
|
_visible(ENTITY_ITEM_DEFAULT_VISIBLE),
|
||||||
_ignoreForCollisions(ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS),
|
_ignoreForCollisions(ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS),
|
||||||
|
_collisionMask(ENTITY_COLLISION_MASK_DEFAULT),
|
||||||
_collisionsWillMove(ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE),
|
_collisionsWillMove(ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE),
|
||||||
_locked(ENTITY_ITEM_DEFAULT_LOCKED),
|
_locked(ENTITY_ITEM_DEFAULT_LOCKED),
|
||||||
_userData(ENTITY_ITEM_DEFAULT_USER_DATA),
|
_userData(ENTITY_ITEM_DEFAULT_USER_DATA),
|
||||||
|
@ -123,6 +124,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
||||||
requestedProperties += PROP_ANGULAR_DAMPING;
|
requestedProperties += PROP_ANGULAR_DAMPING;
|
||||||
requestedProperties += PROP_VISIBLE;
|
requestedProperties += PROP_VISIBLE;
|
||||||
requestedProperties += PROP_IGNORE_FOR_COLLISIONS;
|
requestedProperties += PROP_IGNORE_FOR_COLLISIONS;
|
||||||
|
requestedProperties += PROP_COLLISION_MASK;
|
||||||
requestedProperties += PROP_COLLISIONS_WILL_MOVE;
|
requestedProperties += PROP_COLLISIONS_WILL_MOVE;
|
||||||
requestedProperties += PROP_LOCKED;
|
requestedProperties += PROP_LOCKED;
|
||||||
requestedProperties += PROP_USER_DATA;
|
requestedProperties += PROP_USER_DATA;
|
||||||
|
@ -259,6 +261,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
|
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
|
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, getIgnoreForCollisions());
|
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, getIgnoreForCollisions());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, getCollisionMask());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, getCollisionsWillMove());
|
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, getCollisionsWillMove());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
|
||||||
|
@ -678,6 +681,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping);
|
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping);
|
||||||
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
|
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
|
||||||
READ_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions);
|
READ_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_COLLISION_MASK, uint8_t, updateCollisionMask);
|
||||||
READ_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, bool, updateCollisionsWillMove);
|
READ_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, bool, updateCollisionsWillMove);
|
||||||
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked);
|
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked);
|
||||||
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
|
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
|
||||||
|
@ -1041,6 +1045,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRenderAlpha, getLocalRenderAlpha);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRenderAlpha, getLocalRenderAlpha);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ignoreForCollisions, getIgnoreForCollisions);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ignoreForCollisions, getIgnoreForCollisions);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionMask, getCollisionMask);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionsWillMove, getCollisionsWillMove);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionsWillMove, getCollisionsWillMove);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
|
||||||
|
@ -1096,6 +1101,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(restitution, updateRestitution);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(restitution, updateRestitution);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(friction, updateFriction);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(friction, updateFriction);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ignoreForCollisions, updateIgnoreForCollisions);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ignoreForCollisions, updateIgnoreForCollisions);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionMask, updateCollisionMask);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionsWillMove, updateCollisionsWillMove);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionsWillMove, updateCollisionsWillMove);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(created, updateCreated);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(created, updateCreated);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, updateLifetime);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, updateLifetime);
|
||||||
|
@ -1445,6 +1451,13 @@ void EntityItem::updateIgnoreForCollisions(bool value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItem::updateCollisionMask(uint8_t value) {
|
||||||
|
if ((_collisionMask & ENTITY_COLLISION_MASK_DEFAULT) != (value & ENTITY_COLLISION_MASK_DEFAULT)) {
|
||||||
|
_collisionMask = (value & ENTITY_COLLISION_MASK_DEFAULT);
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EntityItem::updateCollisionsWillMove(bool value) {
|
void EntityItem::updateCollisionsWillMove(bool value) {
|
||||||
if (_collisionsWillMove != value) {
|
if (_collisionsWillMove != value) {
|
||||||
_collisionsWillMove = value;
|
_collisionsWillMove = value;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <Octree.h> // for EncodeBitstreamParams class
|
#include <Octree.h> // for EncodeBitstreamParams class
|
||||||
#include <OctreeElement.h> // for OctreeElement::AppendState
|
#include <OctreeElement.h> // for OctreeElement::AppendState
|
||||||
#include <OctreePacketData.h>
|
#include <OctreePacketData.h>
|
||||||
|
#include <PhysicsCollisionGroups.h>
|
||||||
#include <ShapeInfo.h>
|
#include <ShapeInfo.h>
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
#include <SpatiallyNestable.h>
|
#include <SpatiallyNestable.h>
|
||||||
|
@ -273,6 +274,9 @@ public:
|
||||||
bool getIgnoreForCollisions() const { return _ignoreForCollisions; }
|
bool getIgnoreForCollisions() const { return _ignoreForCollisions; }
|
||||||
void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; }
|
void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; }
|
||||||
|
|
||||||
|
uint8_t getCollisionMask() const { return _collisionMask; }
|
||||||
|
void setCollisionMask(uint8_t value) { _collisionMask = value; }
|
||||||
|
|
||||||
bool getCollisionsWillMove() const { return _collisionsWillMove; }
|
bool getCollisionsWillMove() const { return _collisionsWillMove; }
|
||||||
void setCollisionsWillMove(bool value) { _collisionsWillMove = value; }
|
void setCollisionsWillMove(bool value) { _collisionsWillMove = value; }
|
||||||
|
|
||||||
|
@ -327,6 +331,7 @@ public:
|
||||||
void updateAngularVelocity(const glm::vec3& value);
|
void updateAngularVelocity(const glm::vec3& value);
|
||||||
void updateAngularDamping(float value);
|
void updateAngularDamping(float value);
|
||||||
void updateIgnoreForCollisions(bool value);
|
void updateIgnoreForCollisions(bool value);
|
||||||
|
void updateCollisionMask(uint8_t value);
|
||||||
void updateCollisionsWillMove(bool value);
|
void updateCollisionsWillMove(bool value);
|
||||||
void updateLifetime(float value);
|
void updateLifetime(float value);
|
||||||
void updateCreated(uint64_t value);
|
void updateCreated(uint64_t value);
|
||||||
|
@ -440,6 +445,7 @@ protected:
|
||||||
float _angularDamping;
|
float _angularDamping;
|
||||||
bool _visible;
|
bool _visible;
|
||||||
bool _ignoreForCollisions;
|
bool _ignoreForCollisions;
|
||||||
|
uint8_t _collisionMask { ENTITY_COLLISION_MASK_DEFAULT };
|
||||||
bool _collisionsWillMove;
|
bool _collisionsWillMove;
|
||||||
bool _locked;
|
bool _locked;
|
||||||
QString _userData;
|
QString _userData;
|
||||||
|
|
|
@ -116,6 +116,59 @@ void buildStringToShapeTypeLookup() {
|
||||||
addShapeType(SHAPE_TYPE_CYLINDER_Z);
|
addShapeType(SHAPE_TYPE_CYLINDER_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString getCollisionGroupAsString(uint8_t group) {
|
||||||
|
switch (group) {
|
||||||
|
case USER_COLLISION_GROUP_DYNAMIC:
|
||||||
|
return "dynamic";
|
||||||
|
case USER_COLLISION_GROUP_STATIC:
|
||||||
|
return "static";
|
||||||
|
case USER_COLLISION_GROUP_KINEMATIC:
|
||||||
|
return "kinematic";
|
||||||
|
case USER_COLLISION_GROUP_MY_AVATAR:
|
||||||
|
return "myAvatar";
|
||||||
|
case USER_COLLISION_GROUP_OTHER_AVATAR:
|
||||||
|
return "otherAvatar";
|
||||||
|
};
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getCollisionGroupAsBitMask(const QStringRef& name) {
|
||||||
|
if (0 == name.compare("dynamic")) {
|
||||||
|
return USER_COLLISION_GROUP_DYNAMIC;
|
||||||
|
} else if (0 == name.compare("static")) {
|
||||||
|
return USER_COLLISION_GROUP_STATIC;
|
||||||
|
} else if (0 == name.compare("kinematic")) {
|
||||||
|
return USER_COLLISION_GROUP_KINEMATIC;
|
||||||
|
} else if (0 == name.compare("myAvatar")) {
|
||||||
|
return USER_COLLISION_GROUP_MY_AVATAR;
|
||||||
|
} else if (0 == name.compare("otherAvatar")) {
|
||||||
|
return USER_COLLISION_GROUP_OTHER_AVATAR;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EntityItemProperties::getCollisionMaskAsString() const {
|
||||||
|
QString maskString("");
|
||||||
|
for (int i = 0; i < NUM_USER_COLLISION_GROUPS; ++i) {
|
||||||
|
uint8_t group = 0x01 << i;
|
||||||
|
if (group & _collisionMask) {
|
||||||
|
maskString.append(getCollisionGroupAsString(group));
|
||||||
|
maskString.append(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maskString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItemProperties::setCollisionMaskFromString(const QString& maskString) {
|
||||||
|
QVector<QStringRef> groups = maskString.splitRef(',');
|
||||||
|
uint8_t mask = 0x00;
|
||||||
|
for (auto group : groups) {
|
||||||
|
mask |= getCollisionGroupAsBitMask(group);
|
||||||
|
}
|
||||||
|
_collisionMask = mask;
|
||||||
|
_collisionMaskChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
QString EntityItemProperties::getShapeTypeAsString() const {
|
QString EntityItemProperties::getShapeTypeAsString() const {
|
||||||
if (_shapeType < sizeof(shapeTypeNames) / sizeof(char *))
|
if (_shapeType < sizeof(shapeTypeNames) / sizeof(char *))
|
||||||
return QString(shapeTypeNames[_shapeType]);
|
return QString(shapeTypeNames[_shapeType]);
|
||||||
|
@ -203,6 +256,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_DAMPING, angularDamping);
|
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_IGNORE_FOR_COLLISIONS, ignoreForCollisions);
|
CHECK_PROPERTY_CHANGE(PROP_IGNORE_FOR_COLLISIONS, ignoreForCollisions);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_COLLISION_MASK, collisionMask);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_COLLISIONS_WILL_MOVE, collisionsWillMove);
|
CHECK_PROPERTY_CHANGE(PROP_COLLISIONS_WILL_MOVE, collisionsWillMove);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_IS_SPOTLIGHT, isSpotlight);
|
CHECK_PROPERTY_CHANGE(PROP_IS_SPOTLIGHT, isSpotlight);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_INTENSITY, intensity);
|
CHECK_PROPERTY_CHANGE(PROP_INTENSITY, intensity);
|
||||||
|
@ -317,6 +371,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IGNORE_FOR_COLLISIONS, ignoreForCollisions);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IGNORE_FOR_COLLISIONS, ignoreForCollisions);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISION_MASK, collisionMask, getCollisionMaskAsString());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONS_WILL_MOVE, collisionsWillMove);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONS_WILL_MOVE, collisionsWillMove);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_HREF, href);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_HREF, href);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DESCRIPTION, description);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DESCRIPTION, description);
|
||||||
|
@ -538,6 +593,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(glowLevel, float, setGlowLevel);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(glowLevel, float, setGlowLevel);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRenderAlpha, float, setLocalRenderAlpha);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRenderAlpha, float, setLocalRenderAlpha);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(ignoreForCollisions, bool, setIgnoreForCollisions);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(ignoreForCollisions, bool, setIgnoreForCollisions);
|
||||||
|
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(collisionMask, CollisionMask);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionsWillMove, bool, setCollisionsWillMove);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionsWillMove, bool, setCollisionsWillMove);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(isSpotlight, bool, setIsSpotlight);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isSpotlight, bool, setIsSpotlight);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(intensity, float, setIntensity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(intensity, float, setIntensity);
|
||||||
|
@ -700,6 +756,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
||||||
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3);
|
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float);
|
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool);
|
ADD_PROPERTY_TO_MAP(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLLISION_MASK, CollisionMask, collisionMask, uint8_t);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool);
|
ADD_PROPERTY_TO_MAP(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool);
|
ADD_PROPERTY_TO_MAP(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_INTENSITY, Intensity, intensity, float);
|
ADD_PROPERTY_TO_MAP(PROP_INTENSITY, Intensity, intensity, float);
|
||||||
|
@ -946,6 +1003,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping());
|
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible());
|
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, properties.getIgnoreForCollisions());
|
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, properties.getIgnoreForCollisions());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, properties.getCollisionMask());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, properties.getCollisionsWillMove());
|
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, properties.getCollisionsWillMove());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
||||||
|
@ -1238,6 +1296,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IGNORE_FOR_COLLISIONS, bool, setIgnoreForCollisions);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IGNORE_FOR_COLLISIONS, bool, setIgnoreForCollisions);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONS_WILL_MOVE, bool, setCollisionsWillMove);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONS_WILL_MOVE, bool, setCollisionsWillMove);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
|
||||||
|
@ -1419,6 +1478,7 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_localRenderAlphaChanged = true;
|
_localRenderAlphaChanged = true;
|
||||||
_isSpotlightChanged = true;
|
_isSpotlightChanged = true;
|
||||||
_ignoreForCollisionsChanged = true;
|
_ignoreForCollisionsChanged = true;
|
||||||
|
_collisionMaskChanged = true;
|
||||||
_collisionsWillMoveChanged = true;
|
_collisionsWillMoveChanged = true;
|
||||||
|
|
||||||
_intensityChanged = true;
|
_intensityChanged = true;
|
||||||
|
@ -1537,7 +1597,7 @@ bool EntityItemProperties::hasTerseUpdateChanges() const {
|
||||||
bool EntityItemProperties::hasMiscPhysicsChanges() const {
|
bool EntityItemProperties::hasMiscPhysicsChanges() const {
|
||||||
return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged
|
return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged
|
||||||
|| _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged ||
|
|| _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged ||
|
||||||
_compoundShapeURLChanged || _collisionsWillMoveChanged || _ignoreForCollisionsChanged;
|
_compoundShapeURLChanged || _collisionsWillMoveChanged || _ignoreForCollisionsChanged || _collisionMaskChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItemProperties::clearSimulationOwner() {
|
void EntityItemProperties::clearSimulationOwner() {
|
||||||
|
@ -1653,6 +1713,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
||||||
if (ignoreForCollisionsChanged()) {
|
if (ignoreForCollisionsChanged()) {
|
||||||
out += "ignoreForCollisions";
|
out += "ignoreForCollisions";
|
||||||
}
|
}
|
||||||
|
if (collisionMaskChanged()) {
|
||||||
|
out += "collisionMask";
|
||||||
|
}
|
||||||
if (collisionsWillMoveChanged()) {
|
if (collisionsWillMoveChanged()) {
|
||||||
out += "collisionsWillMove";
|
out += "collisionsWillMove";
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
DEFINE_PROPERTY_REF(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
||||||
DEFINE_PROPERTY(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING);
|
DEFINE_PROPERTY(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING);
|
||||||
DEFINE_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool, ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS);
|
DEFINE_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool, ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS);
|
||||||
|
DEFINE_PROPERTY(PROP_COLLISION_MASK, CollisionMask, collisionMask, uint8_t, ENTITY_COLLISION_MASK_DEFAULT);
|
||||||
DEFINE_PROPERTY(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool, ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE);
|
DEFINE_PROPERTY(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool, ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE);
|
||||||
DEFINE_PROPERTY(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool, false);
|
DEFINE_PROPERTY(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool, false);
|
||||||
DEFINE_PROPERTY(PROP_INTENSITY, Intensity, intensity, float, 1.0f);
|
DEFINE_PROPERTY(PROP_INTENSITY, Intensity, intensity, float, 1.0f);
|
||||||
|
@ -273,6 +274,10 @@ public:
|
||||||
void setJointRotationsDirty() { _jointRotationsSetChanged = true; _jointRotationsChanged = true; }
|
void setJointRotationsDirty() { _jointRotationsSetChanged = true; _jointRotationsChanged = true; }
|
||||||
void setJointTranslationsDirty() { _jointTranslationsSetChanged = true; _jointTranslationsChanged = true; }
|
void setJointTranslationsDirty() { _jointTranslationsSetChanged = true; _jointTranslationsChanged = true; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString getCollisionMaskAsString() const;
|
||||||
|
void setCollisionMaskFromString(const QString& maskString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUuid _id;
|
QUuid _id;
|
||||||
bool _idSet;
|
bool _idSet;
|
||||||
|
|
|
@ -191,6 +191,7 @@ inline quint16 quint16_convertFromScriptValue(const QScriptValue& v, bool& isVal
|
||||||
inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
||||||
inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
||||||
inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); }
|
inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); }
|
||||||
|
inline uint8_t uint8_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return (uint8_t)(0xff & v.toVariant().toInt(&isValid)); }
|
||||||
inline QString QString_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toString().trimmed(); }
|
inline QString QString_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toString().trimmed(); }
|
||||||
inline QUuid QUuid_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toUuid(); }
|
inline QUuid QUuid_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toUuid(); }
|
||||||
inline EntityItemID EntityItemID_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toUuid(); }
|
inline EntityItemID EntityItemID_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toUuid(); }
|
||||||
|
|
|
@ -165,6 +165,8 @@ enum EntityPropertyList {
|
||||||
PROP_JOINT_TRANSLATIONS_SET,
|
PROP_JOINT_TRANSLATIONS_SET,
|
||||||
PROP_JOINT_TRANSLATIONS,
|
PROP_JOINT_TRANSLATIONS,
|
||||||
|
|
||||||
|
PROP_COLLISION_MASK, // one byte of collision group flags
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ATTENTION: add new properties to end of list just ABOVE this line
|
// ATTENTION: add new properties to end of list just ABOVE this line
|
||||||
PROP_AFTER_LAST_ITEM,
|
PROP_AFTER_LAST_ITEM,
|
||||||
|
|
|
@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::EntityAdd:
|
case PacketType::EntityAdd:
|
||||||
case PacketType::EntityEdit:
|
case PacketType::EntityEdit:
|
||||||
case PacketType::EntityData:
|
case PacketType::EntityData:
|
||||||
return VERSION_ENTITITES_HAVE_QUERY_BOX;
|
return VERSION_ENTITITES_HAVE_COLLISION_MASK;
|
||||||
case PacketType::AvatarData:
|
case PacketType::AvatarData:
|
||||||
case PacketType::BulkAvatarData:
|
case PacketType::BulkAvatarData:
|
||||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::SoftAttachmentSupport);
|
return static_cast<PacketVersion>(AvatarMixerPacketVersion::SoftAttachmentSupport);
|
||||||
|
|
|
@ -164,6 +164,7 @@ const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51;
|
||||||
const PacketVersion VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
|
const PacketVersion VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
|
||||||
const PacketVersion VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE = 53;
|
const PacketVersion VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE = 53;
|
||||||
const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54;
|
const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54;
|
||||||
|
const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55;
|
||||||
|
|
||||||
enum class AvatarMixerPacketVersion : PacketVersion {
|
enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
TranslationSupport = 17,
|
TranslationSupport = 17,
|
||||||
|
|
|
@ -27,6 +27,9 @@ class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
|
||||||
public:
|
public:
|
||||||
ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) {
|
ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) {
|
||||||
_me = me;
|
_me = me;
|
||||||
|
// the RayResultCallback's group and mask must match MY_AVATAR
|
||||||
|
m_collisionFilterGroup = BULLET_COLLISION_GROUP_MY_AVATAR;
|
||||||
|
m_collisionFilterMask = BULLET_COLLISION_MASK_MY_AVATAR;
|
||||||
}
|
}
|
||||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) {
|
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) {
|
||||||
if (rayResult.m_collisionObject == _me) {
|
if (rayResult.m_collisionObject == _me) {
|
||||||
|
@ -84,7 +87,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
|
||||||
// Before adding the RigidBody to the world we must save its oldGravity to the side
|
// Before adding the RigidBody to the world we must save its oldGravity to the side
|
||||||
// because adding an object to the world will overwrite it with the default gravity.
|
// because adding an object to the world will overwrite it with the default gravity.
|
||||||
btVector3 oldGravity = _rigidBody->getGravity();
|
btVector3 oldGravity = _rigidBody->getGravity();
|
||||||
_dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR);
|
_dynamicsWorld->addRigidBody(_rigidBody, BULLET_COLLISION_GROUP_MY_AVATAR, BULLET_COLLISION_MASK_MY_AVATAR);
|
||||||
_dynamicsWorld->addAction(this);
|
_dynamicsWorld->addAction(this);
|
||||||
// restore gravity settings
|
// restore gravity settings
|
||||||
_rigidBody->setGravity(oldGravity);
|
_rigidBody->setGravity(oldGravity);
|
||||||
|
|
|
@ -80,9 +80,9 @@ EntityMotionState::~EntityMotionState() {
|
||||||
_entity = nullptr;
|
_entity = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
|
void EntityMotionState::updateServerPhysicsVariables() {
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
if (_entity->getSimulatorID() == sessionID) {
|
if (_entity->getSimulatorID() == PhysicsEngine::getSessionID()) {
|
||||||
// don't slam these values if we are the simulation owner
|
// don't slam these values if we are the simulation owner
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,10 +96,10 @@ void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
updateServerPhysicsVariables(engine->getSessionID());
|
updateServerPhysicsVariables();
|
||||||
ObjectMotionState::handleEasyChanges(flags, engine);
|
ObjectMotionState::handleEasyChanges(flags);
|
||||||
|
|
||||||
if (flags & Simulation::DIRTY_SIMULATOR_ID) {
|
if (flags & Simulation::DIRTY_SIMULATOR_ID) {
|
||||||
_loopsWithoutOwner = 0;
|
_loopsWithoutOwner = 0;
|
||||||
|
@ -113,7 +113,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
|
||||||
_outgoingPriority = NO_PRORITY;
|
_outgoingPriority = NO_PRORITY;
|
||||||
} else {
|
} else {
|
||||||
_nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS;
|
_nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||||
if (engine->getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) {
|
if (PhysicsEngine::getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) {
|
||||||
// we own the simulation or our priority looses to (or ties with) remote
|
// we own the simulation or our priority looses to (or ties with) remote
|
||||||
_outgoingPriority = NO_PRORITY;
|
_outgoingPriority = NO_PRORITY;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||||
updateServerPhysicsVariables(engine->getSessionID());
|
updateServerPhysicsVariables();
|
||||||
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
|
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +523,17 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
||||||
uint32_t dirtyFlags = 0;
|
uint32_t dirtyFlags = 0;
|
||||||
if (_body && _entity) {
|
if (_body && _entity) {
|
||||||
dirtyFlags = _entity->getDirtyFlags();
|
dirtyFlags = _entity->getDirtyFlags();
|
||||||
|
|
||||||
|
if (dirtyFlags | Simulation::DIRTY_SIMULATOR_ID) {
|
||||||
|
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
|
||||||
|
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
|
||||||
|
uint8_t entityCollisionMask = _entity->getCollisionMask();
|
||||||
|
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
|
||||||
|
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
|
||||||
|
// bits are asymmetric --> flag for reinsertion in physics simulation
|
||||||
|
dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
|
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
|
||||||
int bodyFlags = _body->getCollisionFlags();
|
int bodyFlags = _body->getCollisionFlags();
|
||||||
bool isMoving = _entity->isMoving();
|
bool isMoving = _entity->isMoving();
|
||||||
|
@ -610,19 +621,40 @@ QString EntityMotionState::getName() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
int16_t EntityMotionState::computeCollisionGroup() const {
|
void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
|
||||||
if (_entity->getIgnoreForCollisions()) {
|
group = BULLET_COLLISION_GROUP_STATIC;
|
||||||
return COLLISION_GROUP_COLLISIONLESS;
|
if (_entity) {
|
||||||
|
if (_entity->getIgnoreForCollisions()) {
|
||||||
|
group = BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||||
|
}
|
||||||
|
switch (computeObjectMotionType()){
|
||||||
|
case MOTION_TYPE_STATIC:
|
||||||
|
group = BULLET_COLLISION_GROUP_STATIC;
|
||||||
|
break;
|
||||||
|
case MOTION_TYPE_DYNAMIC:
|
||||||
|
group = BULLET_COLLISION_GROUP_DYNAMIC;
|
||||||
|
break;
|
||||||
|
case MOTION_TYPE_KINEMATIC:
|
||||||
|
group = BULLET_COLLISION_GROUP_KINEMATIC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch (computeObjectMotionType()){
|
|
||||||
case MOTION_TYPE_STATIC:
|
mask = PhysicsEngine::getCollisionMask(group);
|
||||||
return COLLISION_GROUP_STATIC;
|
if (_entity) {
|
||||||
case MOTION_TYPE_KINEMATIC:
|
uint8_t entityCollisionMask = _entity->getCollisionMask();
|
||||||
return COLLISION_GROUP_KINEMATIC;
|
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
|
||||||
default:
|
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
|
||||||
break;
|
// asymmetric avatar collision mask bits
|
||||||
|
if (!_entity->getSimulatorID().isNull() && _entity->getSimulatorID() != PhysicsEngine::getSessionID()) {
|
||||||
|
// someone else owns the simulation, so we swap the interpretation of the bits
|
||||||
|
entityCollisionMask ^= USER_COLLISION_MASK_AVATARS | ~entityCollisionMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask &= (int16_t)(entityCollisionMask);
|
||||||
}
|
}
|
||||||
return COLLISION_GROUP_DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityMotionState::setOutgoingPriority(quint8 priority) {
|
void EntityMotionState::setOutgoingPriority(quint8 priority) {
|
||||||
|
|
|
@ -28,8 +28,8 @@ public:
|
||||||
EntityMotionState(btCollisionShape* shape, EntityItemPointer item);
|
EntityMotionState(btCollisionShape* shape, EntityItemPointer item);
|
||||||
virtual ~EntityMotionState();
|
virtual ~EntityMotionState();
|
||||||
|
|
||||||
void updateServerPhysicsVariables(const QUuid& sessionID);
|
void updateServerPhysicsVariables();
|
||||||
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
virtual bool handleEasyChanges(uint32_t& flags);
|
||||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
virtual QString getName() const override;
|
virtual QString getName() const override;
|
||||||
|
|
||||||
virtual int16_t computeCollisionGroup() const override;
|
virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const;
|
||||||
|
|
||||||
// eternal logic can suggest a simuator priority bid for the next outgoing update
|
// eternal logic can suggest a simuator priority bid for the next outgoing update
|
||||||
void setOutgoingPriority(quint8 priority);
|
void setOutgoingPriority(quint8 priority);
|
||||||
|
|
|
@ -62,9 +62,10 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
float offsetLength = offset.length();
|
float offsetLength = offset.length();
|
||||||
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
if (offsetLength > 0) {
|
float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f;
|
||||||
float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f;
|
if (speed > rigidBody->getLinearSleepingThreshold()) {
|
||||||
targetVelocity = (-speed / offsetLength) * offset;
|
targetVelocity = (-speed / offsetLength) * offset;
|
||||||
|
rigidBody->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// this action is aggresively critically damped and defeats the current velocity
|
// this action is aggresively critically damped and defeats the current velocity
|
||||||
|
@ -90,10 +91,10 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
//
|
//
|
||||||
// dQ = Q1 * Q0^
|
// dQ = Q1 * Q0^
|
||||||
btQuaternion deltaQ = target * bodyRotation.inverse();
|
btQuaternion deltaQ = target * bodyRotation.inverse();
|
||||||
float angle = deltaQ.getAngle();
|
float speed = deltaQ.getAngle() / _angularTimeScale;
|
||||||
const float MIN_ANGLE = 1.0e-4f;
|
if (speed > rigidBody->getAngularSleepingThreshold()) {
|
||||||
if (angle > MIN_ANGLE) {
|
targetVelocity = speed * deltaQ.getAxis();
|
||||||
targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
|
rigidBody->activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this action is aggresively critically damped and defeats the current velocity
|
// this action is aggresively critically damped and defeats the current velocity
|
||||||
|
|
|
@ -164,7 +164,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
if (flags & Simulation::DIRTY_POSITION) {
|
if (flags & Simulation::DIRTY_POSITION) {
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
btVector3 newPosition = glmToBullet(getObjectPosition());
|
btVector3 newPosition = glmToBullet(getObjectPosition());
|
||||||
|
@ -251,7 +251,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
|
||||||
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
|
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
|
||||||
// no HARD flags remain, so do any EASY changes
|
// no HARD flags remain, so do any EASY changes
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
handleEasyChanges(flags, engine);
|
handleEasyChanges(flags);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
handleEasyChanges(flags, engine);
|
handleEasyChanges(flags);
|
||||||
}
|
}
|
||||||
// it is possible there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
// it is possible there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
||||||
// so we check again before we reinsert:
|
// so we check again before we reinsert:
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
ObjectMotionState(btCollisionShape* shape);
|
ObjectMotionState(btCollisionShape* shape);
|
||||||
~ObjectMotionState();
|
~ObjectMotionState();
|
||||||
|
|
||||||
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
virtual bool handleEasyChanges(uint32_t& flags);
|
||||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
void updateBodyMaterialProperties();
|
void updateBodyMaterialProperties();
|
||||||
|
@ -136,7 +136,7 @@ public:
|
||||||
|
|
||||||
virtual QString getName() const { return ""; }
|
virtual QString getName() const { return ""; }
|
||||||
|
|
||||||
virtual int16_t computeCollisionGroup() const = 0;
|
virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const = 0;
|
||||||
|
|
||||||
bool isActive() const { return _body ? _body->isActive() : false; }
|
bool isActive() const { return _body ? _body->isActive() : false; }
|
||||||
|
|
||||||
|
|
|
@ -22,20 +22,43 @@ uint32_t PhysicsEngine::getNumSubsteps() {
|
||||||
return _numSubsteps;
|
return _numSubsteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btHashMap<btHashInt, int16_t> _collisionMasks;
|
||||||
|
|
||||||
|
void initCollisionMaskTable() {
|
||||||
|
if (_collisionMasks.size() == 0) {
|
||||||
|
// build table of masks with their group as the key
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_DYNAMIC), BULLET_COLLISION_MASK_DYNAMIC);
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_STATIC), BULLET_COLLISION_MASK_STATIC);
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_KINEMATIC), BULLET_COLLISION_MASK_KINEMATIC);
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_MY_AVATAR), BULLET_COLLISION_MASK_MY_AVATAR);
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_OTHER_AVATAR), BULLET_COLLISION_MASK_OTHER_AVATAR);
|
||||||
|
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_COLLISIONLESS), BULLET_COLLISION_MASK_COLLISIONLESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
int16_t PhysicsEngine::getCollisionMask(int16_t group) {
|
||||||
|
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
||||||
|
return mask ? *mask : BULLET_COLLISION_MASK_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid _sessionID;
|
||||||
|
|
||||||
|
// static
|
||||||
|
void PhysicsEngine::setSessionUUID(const QUuid& sessionID) {
|
||||||
|
_sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
const QUuid& PhysicsEngine::getSessionID() {
|
||||||
|
return _sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
|
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
|
||||||
_originOffset(offset),
|
_originOffset(offset),
|
||||||
_myAvatarController(nullptr) {
|
_myAvatarController(nullptr) {
|
||||||
// build table of masks with their group as the key
|
initCollisionMaskTable();
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEFAULT), COLLISION_MASK_DEFAULT);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_STATIC), COLLISION_MASK_STATIC);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_KINEMATIC), COLLISION_MASK_KINEMATIC);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEBRIS), COLLISION_MASK_DEBRIS);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_TRIGGER), COLLISION_MASK_TRIGGER);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_MY_AVATAR), COLLISION_MASK_MY_AVATAR);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_MY_ATTACHMENT), COLLISION_MASK_MY_ATTACHMENT);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_OTHER_AVATAR), COLLISION_MASK_OTHER_AVATAR);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_OTHER_ATTACHMENT), COLLISION_MASK_OTHER_ATTACHMENT);
|
|
||||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_COLLISIONLESS), COLLISION_MASK_COLLISIONLESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsEngine::~PhysicsEngine() {
|
PhysicsEngine::~PhysicsEngine() {
|
||||||
|
@ -139,8 +162,9 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
|
||||||
body->setFlags(BT_DISABLE_WORLD_GRAVITY);
|
body->setFlags(BT_DISABLE_WORLD_GRAVITY);
|
||||||
motionState->updateBodyMaterialProperties();
|
motionState->updateBodyMaterialProperties();
|
||||||
|
|
||||||
int16_t group = motionState->computeCollisionGroup();
|
int16_t group, mask;
|
||||||
_dynamicsWorld->addRigidBody(body, group, getCollisionMask(group));
|
motionState->computeCollisionGroupAndMask(group, mask);
|
||||||
|
_dynamicsWorld->addRigidBody(body, group, mask);
|
||||||
|
|
||||||
motionState->clearIncomingDirtyFlags();
|
motionState->clearIncomingDirtyFlags();
|
||||||
}
|
}
|
||||||
|
@ -198,7 +222,7 @@ VectorOfMotionStates PhysicsEngine::changeObjects(const VectorOfMotionStates& ob
|
||||||
stillNeedChange.push_back(object);
|
stillNeedChange.push_back(object);
|
||||||
}
|
}
|
||||||
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
if (object->handleEasyChanges(flags, this)) {
|
if (object->handleEasyChanges(flags)) {
|
||||||
object->clearIncomingDirtyFlags();
|
object->clearIncomingDirtyFlags();
|
||||||
} else {
|
} else {
|
||||||
stillNeedChange.push_back(object);
|
stillNeedChange.push_back(object);
|
||||||
|
@ -457,11 +481,6 @@ void PhysicsEngine::setCharacterController(CharacterController* character) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PhysicsEngine::getCollisionMask(int16_t group) const {
|
|
||||||
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
|
||||||
return mask ? *mask : COLLISION_MASK_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityActionPointer PhysicsEngine::getActionByID(const QUuid& actionID) const {
|
EntityActionPointer PhysicsEngine::getActionByID(const QUuid& actionID) const {
|
||||||
if (_objectActions.contains(actionID)) {
|
if (_objectActions.contains(actionID)) {
|
||||||
return _objectActions[actionID];
|
return _objectActions[actionID];
|
||||||
|
|
|
@ -45,14 +45,16 @@ typedef QVector<Collision> CollisionEvents;
|
||||||
|
|
||||||
class PhysicsEngine {
|
class PhysicsEngine {
|
||||||
public:
|
public:
|
||||||
|
static int16_t getCollisionMask(int16_t group);
|
||||||
|
|
||||||
uint32_t getNumSubsteps();
|
uint32_t getNumSubsteps();
|
||||||
|
|
||||||
PhysicsEngine(const glm::vec3& offset);
|
PhysicsEngine(const glm::vec3& offset);
|
||||||
~PhysicsEngine();
|
~PhysicsEngine();
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void setSessionUUID(const QUuid& sessionID) { _sessionID = sessionID; }
|
static void setSessionUUID(const QUuid& sessionID);
|
||||||
const QUuid& getSessionID() const { return _sessionID; }
|
static const QUuid& getSessionID();
|
||||||
|
|
||||||
void removeObjects(const VectorOfMotionStates& objects);
|
void removeObjects(const VectorOfMotionStates& objects);
|
||||||
void removeObjects(const SetOfMotionStates& objects); // only called during teardown
|
void removeObjects(const SetOfMotionStates& objects); // only called during teardown
|
||||||
|
@ -88,8 +90,6 @@ public:
|
||||||
|
|
||||||
void dumpNextStats() { _dumpNextStats = true; }
|
void dumpNextStats() { _dumpNextStats = true; }
|
||||||
|
|
||||||
int16_t getCollisionMask(int16_t group) const;
|
|
||||||
|
|
||||||
EntityActionPointer getActionByID(const QUuid& actionID) const;
|
EntityActionPointer getActionByID(const QUuid& actionID) const;
|
||||||
void addAction(EntityActionPointer action);
|
void addAction(EntityActionPointer action);
|
||||||
void removeAction(const QUuid actionID);
|
void removeAction(const QUuid actionID);
|
||||||
|
@ -122,12 +122,10 @@ private:
|
||||||
bool _dumpNextStats = false;
|
bool _dumpNextStats = false;
|
||||||
bool _hasOutgoingChanges = false;
|
bool _hasOutgoingChanges = false;
|
||||||
|
|
||||||
QUuid _sessionID;
|
|
||||||
CollisionEvents _collisionEvents;
|
CollisionEvents _collisionEvents;
|
||||||
|
|
||||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
|
|
||||||
btHashMap<btHashInt, int16_t> _collisionMasks;
|
|
||||||
|
|
||||||
uint32_t _numSubsteps;
|
uint32_t _numSubsteps;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* Note: These are the Bullet collision groups defined in btBroadphaseProxy. Only
|
/* Note: These are the Bullet collision groups defined in btBroadphaseProxy. Only
|
||||||
* DefaultFilter and StaticFilter are explicitly used by Bullet (when the collision
|
* DefaultFilter and StaticFilter are explicitly used by Bullet (when the collision
|
||||||
* filter of an object is not manually specified), the rest are merely suggestions.
|
* filter of an object is not manually specified), the rest are merely suggestions.
|
||||||
*
|
*
|
||||||
enum CollisionFilterGroups {
|
enum CollisionFilterGroups {
|
||||||
|
@ -28,52 +28,60 @@ enum CollisionFilterGroups {
|
||||||
AllFilter = -1
|
AllFilter = -1
|
||||||
}
|
}
|
||||||
*
|
*
|
||||||
* When using custom collision filters we pretty much need to do all or nothing.
|
* When using custom collision filters we pretty much need to do all or nothing.
|
||||||
* We'll be doing it all which means we define our own groups and build custom masks
|
* We'll be doing it all which means we define our own groups and build custom masks
|
||||||
* for everything.
|
* for everything.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int16_t COLLISION_GROUP_DEFAULT = 1 << 0;
|
const int16_t BULLET_COLLISION_GROUP_STATIC = 1 << 0;
|
||||||
const int16_t COLLISION_GROUP_STATIC = 1 << 1;
|
const int16_t BULLET_COLLISION_GROUP_DYNAMIC = 1 << 1;
|
||||||
const int16_t COLLISION_GROUP_KINEMATIC = 1 << 2;
|
const int16_t BULLET_COLLISION_GROUP_KINEMATIC = 1 << 2;
|
||||||
const int16_t COLLISION_GROUP_DEBRIS = 1 << 3;
|
const int16_t BULLET_COLLISION_GROUP_MY_AVATAR = 1 << 3;
|
||||||
const int16_t COLLISION_GROUP_TRIGGER = 1 << 4;
|
const int16_t BULLET_COLLISION_GROUP_OTHER_AVATAR = 1 << 4;
|
||||||
const int16_t COLLISION_GROUP_MY_AVATAR = 1 << 5;
|
|
||||||
const int16_t COLLISION_GROUP_OTHER_AVATAR = 1 << 6;
|
|
||||||
const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7;
|
|
||||||
const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8;
|
|
||||||
// ...
|
// ...
|
||||||
const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 14;
|
const int16_t BULLET_COLLISION_GROUP_COLLISIONLESS = 1 << 14;
|
||||||
|
|
||||||
|
|
||||||
/* Note: In order for objectA to collide with objectB at the filter stage
|
/* Note: In order for objectA to collide with objectB at the filter stage
|
||||||
* both (groupA & maskB) and (groupB & maskA) must be non-zero.
|
* both (groupA & maskB) and (groupB & maskA) must be non-zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// DEFAULT collides with everything except COLLISIONLESS
|
// the default collision mask is: collides with everything except collisionless
|
||||||
const int16_t COLLISION_MASK_DEFAULT = ~ COLLISION_GROUP_COLLISIONLESS;
|
const int16_t BULLET_COLLISION_MASK_DEFAULT = ~ BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||||
|
|
||||||
// STATIC also doesn't collide with other STATIC
|
// STATIC does not collide with itself (as optimization of physics simulation)
|
||||||
const int16_t COLLISION_MASK_STATIC = ~ (COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_STATIC);
|
const int16_t BULLET_COLLISION_MASK_STATIC = ~ (BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_STATIC);
|
||||||
|
|
||||||
const int16_t COLLISION_MASK_KINEMATIC = COLLISION_MASK_DEFAULT;
|
const int16_t BULLET_COLLISION_MASK_DYNAMIC = BULLET_COLLISION_MASK_DEFAULT;
|
||||||
|
const int16_t BULLET_COLLISION_MASK_KINEMATIC = BULLET_COLLISION_MASK_DEFAULT;
|
||||||
|
|
||||||
// DEBRIS also doesn't collide with other DEBRIS, or TRIGGER
|
// MY_AVATAR does not collide with itself
|
||||||
const int16_t COLLISION_MASK_DEBRIS = ~ (COLLISION_GROUP_COLLISIONLESS
|
const int16_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR);
|
||||||
| COLLISION_GROUP_DEBRIS
|
|
||||||
| COLLISION_GROUP_TRIGGER);
|
|
||||||
|
|
||||||
// TRIGGER also doesn't collide with DEBRIS, TRIGGER, or STATIC (TRIGGER only detects moveable things that matter)
|
const int16_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_MASK_DEFAULT;
|
||||||
const int16_t COLLISION_MASK_TRIGGER = COLLISION_MASK_DEBRIS & ~(COLLISION_GROUP_STATIC);
|
|
||||||
|
|
||||||
// AVATAR also doesn't collide with corresponding ATTACHMENTs
|
|
||||||
const int16_t COLLISION_MASK_MY_AVATAR = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_MY_ATTACHMENT);
|
|
||||||
const int16_t COLLISION_MASK_MY_ATTACHMENT = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_MY_AVATAR);
|
|
||||||
const int16_t COLLISION_MASK_OTHER_AVATAR = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_OTHER_ATTACHMENT);
|
|
||||||
const int16_t COLLISION_MASK_OTHER_ATTACHMENT = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_OTHER_AVATAR);
|
|
||||||
|
|
||||||
// COLLISIONLESS gets an empty mask.
|
// COLLISIONLESS gets an empty mask.
|
||||||
const int16_t COLLISION_MASK_COLLISIONLESS = 0;
|
const int16_t BULLET_COLLISION_MASK_COLLISIONLESS = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// The USER collision groups are exposed to script and can be used to generate per-object collision masks.
|
||||||
|
// They are not necessarily the same as the BULLET_COLLISION_GROUPS, but we start them off with matching numbers.
|
||||||
|
const uint8_t USER_COLLISION_GROUP_STATIC = 1 << 0;
|
||||||
|
const uint8_t USER_COLLISION_GROUP_DYNAMIC = 1 << 1;
|
||||||
|
const uint8_t USER_COLLISION_GROUP_KINEMATIC = 1 << 2;
|
||||||
|
const uint8_t USER_COLLISION_GROUP_MY_AVATAR = 1 << 3;
|
||||||
|
const uint8_t USER_COLLISION_GROUP_OTHER_AVATAR = 1 << 4;
|
||||||
|
|
||||||
|
const uint8_t ENTITY_COLLISION_MASK_DEFAULT =
|
||||||
|
USER_COLLISION_GROUP_STATIC |
|
||||||
|
USER_COLLISION_GROUP_DYNAMIC |
|
||||||
|
USER_COLLISION_GROUP_KINEMATIC |
|
||||||
|
USER_COLLISION_GROUP_MY_AVATAR |
|
||||||
|
USER_COLLISION_GROUP_OTHER_AVATAR;
|
||||||
|
|
||||||
|
const uint8_t USER_COLLISION_MASK_AVATARS = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR;
|
||||||
|
|
||||||
|
const int NUM_USER_COLLISION_GROUPS = 5;
|
||||||
|
|
||||||
#endif // hifi_PhysicsCollisionGroups_h
|
#endif // hifi_PhysicsCollisionGroups_h
|
||||||
|
|
Loading…
Reference in a new issue