mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 19494
This commit is contained in:
commit
d5b87fbe8a
22 changed files with 231 additions and 292 deletions
|
@ -2180,15 +2180,6 @@ void Application::updateThreads(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::updateParticles(float deltaTime) {
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateParticles()");
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) {
|
||||
_cloud.simulate(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateMetavoxels(float deltaTime) {
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateMetavoxels()");
|
||||
|
@ -2310,7 +2301,6 @@ void Application::update(float deltaTime) {
|
|||
updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
||||
updateParticles(deltaTime); // Simulate particle cloud movements
|
||||
updateMetavoxels(deltaTime); // update metavoxels
|
||||
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
|
||||
updateDialogs(deltaTime); // update various stats dialogs if present
|
||||
|
@ -2745,10 +2735,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
// disable specular lighting for ground and voxels
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR);
|
||||
|
||||
// Draw Cloud Particles
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) {
|
||||
_cloud.render();
|
||||
}
|
||||
// Draw voxels
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
|
@ -4032,6 +4018,32 @@ void Application::saveScripts() {
|
|||
settings->endArray();
|
||||
}
|
||||
|
||||
void Application::stopAllScripts() {
|
||||
// stops all current running scripts
|
||||
QList<QAction*> scriptActions = Menu::getInstance()->getActiveScriptsMenu()->actions();
|
||||
foreach (QAction* scriptAction, scriptActions) {
|
||||
scriptAction->activate(QAction::Trigger);
|
||||
qDebug() << "stopping script..." << scriptAction->text();
|
||||
}
|
||||
_activeScripts.clear();
|
||||
}
|
||||
|
||||
void Application::reloadAllScripts() {
|
||||
// remember all the current scripts so we can reload them
|
||||
QStringList reloadList = _activeScripts;
|
||||
// reloads all current running scripts
|
||||
QList<QAction*> scriptActions = Menu::getInstance()->getActiveScriptsMenu()->actions();
|
||||
foreach (QAction* scriptAction, scriptActions) {
|
||||
scriptAction->activate(QAction::Trigger);
|
||||
qDebug() << "stopping script..." << scriptAction->text();
|
||||
}
|
||||
_activeScripts.clear();
|
||||
foreach (QString scriptName, reloadList){
|
||||
qDebug() << "reloading script..." << scriptName;
|
||||
loadScript(scriptName);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::removeScriptName(const QString& fileNameString) {
|
||||
_activeScripts.removeOne(fileNameString);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "BandwidthMeter.h"
|
||||
#include "Camera.h"
|
||||
#include "Cloud.h"
|
||||
#include "DatagramProcessor.h"
|
||||
#include "Environment.h"
|
||||
#include "GLCanvas.h"
|
||||
|
@ -234,6 +233,8 @@ public slots:
|
|||
void loadDialog();
|
||||
void toggleLogDialog();
|
||||
void initAvatarAndViewFrustum();
|
||||
void stopAllScripts();
|
||||
void reloadAllScripts();
|
||||
|
||||
private slots:
|
||||
void timer();
|
||||
|
@ -286,7 +287,6 @@ private:
|
|||
void updateSixense(float deltaTime);
|
||||
void updateSerialDevices(float deltaTime);
|
||||
void updateThreads(float deltaTime);
|
||||
void updateParticles(float deltaTime);
|
||||
void updateMetavoxels(float deltaTime);
|
||||
void updateCamera(float deltaTime);
|
||||
void updateDialogs(float deltaTime);
|
||||
|
@ -353,8 +353,6 @@ private:
|
|||
|
||||
Stars _stars;
|
||||
|
||||
Cloud _cloud;
|
||||
|
||||
VoxelSystem _voxels;
|
||||
VoxelTree _clipboard; // if I copy/paste
|
||||
VoxelImporter* _voxelImporter;
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
//
|
||||
// Cloud.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Philip Rosedale on 11/17/12.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <InterfaceConfig.h>
|
||||
#include "Cloud.h"
|
||||
#include "Util.h"
|
||||
#include "Field.h"
|
||||
|
||||
const int NUM_PARTICLES = 100000;
|
||||
const float FIELD_COUPLE = 0.001f;
|
||||
const bool RENDER_FIELD = false;
|
||||
|
||||
Cloud::Cloud() {
|
||||
glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE);
|
||||
_bounds = box;
|
||||
_count = NUM_PARTICLES;
|
||||
_particles = new Particle[_count];
|
||||
_field = new Field(PARTICLE_WORLD_SIZE, FIELD_COUPLE);
|
||||
|
||||
for (unsigned int i = 0; i < _count; i++) {
|
||||
_particles[i].position = randVector() * box;
|
||||
const float INIT_VEL_SCALE = 0.03f;
|
||||
_particles[i].velocity = randVector() * ((float)PARTICLE_WORLD_SIZE * INIT_VEL_SCALE);
|
||||
_particles[i].color = randVector();
|
||||
}
|
||||
}
|
||||
|
||||
void Cloud::render() {
|
||||
if (RENDER_FIELD) {
|
||||
_field->render();
|
||||
}
|
||||
|
||||
glPointSize(3.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 3 * sizeof(glm::vec3), &_particles[0].position);
|
||||
glColorPointer(3, GL_FLOAT, 3 * sizeof(glm::vec3), &_particles[0].color);
|
||||
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
}
|
||||
|
||||
void Cloud::simulate (float deltaTime) {
|
||||
unsigned int i;
|
||||
_field->simulate(deltaTime);
|
||||
for (i = 0; i < _count; ++i) {
|
||||
|
||||
// Update position
|
||||
_particles[i].position += _particles[i].velocity * deltaTime;
|
||||
|
||||
// Decay Velocity (Drag)
|
||||
const float CONSTANT_DAMPING = 0.15f;
|
||||
_particles[i].velocity *= (1.f - CONSTANT_DAMPING * deltaTime);
|
||||
|
||||
// Interact with Field
|
||||
_field->interact(deltaTime, _particles[i].position, _particles[i].velocity);
|
||||
|
||||
// Update color to velocity
|
||||
_particles[i].color = (glm::normalize(_particles[i].velocity) * 0.5f) + 0.5f;
|
||||
|
||||
// Bounce at bounds
|
||||
if ((_particles[i].position.x > _bounds.x) || (_particles[i].position.x < 0.f)) {
|
||||
_particles[i].position.x = glm::clamp(_particles[i].position.x, 0.f, _bounds.x);
|
||||
_particles[i].velocity.x *= -1.f;
|
||||
}
|
||||
if ((_particles[i].position.y > _bounds.y) || (_particles[i].position.y < 0.f)) {
|
||||
_particles[i].position.y = glm::clamp(_particles[i].position.y, 0.f, _bounds.y);
|
||||
_particles[i].velocity.y *= -1.f;
|
||||
}
|
||||
if ((_particles[i].position.z > _bounds.z) || (_particles[i].position.z < 0.f)) {
|
||||
_particles[i].position.z = glm::clamp(_particles[i].position.z, 0.f, _bounds.z);
|
||||
_particles[i].velocity.z *= -1.f;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// Cloud.h
|
||||
// interface
|
||||
//
|
||||
// Created by Philip Rosedale on 11/17/12.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__Cloud__
|
||||
#define __interface__Cloud__
|
||||
|
||||
#include "Field.h"
|
||||
|
||||
#define PARTICLE_WORLD_SIZE 256.0
|
||||
|
||||
class Cloud {
|
||||
public:
|
||||
Cloud();
|
||||
void simulate(float deltaTime);
|
||||
void render();
|
||||
|
||||
private:
|
||||
struct Particle {
|
||||
glm::vec3 position, velocity, color;
|
||||
}* _particles;
|
||||
|
||||
unsigned int _count;
|
||||
glm::vec3 _bounds;
|
||||
Field* _field;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -93,6 +93,8 @@ Menu::Menu() :
|
|||
|
||||
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadDialog()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, appInstance, SLOT(stopAllScripts()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, 0, appInstance, SLOT(reloadAllScripts()));
|
||||
_activeScriptsMenu = fileMenu->addMenu("Running Scripts");
|
||||
|
||||
addDisabledActionAndSeparator(fileMenu, "Voxels");
|
||||
|
@ -161,7 +163,7 @@ Menu::Menu() :
|
|||
#endif
|
||||
|
||||
addDisabledActionAndSeparator(editMenu, "Physics");
|
||||
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true);
|
||||
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, false);
|
||||
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ClickToFly);
|
||||
|
@ -238,9 +240,9 @@ Menu::Menu() :
|
|||
SLOT(setFullscreen(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true,
|
||||
appInstance,SLOT(cameraMenuChanged()));
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H,false,
|
||||
appInstance,SLOT(cameraMenuChanged()));
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,
|
||||
appInstance, SLOT(cameraMenuChanged()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,
|
||||
false,
|
||||
|
@ -266,14 +268,8 @@ Menu::Menu() :
|
|||
appInstance->getAvatar(),
|
||||
SLOT(resetSize()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::OffAxisProjection,
|
||||
0,
|
||||
true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::TurnWithHead,
|
||||
0,
|
||||
true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);
|
||||
|
||||
|
@ -298,7 +294,6 @@ Menu::Menu() :
|
|||
appInstance->getGlowEffect(),
|
||||
SLOT(cycleRenderMode()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, false);
|
||||
|
||||
|
@ -339,14 +334,14 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu,
|
||||
MenuOption::FaceshiftTCP,
|
||||
0,
|
||||
false,
|
||||
appInstance->getFaceshift(),
|
||||
SLOT(setTCPEnabled(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);
|
||||
|
||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");
|
||||
|
||||
|
@ -356,7 +351,7 @@ Menu::Menu() :
|
|||
true,
|
||||
appInstance->getSixenseManager(),
|
||||
SLOT(setFilter(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace MenuOption {
|
|||
const QString DisableDeltaSending = "Disable Delta Sending";
|
||||
const QString DisableLowRes = "Disable Lower Resolution While Moving";
|
||||
const QString DisplayFrustum = "Display Frustum";
|
||||
const QString DisplayLeapHands = "Display Leap Hands";
|
||||
const QString DisplayHands = "Display Hands";
|
||||
const QString DisplayHandTargets = "Display Hand Targets";
|
||||
const QString FilterSixense = "Smooth Sixense Movement";
|
||||
const QString DontRenderVoxels = "Don't call _voxels.render()";
|
||||
|
@ -226,7 +226,6 @@ namespace MenuOption {
|
|||
const QString KillLocalVoxels = "Kill Local Voxels";
|
||||
const QString GoHome = "Go Home";
|
||||
const QString Gravity = "Use Gravity";
|
||||
const QString ParticleCloud = "Particle Cloud";
|
||||
const QString LodTools = "LOD Tools";
|
||||
const QString Log = "Log";
|
||||
const QString Login = "Login";
|
||||
|
@ -247,8 +246,10 @@ namespace MenuOption {
|
|||
const QString PasteVoxels = "Paste";
|
||||
const QString PasteToVoxel = "Paste to Voxel...";
|
||||
const QString PipelineWarnings = "Show Render Pipeline Warnings";
|
||||
const QString PlaySlaps = "Play Slaps";
|
||||
const QString Preferences = "Preferences...";
|
||||
const QString RandomizeVoxelColors = "Randomize Voxel TRUE Colors";
|
||||
const QString ReloadAllScripts = "Reload All Scripts";
|
||||
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||
const QString ResetSwatchColors = "Reset Swatch Colors";
|
||||
const QString RunTimingTests = "Run Timing Tests";
|
||||
|
@ -257,11 +258,10 @@ namespace MenuOption {
|
|||
const QString SettingsExport = "Export Settings";
|
||||
const QString ShowAllLocalVoxels = "Show All Local Voxels";
|
||||
const QString ShowTrueColors = "Show TRUE Colors";
|
||||
const QString VoxelDrumming = "Voxel Drumming";
|
||||
const QString PlaySlaps = "Play Slaps";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString Stars = "Stars";
|
||||
const QString Stats = "Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
const QString TestPing = "Test Ping";
|
||||
const QString TreeStats = "Calculate Tree Stats";
|
||||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
|
@ -272,6 +272,7 @@ namespace MenuOption {
|
|||
const QString VoxelAddMode = "Add Voxel Mode";
|
||||
const QString VoxelColorMode = "Color Voxel Mode";
|
||||
const QString VoxelDeleteMode = "Delete Voxel Mode";
|
||||
const QString VoxelDrumming = "Voxel Drumming";
|
||||
const QString VoxelGetColorMode = "Get Color Mode";
|
||||
const QString VoxelMode = "Cycle Voxel Mode";
|
||||
const QString VoxelPaintColor = "Voxel Paint Color";
|
||||
|
|
|
@ -162,6 +162,7 @@ void Avatar::render(bool forceRenderHead) {
|
|||
// render body
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {
|
||||
_skeletonModel.renderCollisionProxies(1.f);
|
||||
//_head.getFaceModel().renderCollisionProxies(0.5f);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
|
@ -276,11 +277,14 @@ bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penet
|
|||
bool didPenetrate = false;
|
||||
glm::vec3 skeletonPenetration;
|
||||
ModelCollisionInfo collisionInfo;
|
||||
/* Temporarily disabling collisions against the skeleton because the collision proxies up
|
||||
* near the neck are bad and prevent the hand from hitting the face.
|
||||
if (_skeletonModel.findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo, 1.0f, skeletonSkipIndex)) {
|
||||
collisionInfo._model = &_skeletonModel;
|
||||
collisions.push_back(collisionInfo);
|
||||
didPenetrate = true;
|
||||
}
|
||||
*/
|
||||
if (_head.getFaceModel().findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo)) {
|
||||
collisionInfo._model = &(_head.getFaceModel());
|
||||
collisions.push_back(collisionInfo);
|
||||
|
@ -445,20 +449,34 @@ float Avatar::getHeight() const {
|
|||
return extents.maximum.y - extents.minimum.y;
|
||||
}
|
||||
|
||||
bool Avatar::isPokeable(ModelCollisionInfo& collision) const {
|
||||
bool Avatar::collisionWouldMoveAvatar(ModelCollisionInfo& collision) const {
|
||||
// ATM only the Skeleton is pokeable
|
||||
// TODO: make poke affect head
|
||||
if (!collision._model) {
|
||||
return false;
|
||||
}
|
||||
if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
|
||||
return _skeletonModel.isPokeable(collision);
|
||||
// collision response of skeleton is temporarily disabled
|
||||
return false;
|
||||
//return _skeletonModel.collisionHitsMoveableJoint(collision);
|
||||
}
|
||||
if (collision._model == &(_head.getFaceModel())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Avatar::poke(ModelCollisionInfo& collision) {
|
||||
if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
|
||||
return _skeletonModel.poke(collision);
|
||||
void Avatar::applyCollision(ModelCollisionInfo& collision) {
|
||||
if (!collision._model) {
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
if (collision._model == &(_head.getFaceModel())) {
|
||||
_head.applyCollision(collision);
|
||||
}
|
||||
// TODO: make skeleton respond to collisions
|
||||
//if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
|
||||
// _skeletonModel.applyCollision(collision);
|
||||
//}
|
||||
}
|
||||
|
||||
float Avatar::getPelvisFloatingHeight() const {
|
||||
|
|
|
@ -129,11 +129,10 @@ public:
|
|||
float getHeight() const;
|
||||
|
||||
/// \return true if we expect the avatar would move as a result of the collision
|
||||
bool isPokeable(ModelCollisionInfo& collision) const;
|
||||
bool collisionWouldMoveAvatar(ModelCollisionInfo& collision) const;
|
||||
|
||||
/// \param collision a data structure for storing info about collisions against Models
|
||||
/// \return true if the collision affects the Avatar models
|
||||
bool poke(ModelCollisionInfo& collision);
|
||||
void applyCollision(ModelCollisionInfo& collision);
|
||||
|
||||
public slots:
|
||||
void updateCollisionFlags();
|
||||
|
|
|
@ -57,7 +57,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
|
||||
if (isMine) {
|
||||
_buckyBalls.simulate(deltaTime);
|
||||
updateCollisions();
|
||||
}
|
||||
|
||||
calculateGeometry();
|
||||
|
@ -126,92 +125,105 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
}
|
||||
}
|
||||
|
||||
void Hand::updateCollisions() {
|
||||
// use position to obtain the left and right palm indices
|
||||
int leftPalmIndex, rightPalmIndex;
|
||||
getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
||||
|
||||
ModelCollisionList collisions;
|
||||
// check for collisions
|
||||
void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) {
|
||||
if (!avatar || avatar == _owningAvatar) {
|
||||
// don't collide with our own hands (that is done elsewhere)
|
||||
return;
|
||||
}
|
||||
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
if (!palm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
||||
glm::vec3 totalPenetration;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
|
||||
// check other avatars
|
||||
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
if (avatar == _owningAvatar) {
|
||||
// don't collid with our own hands
|
||||
ModelCollisionList collisions;
|
||||
if (isMyHand && Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||
// Check for palm collisions
|
||||
glm::vec3 myPalmPosition = palm.getPosition();
|
||||
float palmCollisionDistance = 0.1f;
|
||||
bool wasColliding = palm.getIsCollidingWithPalm();
|
||||
palm.setIsCollidingWithPalm(false);
|
||||
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
||||
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
||||
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
||||
if (!otherPalm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||
// Check for palm collisions
|
||||
glm::vec3 myPalmPosition = palm.getPosition();
|
||||
float palmCollisionDistance = 0.1f;
|
||||
bool wasColliding = palm.getIsCollidingWithPalm();
|
||||
palm.setIsCollidingWithPalm(false);
|
||||
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
||||
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
||||
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
||||
if (!otherPalm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||
palm.setIsCollidingWithPalm(true);
|
||||
if (!wasColliding) {
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||
// add slapback here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
||||
for (int j = 0; j < collisions.size(); ++j) {
|
||||
// we don't resolve penetrations that would poke the other avatar
|
||||
if (!avatar->isPokeable(collisions[j])) {
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||
palm.setIsCollidingWithPalm(true);
|
||||
if (!wasColliding) {
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||
// add slapback here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) {
|
||||
// and the current avatar (ignoring everything below the parent of the parent of the last free joint)
|
||||
collisions.clear();
|
||||
const Model& skeletonModel = _owningAvatar->getSkeletonModel();
|
||||
int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex(
|
||||
skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() :
|
||||
(i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1)));
|
||||
if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) {
|
||||
for (int j = 0; j < collisions.size(); ++j) {
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
||||
for (int j = 0; j < collisions.size(); ++j) {
|
||||
if (isMyHand) {
|
||||
if (!avatar->collisionWouldMoveAvatar(collisions[j])) {
|
||||
// we resolve the hand from collision when it belongs to MyAvatar AND the other Avatar is
|
||||
// not expected to respond to the collision (hand hit unmovable part of their Avatar)
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
}
|
||||
} else {
|
||||
// when !isMyHand then avatar is MyAvatar and we apply the collision
|
||||
// which might not do anything (hand hit unmovable part of MyAvatar) however
|
||||
// we don't resolve the hand's penetration because we expect the remote
|
||||
// simulation to do the right thing.
|
||||
avatar->applyCollision(collisions[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// un-penetrate
|
||||
palm.addToPosition(-totalPenetration);
|
||||
if (isMyHand) {
|
||||
// resolve penetration
|
||||
palm.addToPosition(-totalPenetration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we recycle the collisions container, so we clear it for the next loop
|
||||
void Hand::collideAgainstOurself() {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModelCollisionList collisions;
|
||||
int leftPalmIndex, rightPalmIndex;
|
||||
getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
||||
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
||||
|
||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
if (!palm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
glm::vec3 totalPenetration;
|
||||
// and the current avatar (ignoring everything below the parent of the parent of the last free joint)
|
||||
collisions.clear();
|
||||
const Model& skeletonModel = _owningAvatar->getSkeletonModel();
|
||||
int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex(
|
||||
skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() :
|
||||
(i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1)));
|
||||
if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) {
|
||||
for (int j = 0; j < collisions.size(); ++j) {
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
}
|
||||
}
|
||||
// resolve penetration
|
||||
palm.addToPosition(-totalPenetration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +316,7 @@ void Hand::render(bool isMine) {
|
|||
}
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayLeapHands)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayHands)) {
|
||||
renderLeapHands(isMine);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ public:
|
|||
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
|
||||
const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;}
|
||||
|
||||
void collideAgainstAvatar(Avatar* avatar, bool isMyHand);
|
||||
void collideAgainstOurself();
|
||||
|
||||
private:
|
||||
// disallow copies of the Hand, copy of owning Avatar is disallowed too
|
||||
Hand(const Hand&);
|
||||
|
@ -87,7 +90,6 @@ private:
|
|||
void renderLeapHands(bool isMine);
|
||||
void renderLeapFingerTrails();
|
||||
|
||||
void updateCollisions();
|
||||
void calculateGeometry();
|
||||
|
||||
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
||||
|
|
|
@ -219,6 +219,34 @@ float Head::getTweakedRoll() const {
|
|||
return glm::clamp(_roll + _tweakedRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL);
|
||||
}
|
||||
|
||||
void Head::applyCollision(ModelCollisionInfo& collisionInfo) {
|
||||
// HACK: the collision proxies for the FaceModel are bad. As a temporary workaround
|
||||
// we collide against a hard coded collision proxy.
|
||||
// TODO: get a better collision proxy here.
|
||||
const float HEAD_RADIUS = 0.15f;
|
||||
const glm::vec3 HEAD_CENTER = _position;
|
||||
|
||||
// collide the contactPoint against the collision proxy to obtain a new penetration
|
||||
// NOTE: that penetration is in opposite direction (points the way out for the point, not the sphere)
|
||||
glm::vec3 penetration;
|
||||
if (findPointSpherePenetration(collisionInfo._contactPoint, HEAD_CENTER, HEAD_RADIUS, penetration)) {
|
||||
// compute lean angles
|
||||
Avatar* owningAvatar = static_cast<Avatar*>(_owningAvatar);
|
||||
glm::quat bodyRotation = owningAvatar->getOrientation();
|
||||
glm::vec3 neckPosition;
|
||||
if (owningAvatar->getSkeletonModel().getNeckPosition(neckPosition)) {
|
||||
glm::vec3 xAxis = bodyRotation * glm::vec3(1.f, 0.f, 0.f);
|
||||
glm::vec3 zAxis = bodyRotation * glm::vec3(0.f, 0.f, 1.f);
|
||||
float neckLength = glm::length(_position - neckPosition);
|
||||
if (neckLength > 0.f) {
|
||||
float forward = glm::dot(collisionInfo._penetration, zAxis) / neckLength;
|
||||
float sideways = - glm::dot(collisionInfo._penetration, xAxis) / neckLength;
|
||||
addLean(sideways, forward);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
|
||||
|
||||
Application::getInstance()->getGlowEffect()->begin();
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
float getTweakedPitch() const;
|
||||
float getTweakedYaw() const;
|
||||
float getTweakedRoll() const;
|
||||
|
||||
void applyCollision(ModelCollisionInfo& collisionInfo);
|
||||
|
||||
private:
|
||||
// disallow copies of the Head, copy of owning Avatar is disallowed too
|
||||
|
|
|
@ -112,23 +112,7 @@ void MyAvatar::updateTransmitter(float deltaTime) {
|
|||
void MyAvatar::update(float deltaTime) {
|
||||
updateTransmitter(deltaTime);
|
||||
|
||||
// TODO: resurrect touch interactions between avatars
|
||||
//// rotate body yaw for yaw received from multitouch
|
||||
//setOrientation(getOrientation() * glm::quat(glm::vec3(0, _yawFromTouch, 0)));
|
||||
//_yawFromTouch = 0.f;
|
||||
//
|
||||
//// apply pitch from touch
|
||||
//_head.setPitch(_head.getPitch() + _pitchFromTouch);
|
||||
//_pitchFromTouch = 0.0f;
|
||||
//
|
||||
//float TOUCH_YAW_SCALE = -0.25f;
|
||||
//float TOUCH_PITCH_SCALE = -12.5f;
|
||||
//float FIXED_TOUCH_TIMESTEP = 0.016f;
|
||||
//_yawFromTouch += ((_touchAvgX - _lastTouchAvgX) * TOUCH_YAW_SCALE * FIXED_TOUCH_TIMESTEP);
|
||||
//_pitchFromTouch += ((_touchAvgY - _lastTouchAvgY) * TOUCH_PITCH_SCALE * FIXED_TOUCH_TIMESTEP);
|
||||
|
||||
// Update my avatar's state from gyros
|
||||
updateFromGyros(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
|
||||
updateFromGyros(deltaTime);
|
||||
|
||||
// Update head mouse from faceshift if active
|
||||
Faceshift* faceshift = Application::getInstance()->getFaceshift();
|
||||
|
@ -329,6 +313,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
_position += _velocity * deltaTime;
|
||||
|
||||
// update avatar skeleton and simulate hand and head
|
||||
_hand.collideAgainstOurself();
|
||||
_hand.simulate(deltaTime, true);
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||
|
@ -348,7 +333,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
const float MAX_PITCH = 90.0f;
|
||||
|
||||
// Update avatar head rotation with sensor data
|
||||
void MyAvatar::updateFromGyros(bool turnWithHead) {
|
||||
void MyAvatar::updateFromGyros(float deltaTime) {
|
||||
Faceshift* faceshift = Application::getInstance()->getFaceshift();
|
||||
glm::vec3 estimatedPosition, estimatedRotation;
|
||||
|
||||
|
@ -356,7 +341,7 @@ void MyAvatar::updateFromGyros(bool turnWithHead) {
|
|||
estimatedPosition = faceshift->getHeadTranslation();
|
||||
estimatedRotation = safeEulerAngles(faceshift->getHeadRotation());
|
||||
// Rotate the body if the head is turned beyond the screen
|
||||
if (turnWithHead) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead)) {
|
||||
const float FACESHIFT_YAW_TURN_SENSITIVITY = 0.5f;
|
||||
const float FACESHIFT_MIN_YAW_TURN = 15.f;
|
||||
const float FACESHIFT_MAX_YAW_TURN = 50.f;
|
||||
|
@ -371,11 +356,12 @@ void MyAvatar::updateFromGyros(bool turnWithHead) {
|
|||
}
|
||||
} else {
|
||||
// restore rotation, lean to neutral positions
|
||||
const float RESTORE_RATE = 0.05f;
|
||||
_head.setYaw(glm::mix(_head.getYaw(), 0.0f, RESTORE_RATE));
|
||||
_head.setRoll(glm::mix(_head.getRoll(), 0.0f, RESTORE_RATE));
|
||||
_head.setLeanSideways(glm::mix(_head.getLeanSideways(), 0.0f, RESTORE_RATE));
|
||||
_head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, RESTORE_RATE));
|
||||
const float RESTORE_PERIOD = 1.f; // seconds
|
||||
float restorePercentage = glm::clamp(deltaTime/RESTORE_PERIOD, 0.f, 1.f);
|
||||
_head.setYaw(glm::mix(_head.getYaw(), 0.0f, restorePercentage));
|
||||
_head.setRoll(glm::mix(_head.getRoll(), 0.0f, restorePercentage));
|
||||
_head.setLeanSideways(glm::mix(_head.getLeanSideways(), 0.0f, restorePercentage));
|
||||
_head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, restorePercentage));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -854,7 +840,6 @@ void MyAvatar::updateCollisionWithEnvironment(float deltaTime, float radius) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||
const float VOXEL_ELASTICITY = 0.4f;
|
||||
const float VOXEL_DAMPING = 0.0f;
|
||||
|
@ -1002,8 +987,13 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
|
|||
avatar->getPosition(), theirCapsuleRadius, theirCapsuleHeight, penetration)) {
|
||||
// move the avatar out by half the penetration
|
||||
setPosition(_position - 0.5f * penetration);
|
||||
glm::vec3 pushOut = 0.5f * penetration;
|
||||
}
|
||||
|
||||
// collide our hands against them
|
||||
_hand.collideAgainstAvatar(avatar, true);
|
||||
|
||||
// collide their hands against us
|
||||
avatar->getHand().collideAgainstAvatar(this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
void reset();
|
||||
void update(float deltaTime);
|
||||
void simulate(float deltaTime);
|
||||
void updateFromGyros(bool turnWithHead);
|
||||
void updateFromGyros(float deltaTime);
|
||||
void updateTransmitter(float deltaTime);
|
||||
|
||||
void render(bool forceRenderHead);
|
||||
|
|
|
@ -36,23 +36,24 @@ void SkeletonModel::simulate(float deltaTime) {
|
|||
HandData& hand = _owningAvatar->getHand();
|
||||
hand.getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
||||
|
||||
const float HAND_RESTORATION_RATE = 0.25f;
|
||||
const float HAND_RESTORATION_PERIOD = 1.f; // seconds
|
||||
float handRestorePercent = glm::clamp(deltaTime / HAND_RESTORATION_PERIOD, 0.f, 1.f);
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
if (leftPalmIndex == -1) {
|
||||
// no Leap data; set hands from mouse
|
||||
if (_owningAvatar->getHandState() == HAND_STATE_NULL) {
|
||||
restoreRightHandPosition(HAND_RESTORATION_RATE);
|
||||
restoreRightHandPosition(handRestorePercent);
|
||||
} else {
|
||||
applyHandPosition(geometry.rightHandJointIndex, _owningAvatar->getHandPosition());
|
||||
}
|
||||
restoreLeftHandPosition(HAND_RESTORATION_RATE);
|
||||
restoreLeftHandPosition(handRestorePercent);
|
||||
|
||||
} else if (leftPalmIndex == rightPalmIndex) {
|
||||
// right hand only
|
||||
applyPalmData(geometry.rightHandJointIndex, geometry.rightFingerJointIndices, geometry.rightFingertipJointIndices,
|
||||
hand.getPalms()[leftPalmIndex]);
|
||||
restoreLeftHandPosition(HAND_RESTORATION_RATE);
|
||||
restoreLeftHandPosition(handRestorePercent);
|
||||
|
||||
} else {
|
||||
applyPalmData(geometry.leftHandJointIndex, geometry.leftFingerJointIndices, geometry.leftFingertipJointIndices,
|
||||
|
|
|
@ -477,7 +477,10 @@ bool Model::findSphereCollision(const glm::vec3& penetratorCenter, float penetra
|
|||
if (findSphereCapsuleConePenetration(relativeCenter, penetratorRadius, start, end,
|
||||
startRadius, endRadius, bonePenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, bonePenetration);
|
||||
// TODO: Andrew to try to keep the joint furthest toward the root
|
||||
// BUG: we currently overwrite the jointIndex with the last one found
|
||||
// which can cause incorrect collisions when colliding against more than
|
||||
// one joint.
|
||||
// TODO: fix this.
|
||||
jointIndex = i;
|
||||
}
|
||||
outerContinue: ;
|
||||
|
@ -722,7 +725,7 @@ void Model::renderCollisionProxies(float alpha) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
bool Model::isPokeable(ModelCollisionInfo& collision) const {
|
||||
bool Model::collisionHitsMoveableJoint(ModelCollisionInfo& collision) const {
|
||||
// the joint is pokable by a collision if it exists and is free to move
|
||||
const FBXJoint& joint = _geometry->getFBXGeometry().joints[collision._jointIndex];
|
||||
if (joint.parentIndex == -1 || _jointStates.isEmpty()) {
|
||||
|
@ -734,7 +737,7 @@ bool Model::isPokeable(ModelCollisionInfo& collision) const {
|
|||
return !freeLineage.isEmpty();
|
||||
}
|
||||
|
||||
bool Model::poke(ModelCollisionInfo& collision) {
|
||||
void Model::applyCollision(ModelCollisionInfo& collision) {
|
||||
// This needs work. At the moment it can wiggle joints that are free to move (such as arms)
|
||||
// but unmovable joints (such as torso) cannot be influenced at all.
|
||||
glm::vec3 jointPosition(0.f);
|
||||
|
@ -758,11 +761,10 @@ bool Model::poke(ModelCollisionInfo& collision) {
|
|||
getJointPosition(jointIndex, end);
|
||||
glm::vec3 newEnd = start + glm::angleAxis(glm::degrees(angle), axis) * (end - start);
|
||||
// try to move it
|
||||
return setJointPosition(jointIndex, newEnd, -1, true);
|
||||
setJointPosition(jointIndex, newEnd, -1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Model::deleteGeometry() {
|
||||
|
|
|
@ -167,12 +167,12 @@ public:
|
|||
|
||||
void renderCollisionProxies(float alpha);
|
||||
|
||||
/// \return true if the collision would move the model
|
||||
bool isPokeable(ModelCollisionInfo& collision) const;
|
||||
/// \return true if the collision is against a moveable joint
|
||||
bool collisionHitsMoveableJoint(ModelCollisionInfo& collision) const;
|
||||
|
||||
/// \param collisionInfo info about the collision
|
||||
/// \return true if collision affects the Model
|
||||
bool poke(ModelCollisionInfo& collisionInfo);
|
||||
/// Use the collisionInfo to affect the model
|
||||
void applyCollision(ModelCollisionInfo& collisionInfo);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// AvatarHashMap.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen AndrewMeadows on 1/28/2014.
|
||||
// Created by AndrewMeadows on 1/28/2014.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
|
|
|
@ -45,10 +45,3 @@ void HeadData::addLean(float sideways, float forwards) {
|
|||
_leanForward += forwards;
|
||||
}
|
||||
|
||||
bool HeadData::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration) const {
|
||||
// we would like to update this to determine collisions/penetrations with the Avatar's head sphere...
|
||||
// but right now it does not appear as if the HeadData has a position and radius.
|
||||
// this is a placeholder for now.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,13 +58,6 @@ public:
|
|||
void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; }
|
||||
|
||||
friend class AvatarData;
|
||||
|
||||
/// Checks for penetration between the described sphere and the hand.
|
||||
/// \param penetratorCenter the center of the penetration test sphere
|
||||
/// \param penetratorRadius the radius of the penetration test sphere
|
||||
/// \param penetration[out] the vector in which to store the penetration
|
||||
/// \return whether or not the sphere penetrated
|
||||
bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration) const;
|
||||
|
||||
protected:
|
||||
float _yaw;
|
||||
|
|
|
@ -11,13 +11,19 @@
|
|||
#include "OctreeScriptingInterface.h"
|
||||
|
||||
OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packetSender,
|
||||
JurisdictionListener* jurisdictionListener)
|
||||
JurisdictionListener* jurisdictionListener) :
|
||||
_packetSender(NULL),
|
||||
_jurisdictionListener(NULL),
|
||||
_managedPacketSender(false),
|
||||
_managedJurisdictionListener(false),
|
||||
_initialized(false)
|
||||
{
|
||||
setPacketSender(packetSender);
|
||||
setJurisdictionListener(jurisdictionListener);
|
||||
}
|
||||
|
||||
OctreeScriptingInterface::~OctreeScriptingInterface() {
|
||||
qDebug() << "OctreeScriptingInterface::~OctreeScriptingInterface() this=" << this;
|
||||
cleanupManagedObjects();
|
||||
}
|
||||
|
||||
|
@ -45,6 +51,9 @@ void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jur
|
|||
}
|
||||
|
||||
void OctreeScriptingInterface::init() {
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
if (_jurisdictionListener) {
|
||||
_managedJurisdictionListener = false;
|
||||
} else {
|
||||
|
@ -64,5 +73,5 @@ void OctreeScriptingInterface::init() {
|
|||
if (QCoreApplication::instance()) {
|
||||
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(cleanupManagedObjects()));
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ protected:
|
|||
JurisdictionListener* _jurisdictionListener;
|
||||
bool _managedPacketSender;
|
||||
bool _managedJurisdictionListener;
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__OctreeScriptingInterface__) */
|
||||
|
|
Loading…
Reference in a new issue