mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +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),
|
||||
_bodySensorMatrix(),
|
||||
_goToPending(false),
|
||||
_goToSafe(true),
|
||||
_goToPosition(),
|
||||
_goToOrientation(),
|
||||
_prevShouldDrawHead(true),
|
||||
|
@ -509,7 +510,9 @@ void MyAvatar::update(float deltaTime) {
|
|||
if (_physicsSafetyPending && qApp->isPhysicsEnabled() && _characterController.isEnabledAndReady()) {
|
||||
// When needed and ready, arrange to check and fix.
|
||||
_physicsSafetyPending = false;
|
||||
safeLanding(_goToPosition); // no-op if already safe
|
||||
if (_goToSafe) {
|
||||
safeLanding(_goToPosition); // no-op if already safe
|
||||
}
|
||||
}
|
||||
|
||||
Head* head = getHead();
|
||||
|
@ -3007,7 +3010,7 @@ void MyAvatar::goToFeetLocation(const glm::vec3& newPosition,
|
|||
|
||||
void MyAvatar::goToLocation(const glm::vec3& newPosition,
|
||||
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:
|
||||
// - 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;
|
||||
_goToPosition = newPosition;
|
||||
_goToSafe = withSafeLanding;
|
||||
_goToOrientation = getWorldOrientation();
|
||||
if (hasOrientation) {
|
||||
qCDebug(interfaceapp).nospace() << "MyAvatar goToLocation - new orientation is "
|
||||
|
@ -3299,6 +3303,17 @@ bool MyAvatar::getCollisionsEnabled() {
|
|||
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) {
|
||||
qCDebug(interfaceapp) << "MyAvatar.characterControllerEnabled is deprecated. Use MyAvatar.collisionsEnabled instead.";
|
||||
setCollisionsEnabled(enabled);
|
||||
|
|
|
@ -1017,6 +1017,12 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE bool getCollisionsEnabled();
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.getCollisionCapsule
|
||||
* @returns {object}
|
||||
*/
|
||||
Q_INVOKABLE QVariantMap getCollisionCapsule();
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setCharacterControllerEnabled
|
||||
* @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 {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} [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.
|
||||
*/
|
||||
void goToLocation(const glm::vec3& newPosition,
|
||||
bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(),
|
||||
bool shouldFaceLocation = false);
|
||||
bool shouldFaceLocation = false, bool withSafeLanding = true);
|
||||
/**jsdoc
|
||||
* @function MyAvatar.goToLocation
|
||||
* @param {object} properties
|
||||
|
@ -1720,6 +1727,7 @@ private:
|
|||
|
||||
bool _goToPending { false };
|
||||
bool _physicsSafetyPending { false };
|
||||
bool _goToSafe { true };
|
||||
glm::vec3 _goToPosition;
|
||||
glm::quat _goToOrientation;
|
||||
|
||||
|
|
|
@ -136,9 +136,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.state = TELEPORTER_STATES.IDLE;
|
||||
this.currentTarget = TARGET.INVALID;
|
||||
this.currentResult = null;
|
||||
this.capsuleHeight = 2.0;
|
||||
this.capsuleRadius = 0.25;
|
||||
this.pickHeightOffset = 0.01;
|
||||
this.capsuleThreshold = 0.05;
|
||||
|
||||
this.getOtherModule = function() {
|
||||
var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter;
|
||||
|
@ -176,18 +174,38 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
maxDistance: 8.0
|
||||
});
|
||||
|
||||
this.teleportCollisionPick = Picks.createPick(PickType.Collision, {
|
||||
enabled: true,
|
||||
filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS,
|
||||
shape: {
|
||||
shapeType: "capsule-y",
|
||||
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 },
|
||||
parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end,
|
||||
threshold: 0.05
|
||||
});
|
||||
|
||||
this.teleportCollisionPick;
|
||||
|
||||
this.recreateCollisionPick = function() {
|
||||
if (_this.teleportCollisionPick !== undefined) {
|
||||
Picks.removePick(_this.teleportCollisionPick);
|
||||
}
|
||||
|
||||
var capsuleData = MyAvatar.getCollisionCapsule();
|
||||
var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end);
|
||||
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, {
|
||||
joint: "Avatar",
|
||||
filter: Picks.PICK_ENTITIES,
|
||||
|
@ -222,8 +240,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
Pointers.removePointer(_this.teleportParabolaHeadInvisible);
|
||||
Picks.removePick(_this.teleportCollisionPick);
|
||||
};
|
||||
|
||||
// Picks.setIgnoreItems(_this.teleportCollisionPick, []);
|
||||
|
||||
this.axisButtonStateX = 0; // Left/right axis button pressed.
|
||||
this.axisButtonStateY = 0; // Up/down axis button pressed.
|
||||
|
@ -355,7 +371,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
} else if (target === TARGET.SURFACE) {
|
||||
var offset = getAvatarFootOffset();
|
||||
result.intersection.y += offset;
|
||||
MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false);
|
||||
MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false, false);
|
||||
HMD.centerUI();
|
||||
MyAvatar.centerBody();
|
||||
}
|
||||
|
@ -558,7 +574,55 @@ 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-Ignore-Add');
|
||||
Messages.subscribe('Hifi-Teleport-Ignore-Remove');
|
||||
|
|
Loading…
Reference in a new issue