mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 19:52:26 +02:00
merge fix
This commit is contained in:
commit
1412d49a2f
27 changed files with 420 additions and 141 deletions
|
@ -69,6 +69,12 @@ function checkCamera() {
|
||||||
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
|
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
|
||||||
yaw -= viewJoystickPosition.x * JOYSTICK_YAW_MAG * deltaTime;
|
yaw -= viewJoystickPosition.x * JOYSTICK_YAW_MAG * deltaTime;
|
||||||
pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
|
pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
|
||||||
|
if (yaw > 360) {
|
||||||
|
yaw -= 360;
|
||||||
|
}
|
||||||
|
if (yaw < -360) {
|
||||||
|
yaw += 360;
|
||||||
|
}
|
||||||
var orientation = Quat.fromPitchYawRoll(pitch, yaw, roll);
|
var orientation = Quat.fromPitchYawRoll(pitch, yaw, roll);
|
||||||
Camera.setOrientation(orientation);
|
Camera.setOrientation(orientation);
|
||||||
}
|
}
|
||||||
|
|
210
examples/hydraMove.js
Normal file
210
examples/hydraMove.js
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
//
|
||||||
|
// hydraMove.js
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 2/10/14.
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// This is an example script that demonstrates use of the Controller and MyAvatar classes to implement
|
||||||
|
// avatar flying through the hydra/controller joysticks
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
var damping = 0.9;
|
||||||
|
var position = { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z };
|
||||||
|
var joysticksCaptured = false;
|
||||||
|
var THRUST_CONTROLLER = 0;
|
||||||
|
var VIEW_CONTROLLER = 1;
|
||||||
|
var INITIAL_THRUST_MULTPLIER = 1.0;
|
||||||
|
var THRUST_INCREASE_RATE = 1.05;
|
||||||
|
var MAX_THRUST_MULTIPLIER = 75.0;
|
||||||
|
var thrustMultiplier = INITIAL_THRUST_MULTPLIER;
|
||||||
|
var grabDelta = { x: 0, y: 0, z: 0};
|
||||||
|
var grabDeltaVelocity = { x: 0, y: 0, z: 0};
|
||||||
|
var grabStartRotation = { x: 0, y: 0, z: 0, w: 1};
|
||||||
|
var grabCurrentRotation = { x: 0, y: 0, z: 0, w: 1};
|
||||||
|
var grabbingWithRightHand = false;
|
||||||
|
var wasGrabbingWithRightHand = false;
|
||||||
|
var grabbingWithLeftHand = false;
|
||||||
|
var wasGrabbingWithLeftHand = false;
|
||||||
|
var EPSILON = 0.000001;
|
||||||
|
var velocity = { x: 0, y: 0, z: 0};
|
||||||
|
var deltaTime = 1/60; // approximately our FPS - maybe better to be elapsed time since last call
|
||||||
|
var THRUST_MAG_UP = 800.0;
|
||||||
|
var THRUST_MAG_DOWN = 300.0;
|
||||||
|
var THRUST_MAG_FWD = 500.0;
|
||||||
|
var THRUST_MAG_BACK = 300.0;
|
||||||
|
var THRUST_MAG_LATERAL = 250.0;
|
||||||
|
var THRUST_JUMP = 120.0;
|
||||||
|
|
||||||
|
var YAW_MAG = 500.0;
|
||||||
|
var PITCH_MAG = 100.0;
|
||||||
|
var THRUST_MAG_HAND_JETS = THRUST_MAG_FWD;
|
||||||
|
var JOYSTICK_YAW_MAG = YAW_MAG;
|
||||||
|
var JOYSTICK_PITCH_MAG = PITCH_MAG * 0.5;
|
||||||
|
|
||||||
|
|
||||||
|
var LEFT_PALM = 0;
|
||||||
|
var LEFT_BUTTON_4 = 4;
|
||||||
|
var RIGHT_PALM = 2;
|
||||||
|
var RIGHT_BUTTON_4 = 10;
|
||||||
|
|
||||||
|
// Used by handleGrabBehavior() for managing the grab position changes
|
||||||
|
function getAndResetGrabDelta() {
|
||||||
|
var HAND_GRAB_SCALE_DISTANCE = 2.0;
|
||||||
|
var delta = Vec3.multiply(grabDelta, (MyAvatar.scale * HAND_GRAB_SCALE_DISTANCE));
|
||||||
|
grabDelta = { x: 0, y: 0, z: 0};
|
||||||
|
var avatarRotation = MyAvatar.orientation;
|
||||||
|
var result = Vec3.multiplyQbyV(avatarRotation, Vec3.multiply(delta, -1));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by handleGrabBehavior() for managing the grab velocity feature
|
||||||
|
function getAndResetGrabDeltaVelocity() {
|
||||||
|
var HAND_GRAB_SCALE_VELOCITY = 50.0;
|
||||||
|
var delta = Vec3.multiply(grabDeltaVelocity, (MyAvatar.scale * HAND_GRAB_SCALE_VELOCITY));
|
||||||
|
grabDeltaVelocity = { x: 0, y: 0, z: 0};
|
||||||
|
var avatarRotation = MyAvatar.orientation;
|
||||||
|
var result = Quat.multiply(avatarRotation, Vec3.multiply(delta, -1));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by handleGrabBehavior() for managing the grab rotation feature
|
||||||
|
function getAndResetGrabRotation() {
|
||||||
|
var quatDiff = Quat.multiply(grabCurrentRotation, Quat.inverse(grabStartRotation));
|
||||||
|
grabStartRotation = grabCurrentRotation;
|
||||||
|
return quatDiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles all the grab related behavior: position (crawl), velocity (flick), and rotate (twist)
|
||||||
|
function handleGrabBehavior() {
|
||||||
|
// check for and handle grab behaviors
|
||||||
|
grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4);
|
||||||
|
grabbingWithLeftHand = Controller.isButtonPressed(LEFT_BUTTON_4);
|
||||||
|
stoppedGrabbingWithLeftHand = false;
|
||||||
|
stoppedGrabbingWithRightHand = false;
|
||||||
|
|
||||||
|
if (grabbingWithRightHand && !wasGrabbingWithRightHand) {
|
||||||
|
// Just starting grab, capture starting rotation
|
||||||
|
grabStartRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
||||||
|
}
|
||||||
|
if (grabbingWithRightHand) {
|
||||||
|
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime));
|
||||||
|
grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
||||||
|
}
|
||||||
|
if (!grabbingWithRightHand && wasGrabbingWithRightHand) {
|
||||||
|
// Just ending grab, capture velocity
|
||||||
|
grabDeltaVelocity = Controller.getSpatialControlVelocity(RIGHT_PALM);
|
||||||
|
stoppedGrabbingWithRightHand = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grabbingWithLeftHand && !wasGrabbingWithLeftHand) {
|
||||||
|
// Just starting grab, capture starting rotation
|
||||||
|
grabStartRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grabbingWithLeftHand) {
|
||||||
|
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime));
|
||||||
|
grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
||||||
|
}
|
||||||
|
if (!grabbingWithLeftHand && wasGrabbingWithLeftHand) {
|
||||||
|
// Just ending grab, capture velocity
|
||||||
|
grabDeltaVelocity = Controller.getSpatialControlVelocity(LEFT_PALM);
|
||||||
|
stoppedGrabbingWithLeftHand = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
grabbing = grabbingWithRightHand || grabbingWithLeftHand;
|
||||||
|
stoppedGrabbing = stoppedGrabbingWithRightHand || stoppedGrabbingWithLeftHand;
|
||||||
|
|
||||||
|
if (grabbing) {
|
||||||
|
|
||||||
|
// move position
|
||||||
|
var moveFromGrab = getAndResetGrabDelta();
|
||||||
|
if (Vec3.length(moveFromGrab) > EPSILON) {
|
||||||
|
MyAvatar.position = Vec3.sum(MyAvatar.position, moveFromGrab);
|
||||||
|
velocity = { x: 0, y: 0, z: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// add some rotation...
|
||||||
|
var deltaRotation = getAndResetGrabRotation();
|
||||||
|
var GRAB_CONTROLLER_TURN_SCALING = 0.5;
|
||||||
|
var euler = Vec3.multiply(Quat.safeEulerAngles(deltaRotation), GRAB_CONTROLLER_TURN_SCALING);
|
||||||
|
|
||||||
|
// Adjust body yaw by yaw from controller
|
||||||
|
var orientation = Quat.multiply(Quat.angleAxis(-euler.y, {x:0, y: 1, z:0}), MyAvatar.orientation);
|
||||||
|
MyAvatar.orientation = orientation;
|
||||||
|
|
||||||
|
// Adjust head pitch from controller
|
||||||
|
MyAvatar.headPitch = MyAvatar.headPitch - euler.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add some velocity...
|
||||||
|
if (stoppedGrabbing) {
|
||||||
|
velocity = Vec3.sum(velocity, getAndResetGrabDeltaVelocity());
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle residual velocity
|
||||||
|
if(Vec3.length(velocity) > EPSILON) {
|
||||||
|
MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(velocity, deltaTime));
|
||||||
|
// damp velocity
|
||||||
|
velocity = Vec3.multiply(velocity, damping);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wasGrabbingWithRightHand = grabbingWithRightHand;
|
||||||
|
wasGrabbingWithLeftHand = grabbingWithLeftHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main update function that handles flying and grabbing behaviort
|
||||||
|
function flyWithHydra() {
|
||||||
|
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
||||||
|
|
||||||
|
if (thrustJoystickPosition.x != 0 || thrustJoystickPosition.y != 0) {
|
||||||
|
if (thrustMultiplier < MAX_THRUST_MULTIPLIER) {
|
||||||
|
thrustMultiplier *= 1 + (deltaTime * THRUST_INCREASE_RATE);
|
||||||
|
}
|
||||||
|
var currentOrientation = MyAvatar.orientation;
|
||||||
|
|
||||||
|
var front = Quat.getFront(currentOrientation);
|
||||||
|
var right = Quat.getRight(currentOrientation);
|
||||||
|
var up = Quat.getUp(currentOrientation);
|
||||||
|
|
||||||
|
var thrustFront = Vec3.multiply(front, MyAvatar.scale * THRUST_MAG_HAND_JETS *
|
||||||
|
thrustJoystickPosition.y * thrustMultiplier * deltaTime);
|
||||||
|
MyAvatar.addThrust(thrustFront);
|
||||||
|
var thrustRight = Vec3.multiply(right, MyAvatar.scale * THRUST_MAG_HAND_JETS *
|
||||||
|
thrustJoystickPosition.x * thrustMultiplier * deltaTime);
|
||||||
|
MyAvatar.addThrust(thrustRight);
|
||||||
|
} else {
|
||||||
|
thrustMultiplier = INITIAL_THRUST_MULTPLIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// View Controller
|
||||||
|
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
|
||||||
|
if (viewJoystickPosition.x != 0 || viewJoystickPosition.y != 0) {
|
||||||
|
|
||||||
|
// change the body yaw based on our x controller
|
||||||
|
var orientation = MyAvatar.orientation;
|
||||||
|
var deltaOrientation = Quat.fromPitchYawRoll(0, (-1 * viewJoystickPosition.x * JOYSTICK_YAW_MAG * deltaTime), 0);
|
||||||
|
MyAvatar.orientation = Quat.multiply(orientation, deltaOrientation);
|
||||||
|
|
||||||
|
// change the headPitch based on our x controller
|
||||||
|
//pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
|
||||||
|
var newPitch = MyAvatar.headPitch + (viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime);
|
||||||
|
MyAvatar.headPitch = newPitch;
|
||||||
|
}
|
||||||
|
handleGrabBehavior();
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.willSendVisualDataCallback.connect(flyWithHydra);
|
||||||
|
Controller.captureJoystick(THRUST_CONTROLLER);
|
||||||
|
Controller.captureJoystick(VIEW_CONTROLLER);
|
||||||
|
|
||||||
|
// Map keyPress and mouse move events to our callbacks
|
||||||
|
function scriptEnding() {
|
||||||
|
// re-enabled the standard application for touch events
|
||||||
|
Controller.releaseJoystick(THRUST_CONTROLLER);
|
||||||
|
Controller.releaseJoystick(VIEW_CONTROLLER);
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
BIN
interface/resources/meshes/body.jpg
Normal file
BIN
interface/resources/meshes/body.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
18
interface/resources/meshes/defaultAvatar_body.fst
Normal file
18
interface/resources/meshes/defaultAvatar_body.fst
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
scale=130
|
||||||
|
joint = jointRoot = jointRoot
|
||||||
|
joint = jointLean = jointSpine
|
||||||
|
joint = jointNeck = jointNeck
|
||||||
|
joint = jointHead = jointHeadtop
|
||||||
|
joint = joint_L_shoulder = joint_L_shoulder
|
||||||
|
freeJoint = joint_L_arm
|
||||||
|
freeJoint = joint_L_elbow
|
||||||
|
joint = jointLeftHand = joint_L_hand
|
||||||
|
joint = joint_R_shoulder = joint_R_shoulder
|
||||||
|
freeJoint = joint_R_arm
|
||||||
|
freeJoint = joint_R_elbow
|
||||||
|
joint = jointRightHand = joint_R_hand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
45
interface/resources/meshes/defaultAvatar_head.fst
Normal file
45
interface/resources/meshes/defaultAvatar_head.fst
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# faceshift target mapping file
|
||||||
|
name= defaultAvatar_head
|
||||||
|
filename=../../../Avatars/Jelly/jellyrob_blue.fbx
|
||||||
|
texdir=../../../Avatars/Jelly
|
||||||
|
scale=80
|
||||||
|
rx=0
|
||||||
|
ry=0
|
||||||
|
rz=0
|
||||||
|
tx=0
|
||||||
|
ty=0
|
||||||
|
tz=0
|
||||||
|
joint = jointNeck = jointNeck
|
||||||
|
bs = BrowsD_L = Leye1.BrowsD_L = 0.97
|
||||||
|
bs = BrowsD_R = Reye1.BrowsD_R = 1
|
||||||
|
bs = CheekSquint_L = Leye1.CheekSquint_L = 1
|
||||||
|
bs = CheekSquint_R = Reye1.CheekSquint_R = 1
|
||||||
|
bs = EyeBlink_L = Leye1.EyeBlink_L = 1
|
||||||
|
bs = EyeBlink_R = Reye1.EyeBlink_R = 1
|
||||||
|
bs = EyeDown_L = Leye1.EyeDown_L = 1
|
||||||
|
bs = EyeDown_R = Reye1.EyeDown_R = 0.99
|
||||||
|
bs = EyeIn_L = Leye1.EyeIn_L = 0.92
|
||||||
|
bs = EyeIn_R = Reye1.EyeIn_R = 1
|
||||||
|
bs = EyeOpen_L = Leye1.EyeOpen_L = 1
|
||||||
|
bs = EyeOpen_R = Reye1.EyeOpen_R = 1
|
||||||
|
bs = EyeOut_L = Leye1.EyeOut_L = 0.99
|
||||||
|
bs = EyeOut_R = Reye1.EyeOut_R = 1
|
||||||
|
bs = EyeUp_L = Leye1.EyeUp_L = 0.93
|
||||||
|
bs = EyeUp_R = Reye1.EyeUp_R = 1
|
||||||
|
bs = JawOpen = Mouth.JawOpen = 1
|
||||||
|
bs = LipsFunnel = Mouth.LipsFunnel = 1
|
||||||
|
bs = LipsLowerDown = Mouth.LipsLowerDown = 1
|
||||||
|
bs = LipsPucker = Mouth.LipsPucker = 1
|
||||||
|
bs = LipsStretch_L = Mouth.LipsStretch_L = 0.96
|
||||||
|
bs = LipsStretch_R = Mouth.LipsStretch_R = 1
|
||||||
|
bs = LipsUpperUp = Mouth.LipsUpperUp = 1
|
||||||
|
bs = MouthDimple_L = Mouth.MouthDimple_L = 1
|
||||||
|
bs = MouthDimple_R = Mouth.MouthDimple_R = 1
|
||||||
|
bs = MouthFrown_L = Mouth.MouthFrown_L = 1
|
||||||
|
bs = MouthFrown_R = Mouth.MouthFrown_R = 1
|
||||||
|
bs = MouthLeft = Mouth.MouthLeft = 1
|
||||||
|
bs = MouthRight = Mouth.MouthRight = 1
|
||||||
|
bs = MouthSmile_L = Mouth.MouthSmile_L = 1
|
||||||
|
bs = MouthSmile_R = Mouth.MouthSmile_R = 1
|
||||||
|
bs = Puff = Mouth.Puff = 1
|
||||||
|
bs = Sneer = Mouth.Sneer = 1
|
BIN
interface/resources/meshes/tail.jpg
Normal file
BIN
interface/resources/meshes/tail.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
BIN
interface/resources/meshes/visor.png
Normal file
BIN
interface/resources/meshes/visor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -4042,7 +4042,7 @@ void Application::loadScript(const QString& fileNameString) {
|
||||||
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
||||||
|
|
||||||
// hook our avatar object into this script engine
|
// hook our avatar object into this script engine
|
||||||
scriptEngine->setAvatarData( static_cast<Avatar*>(_myAvatar), "MyAvatar");
|
scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features
|
||||||
|
|
||||||
CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum);
|
CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum);
|
||||||
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
|
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
|
||||||
|
|
|
@ -172,6 +172,21 @@ glm::vec3 ControllerScriptingInterface::getSpatialControlVelocity(int controlInd
|
||||||
return glm::vec3(0); // bad index
|
return glm::vec3(0); // bad index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat ControllerScriptingInterface::getSpatialControlRawRotation(int controlIndex) const {
|
||||||
|
int palmIndex = controlIndex / NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
||||||
|
int controlOfPalm = controlIndex % NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
||||||
|
const PalmData* palmData = getActivePalm(palmIndex);
|
||||||
|
if (palmData) {
|
||||||
|
switch (controlOfPalm) {
|
||||||
|
case PALM_SPATIALCONTROL:
|
||||||
|
return palmData->getRawRotation();
|
||||||
|
case TIP_SPATIALCONTROL:
|
||||||
|
return palmData->getRawRotation(); // currently the tip doesn't have a unique rotation, use the palm rotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return glm::quat(); // bad index
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 ControllerScriptingInterface::getSpatialControlNormal(int controlIndex) const {
|
glm::vec3 ControllerScriptingInterface::getSpatialControlNormal(int controlIndex) const {
|
||||||
int palmIndex = controlIndex / NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
int palmIndex = controlIndex / NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
||||||
int controlOfPalm = controlIndex % NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
int controlOfPalm = controlIndex % NUMBER_OF_SPATIALCONTROLS_PER_PALM;
|
||||||
|
|
|
@ -58,7 +58,7 @@ public slots:
|
||||||
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const;
|
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const;
|
||||||
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const;
|
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const;
|
||||||
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const;
|
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const;
|
||||||
|
virtual glm::quat getSpatialControlRawRotation(int controlIndex) const;
|
||||||
virtual void captureKeyEvents(const KeyEvent& event);
|
virtual void captureKeyEvents(const KeyEvent& event);
|
||||||
virtual void releaseKeyEvents(const KeyEvent& event);
|
virtual void releaseKeyEvents(const KeyEvent& event);
|
||||||
|
|
||||||
|
|
|
@ -345,12 +345,14 @@ bool Avatar::findSphereCollisionWithSkeleton(const glm::vec3& sphereCenter, floa
|
||||||
|
|
||||||
void Avatar::setFaceModelURL(const QUrl &faceModelURL) {
|
void Avatar::setFaceModelURL(const QUrl &faceModelURL) {
|
||||||
AvatarData::setFaceModelURL(faceModelURL);
|
AvatarData::setFaceModelURL(faceModelURL);
|
||||||
_head.getFaceModel().setURL(_faceModelURL);
|
const QUrl DEFAULT_FACE_MODEL_URL = QUrl::fromLocalFile("resources/meshes/defaultAvatar_head.fbx");
|
||||||
|
_head.getFaceModel().setURL(_faceModelURL, DEFAULT_FACE_MODEL_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) {
|
void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) {
|
||||||
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
||||||
_skeletonModel.setURL(_skeletonModelURL);
|
const QUrl DEFAULT_SKELETON_MODEL_URL = QUrl::fromLocalFile("resources/meshes/defaultAvatar_body.fbx");
|
||||||
|
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Avatar::parseData(const QByteArray& packet) {
|
int Avatar::parseData(const QByteArray& packet) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
||||||
state.rotation = glm::angleAxis(-_owningHead->getRoll(), glm::normalize(inverse * axes[2])) *
|
state.rotation = glm::angleAxis(-_owningHead->getTweakedRoll(), glm::normalize(inverse * axes[2])) *
|
||||||
glm::angleAxis(_owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1])) *
|
glm::angleAxis(_owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1])) *
|
||||||
glm::angleAxis(-_owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0])) * joint.rotation;
|
glm::angleAxis(-_owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0])) * joint.rotation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,7 @@ Hand::Hand(Avatar* owningAvatar) :
|
||||||
_ballColor(0.0, 0.0, 0.4),
|
_ballColor(0.0, 0.0, 0.4),
|
||||||
_collisionCenter(0,0,0),
|
_collisionCenter(0,0,0),
|
||||||
_collisionAge(0),
|
_collisionAge(0),
|
||||||
_collisionDuration(0),
|
_collisionDuration(0)
|
||||||
_pitchUpdate(0),
|
|
||||||
_grabDelta(0, 0, 0),
|
|
||||||
_grabDeltaVelocity(0, 0, 0),
|
|
||||||
_grabStartRotation(0, 0, 0, 1),
|
|
||||||
_grabCurrentRotation(0, 0, 0, 1)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,28 +49,6 @@ void Hand::init() {
|
||||||
void Hand::reset() {
|
void Hand::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Hand::getAndResetGrabDelta() {
|
|
||||||
const float HAND_GRAB_SCALE_DISTANCE = 2.f;
|
|
||||||
glm::vec3 delta = _grabDelta * _owningAvatar->getScale() * HAND_GRAB_SCALE_DISTANCE;
|
|
||||||
_grabDelta = glm::vec3(0,0,0);
|
|
||||||
glm::quat avatarRotation = _owningAvatar->getOrientation();
|
|
||||||
return avatarRotation * -delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Hand::getAndResetGrabDeltaVelocity() {
|
|
||||||
const float HAND_GRAB_SCALE_VELOCITY = 5.f;
|
|
||||||
glm::vec3 delta = _grabDeltaVelocity * _owningAvatar->getScale() * HAND_GRAB_SCALE_VELOCITY;
|
|
||||||
_grabDeltaVelocity = glm::vec3(0,0,0);
|
|
||||||
glm::quat avatarRotation = _owningAvatar->getOrientation();
|
|
||||||
return avatarRotation * -delta;
|
|
||||||
|
|
||||||
}
|
|
||||||
glm::quat Hand::getAndResetGrabRotation() {
|
|
||||||
glm::quat diff = _grabCurrentRotation * glm::inverse(_grabStartRotation);
|
|
||||||
_grabStartRotation = _grabCurrentRotation;
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hand::simulate(float deltaTime, bool isMine) {
|
void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
if (_collisionAge > 0.f) {
|
if (_collisionAge > 0.f) {
|
||||||
|
@ -99,19 +72,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
_buckyBalls.grab(palm, fingerTipPosition, _owningAvatar->getOrientation(), deltaTime);
|
_buckyBalls.grab(palm, fingerTipPosition, _owningAvatar->getOrientation(), deltaTime);
|
||||||
|
|
||||||
if (palm.getControllerButtons() & BUTTON_4) {
|
|
||||||
_grabDelta += palm.getRawVelocity() * deltaTime;
|
|
||||||
_grabCurrentRotation = palm.getRawRotation();
|
|
||||||
}
|
|
||||||
if ((palm.getLastControllerButtons() & BUTTON_4) && !(palm.getControllerButtons() & BUTTON_4)) {
|
|
||||||
// Just ending grab, capture velocity
|
|
||||||
_grabDeltaVelocity = palm.getRawVelocity();
|
|
||||||
}
|
|
||||||
if (!(palm.getLastControllerButtons() & BUTTON_4) && (palm.getControllerButtons() & BUTTON_4)) {
|
|
||||||
// Just starting grab, capture starting rotation
|
|
||||||
_grabStartRotation = palm.getRawRotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (palm.getControllerButtons() & BUTTON_1) {
|
if (palm.getControllerButtons() & BUTTON_1) {
|
||||||
if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||||
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
|
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
|
||||||
|
|
|
@ -58,15 +58,6 @@ public:
|
||||||
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
|
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
|
||||||
const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;}
|
const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;}
|
||||||
|
|
||||||
// Pitch from controller input to view
|
|
||||||
const float getPitchUpdate() const { return _pitchUpdate; }
|
|
||||||
void setPitchUpdate(float pitchUpdate) { _pitchUpdate = pitchUpdate; }
|
|
||||||
|
|
||||||
// Get the drag distance to move
|
|
||||||
glm::vec3 getAndResetGrabDelta();
|
|
||||||
glm::vec3 getAndResetGrabDeltaVelocity();
|
|
||||||
glm::quat getAndResetGrabRotation();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disallow copies of the Hand, copy of owning Avatar is disallowed too
|
// disallow copies of the Hand, copy of owning Avatar is disallowed too
|
||||||
Hand(const Hand&);
|
Hand(const Hand&);
|
||||||
|
@ -100,13 +91,6 @@ private:
|
||||||
void calculateGeometry();
|
void calculateGeometry();
|
||||||
|
|
||||||
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
||||||
|
|
||||||
float _pitchUpdate;
|
|
||||||
|
|
||||||
glm::vec3 _grabDelta;
|
|
||||||
glm::vec3 _grabDeltaVelocity;
|
|
||||||
glm::quat _grabStartRotation;
|
|
||||||
glm::quat _grabCurrentRotation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -328,21 +328,6 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
updateChatCircle(deltaTime);
|
updateChatCircle(deltaTime);
|
||||||
|
|
||||||
// Get any position, velocity, or rotation update from Grab Drag controller
|
|
||||||
glm::vec3 moveFromGrab = _hand.getAndResetGrabDelta();
|
|
||||||
if (glm::length(moveFromGrab) > EPSILON) {
|
|
||||||
_position += moveFromGrab;
|
|
||||||
_velocity = glm::vec3(0, 0, 0);
|
|
||||||
}
|
|
||||||
_velocity += _hand.getAndResetGrabDeltaVelocity();
|
|
||||||
glm::quat deltaRotation = _hand.getAndResetGrabRotation();
|
|
||||||
const float GRAB_CONTROLLER_TURN_SCALING = 0.5f;
|
|
||||||
glm::vec3 euler = safeEulerAngles(deltaRotation) * GRAB_CONTROLLER_TURN_SCALING;
|
|
||||||
// Adjust body yaw by yaw from controller
|
|
||||||
setOrientation(glm::angleAxis(-euler.y, glm::vec3(0, 1, 0)) * getOrientation());
|
|
||||||
// Adjust head pitch from controller
|
|
||||||
getHead().setPitch(getHead().getPitch() - euler.x);
|
|
||||||
|
|
||||||
_position += _velocity * deltaTime;
|
_position += _velocity * deltaTime;
|
||||||
|
|
||||||
// update avatar skeleton and simulate hand and head
|
// update avatar skeleton and simulate hand and head
|
||||||
|
@ -807,39 +792,6 @@ void MyAvatar::updateThrust(float deltaTime) {
|
||||||
up;
|
up;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add thrust and rotation from hand controllers
|
|
||||||
const float THRUST_MAG_HAND_JETS = THRUST_MAG_FWD;
|
|
||||||
const float JOYSTICK_YAW_MAG = YAW_MAG;
|
|
||||||
const float JOYSTICK_PITCH_MAG = PITCH_MAG * 0.5f;
|
|
||||||
const int THRUST_CONTROLLER = 0;
|
|
||||||
const int VIEW_CONTROLLER = 1;
|
|
||||||
for (size_t i = 0; i < getHand().getPalms().size(); ++i) {
|
|
||||||
PalmData& palm = getHand().getPalms()[i];
|
|
||||||
|
|
||||||
// If the script hasn't captured this joystick, then let the default behavior work
|
|
||||||
if (!Application::getInstance()->getControllerScriptingInterface()->isJoystickCaptured(palm.getSixenseID())) {
|
|
||||||
if (palm.isActive() && (palm.getSixenseID() == THRUST_CONTROLLER)) {
|
|
||||||
if (palm.getJoystickY() != 0.f) {
|
|
||||||
FingerData& finger = palm.getFingers()[0];
|
|
||||||
if (finger.isActive()) {
|
|
||||||
}
|
|
||||||
_thrust += front * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickY() * _thrustMultiplier * deltaTime;
|
|
||||||
}
|
|
||||||
if (palm.getJoystickX() != 0.f) {
|
|
||||||
_thrust += right * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickX() * _thrustMultiplier * deltaTime;
|
|
||||||
}
|
|
||||||
} else if (palm.isActive() && (palm.getSixenseID() == VIEW_CONTROLLER)) {
|
|
||||||
if (palm.getJoystickX() != 0.f) {
|
|
||||||
_bodyYawDelta -= palm.getJoystickX() * JOYSTICK_YAW_MAG * deltaTime;
|
|
||||||
}
|
|
||||||
if (palm.getJoystickY() != 0.f) {
|
|
||||||
getHand().setPitchUpdate(getHand().getPitchUpdate() +
|
|
||||||
(palm.getJoystickY() * JOYSTICK_PITCH_MAG * deltaTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update speed brake status
|
// Update speed brake status
|
||||||
const float MIN_SPEED_BRAKE_VELOCITY = _scale * 0.4f;
|
const float MIN_SPEED_BRAKE_VELOCITY = _scale * 0.4f;
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; }
|
void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; }
|
||||||
void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }
|
|
||||||
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
||||||
void setLeanScale(float scale) { _leanScale = scale; }
|
void setLeanScale(float scale) { _leanScale = scale; }
|
||||||
void setGravity(glm::vec3 gravity);
|
void setGravity(glm::vec3 gravity);
|
||||||
|
@ -78,9 +77,6 @@ public:
|
||||||
|
|
||||||
static void sendKillAvatar();
|
static void sendKillAvatar();
|
||||||
|
|
||||||
// Set/Get update the thrust that will move the avatar around
|
|
||||||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
|
||||||
glm::vec3 getThrust() { return _thrust; };
|
|
||||||
|
|
||||||
void orbit(const glm::vec3& position, int deltaX, int deltaY);
|
void orbit(const glm::vec3& position, int deltaX, int deltaY);
|
||||||
|
|
||||||
|
@ -94,9 +90,13 @@ public slots:
|
||||||
void increaseSize();
|
void increaseSize();
|
||||||
void decreaseSize();
|
void decreaseSize();
|
||||||
void resetSize();
|
void resetSize();
|
||||||
|
|
||||||
void sendIdentityPacket();
|
void sendIdentityPacket();
|
||||||
|
|
||||||
|
// Set/Get update the thrust that will move the avatar around
|
||||||
|
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||||
|
glm::vec3 getThrust() { return _thrust; };
|
||||||
|
void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _mousePressed;
|
bool _mousePressed;
|
||||||
float _bodyPitchDelta;
|
float _bodyPitchDelta;
|
||||||
|
|
|
@ -834,6 +834,12 @@ QString getTopModelID(const QMultiHash<QString, QString>& parentMap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString getString(const QVariant& value) {
|
||||||
|
// if it's a list, return the first entry
|
||||||
|
QVariantList list = value.toList();
|
||||||
|
return list.isEmpty() ? value.toString() : list.at(0).toString();
|
||||||
|
}
|
||||||
|
|
||||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
||||||
QHash<QString, ExtractedMesh> meshes;
|
QHash<QString, ExtractedMesh> meshes;
|
||||||
QVector<ExtractedBlendshape> blendshapes;
|
QVector<ExtractedBlendshape> blendshapes;
|
||||||
|
@ -847,14 +853,14 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QHash<QString, QString> bumpTextures;
|
QHash<QString, QString> bumpTextures;
|
||||||
|
|
||||||
QVariantHash joints = mapping.value("joint").toHash();
|
QVariantHash joints = mapping.value("joint").toHash();
|
||||||
QString jointEyeLeftName = processID(joints.value("jointEyeLeft", "jointEyeLeft").toString());
|
QString jointEyeLeftName = processID(getString(joints.value("jointEyeLeft", "jointEyeLeft")));
|
||||||
QString jointEyeRightName = processID(joints.value("jointEyeRight", "jointEyeRight").toString());
|
QString jointEyeRightName = processID(getString(joints.value("jointEyeRight", "jointEyeRight")));
|
||||||
QString jointNeckName = processID(joints.value("jointNeck", "jointNeck").toString());
|
QString jointNeckName = processID(getString(joints.value("jointNeck", "jointNeck")));
|
||||||
QString jointRootName = processID(joints.value("jointRoot", "jointRoot").toString());
|
QString jointRootName = processID(getString(joints.value("jointRoot", "jointRoot")));
|
||||||
QString jointLeanName = processID(joints.value("jointLean", "jointLean").toString());
|
QString jointLeanName = processID(getString(joints.value("jointLean", "jointLean")));
|
||||||
QString jointHeadName = processID(joints.value("jointHead", "jointHead").toString());
|
QString jointHeadName = processID(getString(joints.value("jointHead", "jointHead")));
|
||||||
QString jointLeftHandName = processID(joints.value("jointLeftHand", "jointLeftHand").toString());
|
QString jointLeftHandName = processID(getString(joints.value("jointLeftHand", "jointLeftHand")));
|
||||||
QString jointRightHandName = processID(joints.value("jointRightHand", "jointRightHand").toString());
|
QString jointRightHandName = processID(getString(joints.value("jointRightHand", "jointRightHand")));
|
||||||
QVariantList jointLeftFingerNames = joints.values("jointLeftFinger");
|
QVariantList jointLeftFingerNames = joints.values("jointLeftFinger");
|
||||||
QVariantList jointRightFingerNames = joints.values("jointRightFinger");
|
QVariantList jointRightFingerNames = joints.values("jointRightFinger");
|
||||||
QVariantList jointLeftFingertipNames = joints.values("jointLeftFingertip");
|
QVariantList jointLeftFingertipNames = joints.values("jointLeftFingertip");
|
||||||
|
|
|
@ -290,19 +290,24 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions) {
|
||||||
buffer.release();
|
buffer.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url) {
|
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback) {
|
||||||
|
if (!url.isValid() && fallback.isValid()) {
|
||||||
|
return getGeometry(fallback);
|
||||||
|
}
|
||||||
QSharedPointer<NetworkGeometry> geometry = _networkGeometry.value(url);
|
QSharedPointer<NetworkGeometry> geometry = _networkGeometry.value(url);
|
||||||
if (geometry.isNull()) {
|
if (geometry.isNull()) {
|
||||||
geometry = QSharedPointer<NetworkGeometry>(new NetworkGeometry(url));
|
geometry = QSharedPointer<NetworkGeometry>(new NetworkGeometry(url, fallback.isValid() ?
|
||||||
|
getGeometry(fallback) : QSharedPointer<NetworkGeometry>()));
|
||||||
_networkGeometry.insert(url, geometry);
|
_networkGeometry.insert(url, geometry);
|
||||||
}
|
}
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkGeometry::NetworkGeometry(const QUrl& url) :
|
NetworkGeometry::NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGeometry>& fallback) :
|
||||||
_modelRequest(url),
|
_modelRequest(url),
|
||||||
_modelReply(NULL),
|
_modelReply(NULL),
|
||||||
_mappingReply(NULL),
|
_mappingReply(NULL),
|
||||||
|
_fallback(fallback),
|
||||||
_attempts(0)
|
_attempts(0)
|
||||||
{
|
{
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
|
@ -369,18 +374,37 @@ void NetworkGeometry::makeModelRequest() {
|
||||||
void NetworkGeometry::handleModelReplyError() {
|
void NetworkGeometry::handleModelReplyError() {
|
||||||
QDebug debug = qDebug() << _modelReply->errorString();
|
QDebug debug = qDebug() << _modelReply->errorString();
|
||||||
|
|
||||||
|
QNetworkReply::NetworkError error = _modelReply->error();
|
||||||
_modelReply->disconnect(this);
|
_modelReply->disconnect(this);
|
||||||
_modelReply->deleteLater();
|
_modelReply->deleteLater();
|
||||||
_modelReply = NULL;
|
_modelReply = NULL;
|
||||||
|
|
||||||
|
// retry for certain types of failures
|
||||||
|
switch (error) {
|
||||||
|
case QNetworkReply::RemoteHostClosedError:
|
||||||
|
case QNetworkReply::TimeoutError:
|
||||||
|
case QNetworkReply::TemporaryNetworkFailureError:
|
||||||
|
case QNetworkReply::ProxyConnectionClosedError:
|
||||||
|
case QNetworkReply::ProxyTimeoutError:
|
||||||
|
case QNetworkReply::UnknownNetworkError:
|
||||||
|
case QNetworkReply::UnknownProxyError:
|
||||||
|
case QNetworkReply::UnknownContentError:
|
||||||
|
case QNetworkReply::ProtocolFailure: {
|
||||||
// retry with increasing delays
|
// retry with increasing delays
|
||||||
const int MAX_ATTEMPTS = 8;
|
const int MAX_ATTEMPTS = 8;
|
||||||
const int BASE_DELAY_MS = 1000;
|
const int BASE_DELAY_MS = 1000;
|
||||||
if (++_attempts < MAX_ATTEMPTS) {
|
if (++_attempts < MAX_ATTEMPTS) {
|
||||||
QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeModelRequest()));
|
QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeModelRequest()));
|
||||||
debug << " -- retrying...";
|
debug << " -- retrying...";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
// fall through to final failure
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
maybeLoadFallback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::handleMappingReplyError() {
|
void NetworkGeometry::handleMappingReplyError() {
|
||||||
|
@ -415,6 +439,7 @@ void NetworkGeometry::maybeReadModelWithMapping() {
|
||||||
|
|
||||||
} catch (const QString& error) {
|
} catch (const QString& error) {
|
||||||
qDebug() << "Error reading " << url << ": " << error;
|
qDebug() << "Error reading " << url << ": " << error;
|
||||||
|
maybeLoadFallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +532,24 @@ void NetworkGeometry::maybeReadModelWithMapping() {
|
||||||
|
|
||||||
_meshes.append(networkMesh);
|
_meshes.append(networkMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit loaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkGeometry::loadFallback() {
|
||||||
|
_geometry = _fallback->_geometry;
|
||||||
|
_meshes = _fallback->_meshes;
|
||||||
|
emit loaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkGeometry::maybeLoadFallback() {
|
||||||
|
if (_fallback) {
|
||||||
|
if (_fallback->isLoaded()) {
|
||||||
|
loadFallback();
|
||||||
|
} else {
|
||||||
|
connect(_fallback.data(), SIGNAL(loaded()), SLOT(loadFallback()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetworkMeshPart::isTranslucent() const {
|
bool NetworkMeshPart::isTranslucent() const {
|
||||||
|
|
|
@ -37,7 +37,8 @@ public:
|
||||||
void renderGrid(int xDivisions, int yDivisions);
|
void renderGrid(int xDivisions, int yDivisions);
|
||||||
|
|
||||||
/// Loads geometry from the specified URL.
|
/// Loads geometry from the specified URL.
|
||||||
QSharedPointer<NetworkGeometry> getGeometry(const QUrl& url);
|
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||||
|
QSharedPointer<NetworkGeometry> getGeometry(const QUrl& url, const QUrl& fallback = QUrl());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ class NetworkGeometry : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NetworkGeometry(const QUrl& url);
|
NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGeometry>& fallback);
|
||||||
~NetworkGeometry();
|
~NetworkGeometry();
|
||||||
|
|
||||||
bool isLoaded() const { return !_geometry.joints.isEmpty(); }
|
bool isLoaded() const { return !_geometry.joints.isEmpty(); }
|
||||||
|
@ -69,18 +70,26 @@ public:
|
||||||
/// Returns the average color of all meshes in the geometry.
|
/// Returns the average color of all meshes in the geometry.
|
||||||
glm::vec4 computeAverageColor() const;
|
glm::vec4 computeAverageColor() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void loaded();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void makeModelRequest();
|
void makeModelRequest();
|
||||||
void handleModelReplyError();
|
void handleModelReplyError();
|
||||||
void handleMappingReplyError();
|
void handleMappingReplyError();
|
||||||
void maybeReadModelWithMapping();
|
void maybeReadModelWithMapping();
|
||||||
|
void loadFallback();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void maybeLoadFallback();
|
||||||
|
|
||||||
QNetworkRequest _modelRequest;
|
QNetworkRequest _modelRequest;
|
||||||
QNetworkReply* _modelReply;
|
QNetworkReply* _modelReply;
|
||||||
QNetworkReply* _mappingReply;
|
QNetworkReply* _mappingReply;
|
||||||
|
QSharedPointer<NetworkGeometry> _fallback;
|
||||||
|
|
||||||
int _attempts;
|
int _attempts;
|
||||||
FBXGeometry _geometry;
|
FBXGeometry _geometry;
|
||||||
|
|
|
@ -390,7 +390,7 @@ float Model::getRightArmLength() const {
|
||||||
return getLimbLength(getRightHandJointIndex());
|
return getLimbLength(getRightHandJointIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setURL(const QUrl& url) {
|
void Model::setURL(const QUrl& url, const QUrl& fallback) {
|
||||||
// don't recreate the geometry if it's the same URL
|
// don't recreate the geometry if it's the same URL
|
||||||
if (_url == url) {
|
if (_url == url) {
|
||||||
return;
|
return;
|
||||||
|
@ -401,7 +401,7 @@ void Model::setURL(const QUrl& url) {
|
||||||
deleteGeometry();
|
deleteGeometry();
|
||||||
_dilatedTextures.clear();
|
_dilatedTextures.clear();
|
||||||
|
|
||||||
_geometry = Application::getInstance()->getGeometryCache()->getGeometry(url);
|
_geometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec4 Model::computeAverageColor() const {
|
glm::vec4 Model::computeAverageColor() const {
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
bool render(float alpha);
|
bool render(float alpha);
|
||||||
|
|
||||||
Q_INVOKABLE void setURL(const QUrl& url);
|
Q_INVOKABLE void setURL(const QUrl& url, const QUrl& fallback = QUrl());
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
|
|
||||||
/// Returns the extents of the model in its bind pose.
|
/// Returns the extents of the model in its bind pose.
|
||||||
|
|
|
@ -67,6 +67,7 @@ class AvatarData : public NodeData {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
||||||
|
Q_PROPERTY(float scale READ getTargetScale WRITE setTargetScale)
|
||||||
Q_PROPERTY(glm::vec3 handPosition READ getHandPosition WRITE setHandPosition)
|
Q_PROPERTY(glm::vec3 handPosition READ getHandPosition WRITE setHandPosition)
|
||||||
Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw)
|
Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw)
|
||||||
Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch)
|
Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
#include "EventTypes.h"
|
#include "EventTypes.h"
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ public slots:
|
||||||
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const = 0;
|
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const = 0;
|
||||||
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const = 0;
|
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const = 0;
|
||||||
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const = 0;
|
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const = 0;
|
||||||
|
virtual glm::quat getSpatialControlRawRotation(int controlIndex) const = 0;
|
||||||
|
|
||||||
virtual void captureKeyEvents(const KeyEvent& event) = 0;
|
virtual void captureKeyEvents(const KeyEvent& event) = 0;
|
||||||
virtual void releaseKeyEvents(const KeyEvent& event) = 0;
|
virtual void releaseKeyEvents(const KeyEvent& event) = 0;
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <glm/gtx/vector_angle.hpp>
|
||||||
|
|
||||||
#include <OctreeConstants.h>
|
#include <OctreeConstants.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
#include "Quat.h"
|
#include "Quat.h"
|
||||||
|
|
||||||
glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
|
glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
|
||||||
|
@ -24,6 +27,11 @@ glm::quat Quat::fromPitchYawRoll(float pitch, float yaw, float roll) {
|
||||||
return glm::quat(glm::radians(glm::vec3(pitch, yaw, roll)));
|
return glm::quat(glm::radians(glm::vec3(pitch, yaw, roll)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat Quat::inverse(const glm::quat& q) {
|
||||||
|
return glm::inverse(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 Quat::getFront(const glm::quat& orientation) {
|
glm::vec3 Quat::getFront(const glm::quat& orientation) {
|
||||||
return orientation * IDENTITY_FRONT;
|
return orientation * IDENTITY_FRONT;
|
||||||
}
|
}
|
||||||
|
@ -35,3 +43,12 @@ glm::vec3 Quat::getRight(const glm::quat& orientation) {
|
||||||
glm::vec3 Quat::getUp(const glm::quat& orientation) {
|
glm::vec3 Quat::getUp(const glm::quat& orientation) {
|
||||||
return orientation * IDENTITY_UP;
|
return orientation * IDENTITY_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Quat::safeEulerAngles(const glm::quat& orientation) {
|
||||||
|
return ::safeEulerAngles(orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat Quat::angleAxis(float angle, const glm::vec3& v) {
|
||||||
|
return glm::angleAxis(angle, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,12 @@ public slots:
|
||||||
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
|
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
|
||||||
glm::quat fromVec3(const glm::vec3& vec3);
|
glm::quat fromVec3(const glm::vec3& vec3);
|
||||||
glm::quat fromPitchYawRoll(float pitch, float yaw, float roll);
|
glm::quat fromPitchYawRoll(float pitch, float yaw, float roll);
|
||||||
|
glm::quat inverse(const glm::quat& q);
|
||||||
glm::vec3 getFront(const glm::quat& orientation);
|
glm::vec3 getFront(const glm::quat& orientation);
|
||||||
glm::vec3 getRight(const glm::quat& orientation);
|
glm::vec3 getRight(const glm::quat& orientation);
|
||||||
glm::vec3 getUp(const glm::quat& orientation);
|
glm::vec3 getUp(const glm::quat& orientation);
|
||||||
|
glm::vec3 safeEulerAngles(const glm::quat& orientation);
|
||||||
|
glm::quat angleAxis(float angle, const glm::vec3& v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* defined(__hifi__Quat__) */
|
#endif /* defined(__hifi__Quat__) */
|
||||||
|
|
|
@ -19,10 +19,16 @@ glm::vec3 Vec3::multiply(const glm::vec3& v1, float f) {
|
||||||
return v1 * f;
|
return v1 * f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Vec3::multiplyQbyV(const glm::quat& q, const glm::vec3& v) {
|
||||||
|
return q * v;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
|
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
|
||||||
return v1 + v2;
|
return v1 + v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) {
|
glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) {
|
||||||
return v1 - v2;
|
return v1 - v2;
|
||||||
}
|
}
|
||||||
|
float Vec3::length(const glm::vec3& v) {
|
||||||
|
return glm::length(v);
|
||||||
|
}
|
||||||
|
|
|
@ -23,8 +23,10 @@ class Vec3 : public QObject {
|
||||||
public slots:
|
public slots:
|
||||||
glm::vec3 multiply(const glm::vec3& v1, const glm::vec3& v2);
|
glm::vec3 multiply(const glm::vec3& v1, const glm::vec3& v2);
|
||||||
glm::vec3 multiply(const glm::vec3& v1, float f);
|
glm::vec3 multiply(const glm::vec3& v1, float f);
|
||||||
|
glm::vec3 multiplyQbyV(const glm::quat& q, const glm::vec3& v);
|
||||||
glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2);
|
glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2);
|
||||||
glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2);
|
glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2);
|
||||||
|
float length(const glm::vec3& v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue