mirror of
https://github.com/overte-org/overte.git
synced 2025-07-24 01:03:58 +02:00
Update capsule when scale/load and teleport without safe landing
This commit is contained in:
parent
99e6e3d112
commit
abb632afda
3 changed files with 108 additions and 21 deletions
|
@ -113,6 +113,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
||||||
_recentModeReadings(MODE_READINGS_RING_BUFFER_SIZE),
|
_recentModeReadings(MODE_READINGS_RING_BUFFER_SIZE),
|
||||||
_bodySensorMatrix(),
|
_bodySensorMatrix(),
|
||||||
_goToPending(false),
|
_goToPending(false),
|
||||||
|
_goToSafe(true),
|
||||||
_goToPosition(),
|
_goToPosition(),
|
||||||
_goToOrientation(),
|
_goToOrientation(),
|
||||||
_prevShouldDrawHead(true),
|
_prevShouldDrawHead(true),
|
||||||
|
@ -509,7 +510,9 @@ void MyAvatar::update(float deltaTime) {
|
||||||
if (_physicsSafetyPending && qApp->isPhysicsEnabled() && _characterController.isEnabledAndReady()) {
|
if (_physicsSafetyPending && qApp->isPhysicsEnabled() && _characterController.isEnabledAndReady()) {
|
||||||
// When needed and ready, arrange to check and fix.
|
// When needed and ready, arrange to check and fix.
|
||||||
_physicsSafetyPending = false;
|
_physicsSafetyPending = false;
|
||||||
safeLanding(_goToPosition); // no-op if already safe
|
if (_goToSafe) {
|
||||||
|
safeLanding(_goToPosition); // no-op if already safe
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Head* head = getHead();
|
Head* head = getHead();
|
||||||
|
@ -3007,7 +3010,7 @@ void MyAvatar::goToFeetLocation(const glm::vec3& newPosition,
|
||||||
|
|
||||||
void MyAvatar::goToLocation(const glm::vec3& newPosition,
|
void MyAvatar::goToLocation(const glm::vec3& newPosition,
|
||||||
bool hasOrientation, const glm::quat& newOrientation,
|
bool hasOrientation, const glm::quat& newOrientation,
|
||||||
bool shouldFaceLocation) {
|
bool shouldFaceLocation, bool withSafeLanding) {
|
||||||
|
|
||||||
// Most cases of going to a place or user go through this now. Some possible improvements to think about in the future:
|
// Most cases of going to a place or user go through this now. Some possible improvements to think about in the future:
|
||||||
// - It would be nice if this used the same teleport steps and smoothing as in the teleport.js script, as long as it
|
// - It would be nice if this used the same teleport steps and smoothing as in the teleport.js script, as long as it
|
||||||
|
@ -3027,6 +3030,7 @@ void MyAvatar::goToLocation(const glm::vec3& newPosition,
|
||||||
|
|
||||||
_goToPending = true;
|
_goToPending = true;
|
||||||
_goToPosition = newPosition;
|
_goToPosition = newPosition;
|
||||||
|
_goToSafe = withSafeLanding;
|
||||||
_goToOrientation = getWorldOrientation();
|
_goToOrientation = getWorldOrientation();
|
||||||
if (hasOrientation) {
|
if (hasOrientation) {
|
||||||
qCDebug(interfaceapp).nospace() << "MyAvatar goToLocation - new orientation is "
|
qCDebug(interfaceapp).nospace() << "MyAvatar goToLocation - new orientation is "
|
||||||
|
@ -3299,6 +3303,17 @@ bool MyAvatar::getCollisionsEnabled() {
|
||||||
return _characterController.computeCollisionGroup() != BULLET_COLLISION_GROUP_COLLISIONLESS;
|
return _characterController.computeCollisionGroup() != BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap MyAvatar::getCollisionCapsule() {
|
||||||
|
glm::vec3 start, end;
|
||||||
|
float radius;
|
||||||
|
getCapsule(start, end, radius);
|
||||||
|
QVariantMap capsule;
|
||||||
|
capsule["start"] = vec3toVariant(start);
|
||||||
|
capsule["end"] = vec3toVariant(end);
|
||||||
|
capsule["radius"] = QVariant(radius);
|
||||||
|
return capsule;
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::setCharacterControllerEnabled(bool enabled) {
|
void MyAvatar::setCharacterControllerEnabled(bool enabled) {
|
||||||
qCDebug(interfaceapp) << "MyAvatar.characterControllerEnabled is deprecated. Use MyAvatar.collisionsEnabled instead.";
|
qCDebug(interfaceapp) << "MyAvatar.characterControllerEnabled is deprecated. Use MyAvatar.collisionsEnabled instead.";
|
||||||
setCollisionsEnabled(enabled);
|
setCollisionsEnabled(enabled);
|
||||||
|
|
|
@ -1017,6 +1017,12 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE bool getCollisionsEnabled();
|
Q_INVOKABLE bool getCollisionsEnabled();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function MyAvatar.getCollisionCapsule
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE QVariantMap getCollisionCapsule();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.setCharacterControllerEnabled
|
* @function MyAvatar.setCharacterControllerEnabled
|
||||||
* @param {boolean} enabled
|
* @param {boolean} enabled
|
||||||
|
@ -1178,11 +1184,12 @@ public slots:
|
||||||
* @param {boolean} [hasOrientation=false] - Set to <code>true</code> to set the orientation of the avatar.
|
* @param {boolean} [hasOrientation=false] - Set to <code>true</code> to set the orientation of the avatar.
|
||||||
* @param {Quat} [orientation=Quat.IDENTITY] - The new orientation for the avatar.
|
* @param {Quat} [orientation=Quat.IDENTITY] - The new orientation for the avatar.
|
||||||
* @param {boolean} [shouldFaceLocation=false] - Set to <code>true</code> to position the avatar a short distance away from
|
* @param {boolean} [shouldFaceLocation=false] - Set to <code>true</code> to position the avatar a short distance away from
|
||||||
|
* @param {boolean} [withSafeLanding=true] - Set to <code>false</code> MyAvatar::safeLanding will not be called (used when teleporting).
|
||||||
* the new position and orientate the avatar to face the position.
|
* the new position and orientate the avatar to face the position.
|
||||||
*/
|
*/
|
||||||
void goToLocation(const glm::vec3& newPosition,
|
void goToLocation(const glm::vec3& newPosition,
|
||||||
bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(),
|
bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(),
|
||||||
bool shouldFaceLocation = false);
|
bool shouldFaceLocation = false, bool withSafeLanding = true);
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.goToLocation
|
* @function MyAvatar.goToLocation
|
||||||
* @param {object} properties
|
* @param {object} properties
|
||||||
|
@ -1720,6 +1727,7 @@ private:
|
||||||
|
|
||||||
bool _goToPending { false };
|
bool _goToPending { false };
|
||||||
bool _physicsSafetyPending { false };
|
bool _physicsSafetyPending { false };
|
||||||
|
bool _goToSafe { true };
|
||||||
glm::vec3 _goToPosition;
|
glm::vec3 _goToPosition;
|
||||||
glm::quat _goToOrientation;
|
glm::quat _goToOrientation;
|
||||||
|
|
||||||
|
|
|
@ -136,9 +136,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.state = TELEPORTER_STATES.IDLE;
|
this.state = TELEPORTER_STATES.IDLE;
|
||||||
this.currentTarget = TARGET.INVALID;
|
this.currentTarget = TARGET.INVALID;
|
||||||
this.currentResult = null;
|
this.currentResult = null;
|
||||||
this.capsuleHeight = 2.0;
|
this.capsuleThreshold = 0.05;
|
||||||
this.capsuleRadius = 0.25;
|
|
||||||
this.pickHeightOffset = 0.01;
|
|
||||||
|
|
||||||
this.getOtherModule = function() {
|
this.getOtherModule = function() {
|
||||||
var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter;
|
var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter;
|
||||||
|
@ -176,17 +174,37 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
maxDistance: 8.0
|
maxDistance: 8.0
|
||||||
});
|
});
|
||||||
|
|
||||||
this.teleportCollisionPick = Picks.createPick(PickType.Collision, {
|
this.teleportCollisionPick;
|
||||||
enabled: true,
|
|
||||||
filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS,
|
this.recreateCollisionPick = function() {
|
||||||
shape: {
|
if (_this.teleportCollisionPick !== undefined) {
|
||||||
shapeType: "capsule-y",
|
Picks.removePick(_this.teleportCollisionPick);
|
||||||
dimensions: { x: _this.capsuleRadius * 2.0, y: _this.capsuleHeight - (_this.capsuleRadius * 2.0), z: _this.capsuleRadius * 2.0 }
|
}
|
||||||
},
|
|
||||||
position: { x: 0, y: _this.pickHeightOffset + (_this.capsuleHeight * 0.5), z: 0 },
|
var capsuleData = MyAvatar.getCollisionCapsule();
|
||||||
parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end,
|
var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end);
|
||||||
threshold: 0.05
|
var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position);
|
||||||
});
|
var radius = capsuleData.radius;
|
||||||
|
var height = 2.0 * radius + capsuleHeight;
|
||||||
|
|
||||||
|
_this.teleportCollisionPick = Picks.createPick(PickType.Collision, {
|
||||||
|
enabled: true,
|
||||||
|
parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end,
|
||||||
|
filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS,
|
||||||
|
shape: {
|
||||||
|
shapeType: "capsule-y",
|
||||||
|
dimensions: {
|
||||||
|
x: radius * 2.0,
|
||||||
|
y: height - (radius * 2.0),
|
||||||
|
z: radius * 2.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
position: { x: 0, y: offset + (height * 0.5), z: 0 },
|
||||||
|
threshold: _this.capsuleThreshold
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.recreateCollisionPick();
|
||||||
|
|
||||||
this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, {
|
this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, {
|
||||||
joint: "Avatar",
|
joint: "Avatar",
|
||||||
|
@ -223,8 +241,6 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
Picks.removePick(_this.teleportCollisionPick);
|
Picks.removePick(_this.teleportCollisionPick);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Picks.setIgnoreItems(_this.teleportCollisionPick, []);
|
|
||||||
|
|
||||||
this.axisButtonStateX = 0; // Left/right axis button pressed.
|
this.axisButtonStateX = 0; // Left/right axis button pressed.
|
||||||
this.axisButtonStateY = 0; // Up/down axis button pressed.
|
this.axisButtonStateY = 0; // Up/down axis button pressed.
|
||||||
this.BUTTON_TRANSITION_DELAY = 100; // Allow time for transition from direction buttons to touch-pad.
|
this.BUTTON_TRANSITION_DELAY = 100; // Allow time for transition from direction buttons to touch-pad.
|
||||||
|
@ -355,7 +371,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
} else if (target === TARGET.SURFACE) {
|
} else if (target === TARGET.SURFACE) {
|
||||||
var offset = getAvatarFootOffset();
|
var offset = getAvatarFootOffset();
|
||||||
result.intersection.y += offset;
|
result.intersection.y += offset;
|
||||||
MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false);
|
MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false, false);
|
||||||
HMD.centerUI();
|
HMD.centerUI();
|
||||||
MyAvatar.centerBody();
|
MyAvatar.centerBody();
|
||||||
}
|
}
|
||||||
|
@ -559,6 +575,54 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class execute a function after the param value haven't been set for a certain time
|
||||||
|
// It's used in this case to recreate the collision picks once when the avatar scale process ends
|
||||||
|
|
||||||
|
var AfterSet = function(time, maxsteps, callback) {
|
||||||
|
var self = this;
|
||||||
|
this.time = time;
|
||||||
|
this.callback = callback;
|
||||||
|
this.init = false;
|
||||||
|
this.value = 0;
|
||||||
|
this.interval;
|
||||||
|
this.maxsteps = maxsteps;
|
||||||
|
this.steps = 0;
|
||||||
|
this.restateValue = function(value) {
|
||||||
|
if (self.steps++ > self.maxsteps) {
|
||||||
|
self.callback.call(this, self.value);
|
||||||
|
self.steps = 0;
|
||||||
|
}
|
||||||
|
if (!self.init) {
|
||||||
|
console.log("Starting apply after");
|
||||||
|
}
|
||||||
|
self.init = true;
|
||||||
|
self.value = value;
|
||||||
|
if (self.interval !== undefined) {
|
||||||
|
Script.clearInterval(self.interval);
|
||||||
|
}
|
||||||
|
self.interval = Script.setInterval(function() {
|
||||||
|
self.callback.call(this, self.value);
|
||||||
|
self.init = false;
|
||||||
|
Script.clearInterval(self.interval);
|
||||||
|
self.interval = undefined;
|
||||||
|
}, self.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var afterSet = new AfterSet(100, 30, function(value) {
|
||||||
|
leftTeleporter.recreateCollisionPick();
|
||||||
|
rightTeleporter.recreateCollisionPick();
|
||||||
|
});
|
||||||
|
|
||||||
|
MyAvatar.onLoadComplete.connect(function () {
|
||||||
|
leftTeleporter.recreateCollisionPick();
|
||||||
|
rightTeleporter.recreateCollisionPick();
|
||||||
|
});
|
||||||
|
|
||||||
|
MyAvatar.sensorToWorldScaleChanged.connect(function() {
|
||||||
|
afterSet.restateValue(MyAvatar.getSensorToWorldScale());
|
||||||
|
});
|
||||||
|
|
||||||
Messages.subscribe('Hifi-Teleport-Disabler');
|
Messages.subscribe('Hifi-Teleport-Disabler');
|
||||||
Messages.subscribe('Hifi-Teleport-Ignore-Add');
|
Messages.subscribe('Hifi-Teleport-Ignore-Add');
|
||||||
Messages.subscribe('Hifi-Teleport-Ignore-Remove');
|
Messages.subscribe('Hifi-Teleport-Ignore-Remove');
|
||||||
|
|
Loading…
Reference in a new issue