// // MyAvatar.cpp // interface/src/avatar // // Created by Mark Peng on 8/16/13. // Copyright 2012 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Application.h" #include "Audio.h" #include "Environment.h" #include "Menu.h" #include "ModelReferential.h" #include "MyAvatar.h" #include "Physics.h" #include "Recorder.h" #include "devices/Faceshift.h" #include "devices/OculusManager.h" using namespace std; const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f); const float YAW_SPEED = 500.0f; // degrees/sec const float PITCH_SPEED = 100.0f; // degrees/sec const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions const float COLLISION_RADIUS_SCALE = 0.125f; const float MAX_WALKING_SPEED = 2.5f; // human walking speed const float MAX_BOOST_SPEED = 0.5f * MAX_WALKING_SPEED; // keyboard motor gets additive boost below this speed const float MIN_AVATAR_SPEED = 0.05f; // speed is set to zero below this // TODO: normalize avatar speed for standard avatar size, then scale all motion logic // to properly follow avatar size. float MAX_AVATAR_SPEED = 300.0f; float MAX_KEYBOARD_MOTOR_SPEED = MAX_AVATAR_SPEED; float DEFAULT_KEYBOARD_MOTOR_TIMESCALE = 0.25f; float MIN_SCRIPTED_MOTOR_TIMESCALE = 0.005f; float DEFAULT_SCRIPTED_MOTOR_TIMESCALE = 1.0e6f; const int SCRIPTED_MOTOR_CAMERA_FRAME = 0; const int SCRIPTED_MOTOR_AVATAR_FRAME = 1; const int SCRIPTED_MOTOR_WORLD_FRAME = 2; MyAvatar::MyAvatar() : Avatar(), _turningKeyPressTime(0.0f), _gravity(0.0f, 0.0f, 0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), _shouldJump(false), _wasPushing(false), _isPushing(false), _isBraking(false), _trapDuration(0.0f), _thrust(0.0f), _keyboardMotorVelocity(0.0f), _keyboardMotorTimescale(DEFAULT_KEYBOARD_MOTOR_TIMESCALE), _scriptedMotorVelocity(0.0f), _scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE), _scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME), _motionBehaviors(AVATAR_MOTION_DEFAULTS), _lookAtTargetAvatar(), _shouldRender(true), _billboardValid(false), _physicsSimulation(), _voxelShapeManager(), _feetTouchFloor(true), _isLookingAtLeftEye(true) { ShapeCollider::initDispatchTable(); for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; } _physicsSimulation.setEntity(&_skeletonModel); _physicsSimulation.addEntity(&_voxelShapeManager); _skeletonModel.setEnableShapes(true); _skeletonModel.buildRagdoll(); // connect to AddressManager signal for location jumps connect(DependencyManager::get(), &AddressManager::locationChangeRequired, this, &MyAvatar::goToLocation); } MyAvatar::~MyAvatar() { _physicsSimulation.clear(); _lookAtTargetAvatar.clear(); } QByteArray MyAvatar::toByteArray() { CameraMode mode = Application::getInstance()->getCamera()->getMode(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // fake the avatar position that is sent up to the AvatarMixer glm::vec3 oldPosition = _position; _position = getSkeletonPosition(); QByteArray array = AvatarData::toByteArray(); // copy the correct position back _position = oldPosition; return array; } return AvatarData::toByteArray(); } void MyAvatar::reset() { _skeletonModel.reset(); getHead()->reset(); _velocity = glm::vec3(0.0f); setThrust(glm::vec3(0.0f)); // Reset the pitch and roll components of the avatar's orientation, preserve yaw direction glm::vec3 eulers = safeEulerAngles(getOrientation()); eulers.x = 0.0f; eulers.z = 0.0f; setOrientation(glm::quat(eulers)); } void MyAvatar::update(float deltaTime) { if (_referential) { _referential->update(); } Head* head = getHead(); head->relaxLean(deltaTime); updateFromTrackers(deltaTime); // Get audio loudness data from audio input device Audio* audio = DependencyManager::get