mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
Merge pull request #479 from Ventrella/master
preparing avatar balls for extended touch capabilities
This commit is contained in:
commit
c7921c4be9
7 changed files with 453 additions and 294 deletions
|
@ -1,106 +1,106 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
//
|
//
|
||||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||||
//
|
//
|
||||||
// NVIDIA Statement on the Software
|
// NVIDIA Statement on the Software
|
||||||
//
|
//
|
||||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||||
// detailed.
|
// detailed.
|
||||||
//
|
//
|
||||||
// No Warranty
|
// No Warranty
|
||||||
//
|
//
|
||||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
//
|
//
|
||||||
// Limitation of Liability
|
// Limitation of Liability
|
||||||
//
|
//
|
||||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Atmospheric scattering fragment shader
|
// Atmospheric scattering fragment shader
|
||||||
//
|
//
|
||||||
// Author: Sean O'Neil
|
// Author: Sean O'Neil
|
||||||
//
|
//
|
||||||
// Copyright (c) 2004 Sean O'Neil
|
// Copyright (c) 2004 Sean O'Neil
|
||||||
//
|
//
|
||||||
|
|
||||||
uniform vec3 v3CameraPos; // The camera's current position
|
uniform vec3 v3CameraPos; // The camera's current position
|
||||||
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||||
uniform float fInnerRadius; // The inner (planetary) radius
|
uniform float fInnerRadius; // The inner (planetary) radius
|
||||||
uniform float fKrESun; // Kr * ESun
|
uniform float fKrESun; // Kr * ESun
|
||||||
uniform float fKmESun; // Km * ESun
|
uniform float fKmESun; // Km * ESun
|
||||||
uniform float fKr4PI; // Kr * 4 * PI
|
uniform float fKr4PI; // Kr * 4 * PI
|
||||||
uniform float fKm4PI; // Km * 4 * PI
|
uniform float fKm4PI; // Km * 4 * PI
|
||||||
uniform float fScale; // 1 / (fOuterRadius - fInnerRadius)
|
uniform float fScale; // 1 / (fOuterRadius - fInnerRadius)
|
||||||
uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||||
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
|
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
|
||||||
|
|
||||||
const int nSamples = 2;
|
const int nSamples = 2;
|
||||||
const float fSamples = 2.0;
|
const float fSamples = 2.0;
|
||||||
|
|
||||||
uniform vec3 v3LightPos;
|
uniform vec3 v3LightPos;
|
||||||
uniform float g;
|
uniform float g;
|
||||||
uniform float g2;
|
uniform float g2;
|
||||||
|
|
||||||
varying vec3 position;
|
varying vec3 position;
|
||||||
|
|
||||||
float scale(float fCos)
|
float scale(float fCos)
|
||||||
{
|
{
|
||||||
float x = 1.0 - fCos;
|
float x = 1.0 - fCos;
|
||||||
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void main (void)
|
void main (void)
|
||||||
{
|
{
|
||||||
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
||||||
vec3 v3Pos = position;
|
vec3 v3Pos = position;
|
||||||
vec3 v3Ray = v3Pos - v3CameraPos;
|
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||||
float fFar = length(v3Ray);
|
float fFar = length(v3Ray);
|
||||||
v3Ray /= fFar;
|
v3Ray /= fFar;
|
||||||
|
|
||||||
// Calculate the ray's starting position, then calculate its scattering offset
|
// Calculate the ray's starting position, then calculate its scattering offset
|
||||||
vec3 v3Start = v3CameraPos;
|
vec3 v3Start = v3CameraPos;
|
||||||
float fHeight = length(v3Start);
|
float fHeight = length(v3Start);
|
||||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||||
float fStartOffset = fDepth * scale(fStartAngle);
|
float fStartOffset = fDepth * scale(fStartAngle);
|
||||||
|
|
||||||
// Initialize the scattering loop variables
|
// Initialize the scattering loop variables
|
||||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
float fSampleLength = fFar / fSamples;
|
float fSampleLength = fFar / fSamples;
|
||||||
float fScaledLength = fSampleLength * fScale;
|
float fScaledLength = fSampleLength * fScale;
|
||||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||||
|
|
||||||
// Now loop through the sample rays
|
// Now loop through the sample rays
|
||||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||||
for(int i=0; i<nSamples; i++)
|
for(int i=0; i<nSamples; i++)
|
||||||
{
|
{
|
||||||
float fHeight = length(v3SamplePoint);
|
float fHeight = length(v3SamplePoint);
|
||||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||||
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
||||||
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
||||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||||
v3SamplePoint += v3SampleRay;
|
v3SamplePoint += v3SampleRay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||||
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
||||||
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||||
vec3 v3Direction = v3CameraPos - v3Pos;
|
vec3 v3Direction = v3CameraPos - v3Pos;
|
||||||
|
|
||||||
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||||
gl_FragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
gl_FragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
||||||
gl_FragColor.a = gl_FragColor.b;
|
gl_FragColor.a = gl_FragColor.b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
const bool TESTING_AVATAR_TOUCH = false;
|
||||||
|
|
||||||
// Starfield information
|
// Starfield information
|
||||||
static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
||||||
static char STAR_CACHE_FILE[] = "cachedStars.txt";
|
static char STAR_CACHE_FILE[] = "cachedStars.txt";
|
||||||
|
@ -287,22 +289,22 @@ void Application::paintGL() {
|
||||||
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
_myCamera.setTightness (100.0f);
|
_myCamera.setTightness (100.0f);
|
||||||
_myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getBallPosition(AVATAR_JOINT_HEAD_BASE));
|
||||||
_myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
|
_myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
|
||||||
|
|
||||||
} else if (OculusManager::isConnected()) {
|
} else if (OculusManager::isConnected()) {
|
||||||
_myCamera.setUpShift (0.0f);
|
_myCamera.setUpShift (0.0f);
|
||||||
_myCamera.setDistance (0.0f);
|
_myCamera.setDistance (0.0f);
|
||||||
_myCamera.setTightness (100.0f);
|
_myCamera.setTightness (100.0f);
|
||||||
_myCamera.setTargetPosition(_myAvatar.getHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getHeadJointPosition());
|
||||||
_myCamera.setTargetRotation(_myAvatar.getHead().getOrientation());
|
_myCamera.setTargetRotation(_myAvatar.getHead().getOrientation());
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||||
_myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getBallPosition(AVATAR_JOINT_HEAD_BASE));
|
||||||
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
_myCamera.setTargetPosition(_myAvatar.getHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getHeadJointPosition());
|
||||||
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
_myCamera.setTargetRotation(_myAvatar.getHead().getWorldAlignedOrientation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,24 +1080,29 @@ void Application::idle() {
|
||||||
_myAvatar.simulate(deltaTime, NULL);
|
_myAvatar.simulate(deltaTime, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) {
|
if (TESTING_AVATAR_TOUCH) {
|
||||||
if (_manualFirstPerson) {
|
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
|
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
_myCamera.setModeShiftRate(1.0f);
|
||||||
_myCamera.setModeShiftRate(1.0f);
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) {
|
||||||
|
if (_manualFirstPerson) {
|
||||||
if (_myAvatar.getIsNearInteractingOther()) {
|
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
|
|
||||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||||
_myCamera.setModeShiftRate(1.0f);
|
_myCamera.setModeShiftRate(1.0f);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (_myAvatar.getIsNearInteractingOther()) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
|
||||||
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||||
_myCamera.setModeShiftRate(1.0f);
|
_myCamera.setModeShiftRate(1.0f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
|
||||||
|
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||||
|
_myCamera.setModeShiftRate(1.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1547,7 +1554,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||||
if (_cameraFrustum->isChecked()) {
|
if (_cameraFrustum->isChecked()) {
|
||||||
position = camera.getPosition();
|
position = camera.getPosition();
|
||||||
} else {
|
} else {
|
||||||
position = _myAvatar.getHeadPosition();
|
position = _myAvatar.getHeadJointPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
float fov = camera.getFieldOfView();
|
float fov = camera.getFieldOfView();
|
||||||
|
|
|
@ -143,7 +143,7 @@ int audioCallback (const void* inputBuffer,
|
||||||
unsigned char *currentPacketPtr = dataPacket + 1;
|
unsigned char *currentPacketPtr = dataPacket + 1;
|
||||||
|
|
||||||
// memcpy the three float positions
|
// memcpy the three float positions
|
||||||
memcpy(currentPacketPtr, &interfaceAvatar->getHeadPosition(), sizeof(float) * 3);
|
memcpy(currentPacketPtr, &interfaceAvatar->getHeadJointPosition(), sizeof(float) * 3);
|
||||||
currentPacketPtr += (sizeof(float) * 3);
|
currentPacketPtr += (sizeof(float) * 3);
|
||||||
|
|
||||||
// tell the mixer not to add additional attenuation to our source
|
// tell the mixer not to add additional attenuation to our source
|
||||||
|
|
|
@ -44,7 +44,7 @@ const float HEAD_MAX_YAW = 85;
|
||||||
const float HEAD_MIN_YAW = -85;
|
const float HEAD_MIN_YAW = -85;
|
||||||
const float PERIPERSONAL_RADIUS = 1.0f;
|
const float PERIPERSONAL_RADIUS = 1.0f;
|
||||||
const float AVATAR_BRAKING_STRENGTH = 40.0f;
|
const float AVATAR_BRAKING_STRENGTH = 40.0f;
|
||||||
const float JOINT_TOUCH_RANGE = 0.01f;
|
const float MOUSE_RAY_TOUCH_RANGE = 0.01f;
|
||||||
const float FLOATING_HEIGHT = 0.13f;
|
const float FLOATING_HEIGHT = 0.13f;
|
||||||
const bool USING_HEAD_LEAN = false;
|
const bool USING_HEAD_LEAN = false;
|
||||||
const float LEAN_SENSITIVITY = 0.15;
|
const float LEAN_SENSITIVITY = 0.15;
|
||||||
|
@ -64,7 +64,8 @@ float chatMessageHeight = 0.20;
|
||||||
Avatar::Avatar(Agent* owningAgent) :
|
Avatar::Avatar(Agent* owningAgent) :
|
||||||
AvatarData(owningAgent),
|
AvatarData(owningAgent),
|
||||||
_head(this),
|
_head(this),
|
||||||
_TEST_bigSphereRadius(0.4f),
|
_ballSpringsInitialized(false),
|
||||||
|
_TEST_bigSphereRadius(0.5f),
|
||||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||||
_mousePressed(false),
|
_mousePressed(false),
|
||||||
_bodyPitchDelta(0.0f),
|
_bodyPitchDelta(0.0f),
|
||||||
|
@ -101,10 +102,10 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
|
|
||||||
initializeBodyBalls();
|
initializeBodyBalls();
|
||||||
|
|
||||||
_height = _skeleton.getHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius + _bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius;
|
_height = _skeleton.getHeight() + _bodyBall[ BODY_BALL_LEFT_HEEL ].radius + _bodyBall[ BODY_BALL_HEAD_BASE ].radius;
|
||||||
_maxArmLength = _skeleton.getArmLength();
|
_maxArmLength = _skeleton.getArmLength();
|
||||||
_pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius;
|
_pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _bodyBall[ BODY_BALL_LEFT_HEEL ].radius;
|
||||||
_pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius;
|
_pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _bodyBall[ BODY_BALL_LEFT_HEEL ].radius;
|
||||||
|
|
||||||
_avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS);
|
_avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS);
|
||||||
|
|
||||||
|
@ -118,49 +119,142 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
|
|
||||||
void Avatar::initializeBodyBalls() {
|
void Avatar::initializeBodyBalls() {
|
||||||
|
|
||||||
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
_ballSpringsInitialized = false; //this gets set to true on the first update pass...
|
||||||
_bodyBall[b].isCollidable = true;
|
|
||||||
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
|
_bodyBall[b].parentJoint = AVATAR_JOINT_NULL;
|
||||||
|
_bodyBall[b].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
_bodyBall[b].position = glm::vec3(0.0, 0.0, 0.0);
|
_bodyBall[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||||
_bodyBall[b].velocity = glm::vec3(0.0, 0.0, 0.0);
|
_bodyBall[b].velocity = glm::vec3(0.0, 0.0, 0.0);
|
||||||
_bodyBall[b].radius = 0.0;
|
_bodyBall[b].radius = 0.0;
|
||||||
_bodyBall[b].touchForce = 0.0;
|
_bodyBall[b].touchForce = 0.0;
|
||||||
|
_bodyBall[b].isCollidable = true;
|
||||||
_bodyBall[b].jointTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
_bodyBall[b].jointTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// specify the radius of each ball
|
||||||
|
_bodyBall[ BODY_BALL_PELVIS ].radius = 0.07;
|
||||||
|
_bodyBall[ BODY_BALL_TORSO ].radius = 0.065;
|
||||||
|
_bodyBall[ BODY_BALL_CHEST ].radius = 0.08;
|
||||||
|
_bodyBall[ BODY_BALL_NECK_BASE ].radius = 0.03;
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_BASE ].radius = 0.07;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_COLLAR ].radius = 0.04;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].radius = 0.03;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_ELBOW ].radius = 0.02;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_WRIST ].radius = 0.02;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].radius = 0.01;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].radius = 0.04;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].radius = 0.03;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].radius = 0.02;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].radius = 0.02;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].radius = 0.01;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HIP ].radius = 0.04;
|
||||||
|
|
||||||
|
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH ].radius = 0.03;
|
||||||
|
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_KNEE ].radius = 0.025;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HEEL ].radius = 0.025;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_TOES ].radius = 0.025;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HIP ].radius = 0.04;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_KNEE ].radius = 0.025;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HEEL ].radius = 0.025;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_TOES ].radius = 0.025;
|
||||||
|
|
||||||
// specify the radii of the joints
|
|
||||||
_bodyBall[ AVATAR_JOINT_PELVIS ].radius = 0.07;
|
|
||||||
_bodyBall[ AVATAR_JOINT_TORSO ].radius = 0.065;
|
|
||||||
_bodyBall[ AVATAR_JOINT_CHEST ].radius = 0.08;
|
|
||||||
_bodyBall[ AVATAR_JOINT_NECK_BASE ].radius = 0.03;
|
|
||||||
_bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius = 0.07;
|
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.04;
|
// specify the parent joint for each ball
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_SHOULDER ].radius = 0.03;
|
_bodyBall[ BODY_BALL_PELVIS ].parentJoint = AVATAR_JOINT_PELVIS;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.02;
|
_bodyBall[ BODY_BALL_TORSO ].parentJoint = AVATAR_JOINT_TORSO;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_WRIST ].radius = 0.02;
|
_bodyBall[ BODY_BALL_CHEST ].parentJoint = AVATAR_JOINT_CHEST;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_FINGERTIPS ].radius = 0.01;
|
_bodyBall[ BODY_BALL_NECK_BASE ].parentJoint = AVATAR_JOINT_NECK_BASE;
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_BASE ].parentJoint = AVATAR_JOINT_HEAD_BASE;
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_TOP ].parentJoint = AVATAR_JOINT_HEAD_TOP;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentJoint = AVATAR_JOINT_LEFT_COLLAR;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentJoint = AVATAR_JOINT_LEFT_SHOULDER;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentJoint = AVATAR_JOINT_LEFT_ELBOW;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentJoint = AVATAR_JOINT_LEFT_WRIST;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentJoint = AVATAR_JOINT_LEFT_FINGERTIPS;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentJoint = AVATAR_JOINT_RIGHT_COLLAR;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentJoint = AVATAR_JOINT_RIGHT_SHOULDER;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentJoint = AVATAR_JOINT_RIGHT_ELBOW;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentJoint = AVATAR_JOINT_RIGHT_WRIST;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentJoint = AVATAR_JOINT_RIGHT_FINGERTIPS;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HIP ].parentJoint = AVATAR_JOINT_LEFT_HIP;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentJoint = AVATAR_JOINT_LEFT_KNEE;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentJoint = AVATAR_JOINT_LEFT_HEEL;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_TOES ].parentJoint = AVATAR_JOINT_LEFT_TOES;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentJoint = AVATAR_JOINT_RIGHT_HIP;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentJoint = AVATAR_JOINT_RIGHT_KNEE;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentJoint = AVATAR_JOINT_RIGHT_HEEL;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentJoint = AVATAR_JOINT_RIGHT_TOES;
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.04;
|
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH].parentJoint = AVATAR_JOINT_LEFT_HIP;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.03;
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].radius = 0.02;
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].radius = 0.02;
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].radius = 0.01;
|
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_HIP ].radius = 0.04;
|
// specify the parent offset for each ball
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_KNEE ].radius = 0.025;
|
_bodyBall[ BODY_BALL_PELVIS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius = 0.025;
|
_bodyBall[ BODY_BALL_TORSO ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_TOES ].radius = 0.025;
|
_bodyBall[ BODY_BALL_CHEST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_NECK_BASE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_BASE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_TOP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HIP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_TOES ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04;
|
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH].parentOffset = glm::vec3(-0.1, -0.1, 0.0);
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025;
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025;
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025;
|
// specify the parent BALL for each ball
|
||||||
|
_bodyBall[ BODY_BALL_PELVIS ].parentBall = BODY_BALL_NULL;
|
||||||
|
_bodyBall[ BODY_BALL_TORSO ].parentBall = BODY_BALL_PELVIS;
|
||||||
|
_bodyBall[ BODY_BALL_CHEST ].parentBall = BODY_BALL_TORSO;
|
||||||
|
_bodyBall[ BODY_BALL_NECK_BASE ].parentBall = BODY_BALL_CHEST;
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_BASE ].parentBall = BODY_BALL_NECK_BASE;
|
||||||
|
_bodyBall[ BODY_BALL_HEAD_TOP ].parentBall = BODY_BALL_HEAD_BASE;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentBall = BODY_BALL_CHEST;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentBall = BODY_BALL_LEFT_COLLAR;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentBall = BODY_BALL_LEFT_SHOULDER;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentBall = BODY_BALL_LEFT_ELBOW;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentBall = BODY_BALL_LEFT_WRIST;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentBall = BODY_BALL_CHEST;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentBall = BODY_BALL_RIGHT_COLLAR;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentBall = BODY_BALL_RIGHT_SHOULDER;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentBall = BODY_BALL_RIGHT_ELBOW;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentBall = BODY_BALL_RIGHT_WRIST;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HIP ].parentBall = BODY_BALL_PELVIS;
|
||||||
|
|
||||||
|
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH ].parentBall = BODY_BALL_LEFT_HIP;
|
||||||
|
|
||||||
|
// _bodyBall[ BODY_BALL_LEFT_KNEE ].parentBall = BODY_BALL_LEFT_MID_THIGH;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentBall = BODY_BALL_LEFT_HIP;
|
||||||
|
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentBall = BODY_BALL_LEFT_KNEE;
|
||||||
|
_bodyBall[ BODY_BALL_LEFT_TOES ].parentBall = BODY_BALL_LEFT_HEEL;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentBall = BODY_BALL_PELVIS;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentBall = BODY_BALL_RIGHT_HIP;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentBall = BODY_BALL_RIGHT_KNEE;
|
||||||
|
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentBall = BODY_BALL_RIGHT_HEEL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// to aid in hand-shaking and hand-holding, the right hand is not collidable
|
// to aid in hand-shaking and hand-holding, the right hand is not collidable
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false;
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].isCollidable = false;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false;
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].isCollidable = false;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false;
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS].isCollidable = false;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +369,25 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
// update avatar skeleton
|
// update avatar skeleton
|
||||||
_skeleton.update(deltaTime, getOrientation(), _position);
|
_skeleton.update(deltaTime, getOrientation(), _position);
|
||||||
|
|
||||||
|
//determine the lengths of the body springs now that we have updated the skeleton at least once
|
||||||
|
if (!_ballSpringsInitialized) {
|
||||||
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
|
|
||||||
|
glm::vec3 targetPosition
|
||||||
|
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||||
|
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||||
|
|
||||||
|
glm::vec3 parentTargetPosition
|
||||||
|
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||||
|
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||||
|
|
||||||
|
_bodyBall[b].springLength = glm::length(targetPosition - parentTargetPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ballSpringsInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if this is not my avatar, then hand position comes from transmitted data
|
// if this is not my avatar, then hand position comes from transmitted data
|
||||||
if (_owningAgent) {
|
if (_owningAgent) {
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
||||||
|
@ -456,22 +569,22 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
right * _head.getLeanSideways() +
|
right * _head.getLeanSideways() +
|
||||||
front * _head.getLeanForward();
|
front * _head.getLeanForward();
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_TORSO ].position += headLean * 0.1f;
|
_bodyBall[ BODY_BALL_TORSO ].position += headLean * 0.1f;
|
||||||
_bodyBall[ AVATAR_JOINT_CHEST ].position += headLean * 0.4f;
|
_bodyBall[ BODY_BALL_CHEST ].position += headLean * 0.4f;
|
||||||
_bodyBall[ AVATAR_JOINT_NECK_BASE ].position += headLean * 0.7f;
|
_bodyBall[ BODY_BALL_NECK_BASE ].position += headLean * 0.7f;
|
||||||
_bodyBall[ AVATAR_JOINT_HEAD_BASE ].position += headLean * 1.0f;
|
_bodyBall[ BODY_BALL_HEAD_BASE ].position += headLean * 1.0f;
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_COLLAR ].position += headLean * 0.6f;
|
_bodyBall[ BODY_BALL_LEFT_COLLAR ].position += headLean * 0.6f;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_SHOULDER ].position += headLean * 0.6f;
|
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].position += headLean * 0.6f;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_ELBOW ].position += headLean * 0.2f;
|
_bodyBall[ BODY_BALL_LEFT_ELBOW ].position += headLean * 0.2f;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_WRIST ].position += headLean * 0.1f;
|
_bodyBall[ BODY_BALL_LEFT_WRIST ].position += headLean * 0.1f;
|
||||||
_bodyBall[ AVATAR_JOINT_LEFT_FINGERTIPS ].position += headLean * 0.0f;
|
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].position += headLean * 0.0f;
|
||||||
|
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_COLLAR ].position += headLean * 0.6f;
|
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].position += headLean * 0.6f;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_SHOULDER ].position += headLean * 0.6f;
|
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].position += headLean * 0.6f;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].position += headLean * 0.2f;
|
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].position += headLean * 0.2f;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].position += headLean * 0.1f;
|
_bodyBall[ BODY_BALL_RIGHT_WRIST ].position += headLean * 0.1f;
|
||||||
_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += headLean * 0.0f;
|
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].position += headLean * 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,8 +598,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
_head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||||
_head.setPosition(_bodyBall[ AVATAR_JOINT_HEAD_BASE ].position);
|
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
|
||||||
_head.setScale (_bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius);
|
_head.setScale (_bodyBall[ BODY_BALL_HEAD_BASE ].radius);
|
||||||
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
||||||
_head.simulate(deltaTime, !_owningAgent);
|
_head.simulate(deltaTime, !_owningAgent);
|
||||||
|
|
||||||
|
@ -500,12 +613,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
|
|
||||||
void Avatar::checkForMouseRayTouching() {
|
void Avatar::checkForMouseRayTouching() {
|
||||||
|
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
|
|
||||||
glm::vec3 directionToBodySphere = glm::normalize(_bodyBall[b].position - _mouseRayOrigin);
|
glm::vec3 directionToBodySphere = glm::normalize(_bodyBall[b].position - _mouseRayOrigin);
|
||||||
float dot = glm::dot(directionToBodySphere, _mouseRayDirection);
|
float dot = glm::dot(directionToBodySphere, _mouseRayDirection);
|
||||||
|
|
||||||
float range = _bodyBall[b].radius * JOINT_TOUCH_RANGE;
|
float range = _bodyBall[b].radius * MOUSE_RAY_TOUCH_RANGE;
|
||||||
|
|
||||||
if (dot > (1.0f - range)) {
|
if (dot > (1.0f - range)) {
|
||||||
_bodyBall[b].touchForce = (dot - (1.0f - range)) / range;
|
_bodyBall[b].touchForce = (dot - (1.0f - range)) / range;
|
||||||
|
@ -557,11 +670,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||||
|
|
||||||
//Test: Show angle between your fwd vector and nearest avatar
|
|
||||||
//glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
|
|
||||||
// getJointPosition(AVATAR_JOINT_PELVIS);
|
|
||||||
//printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, getBodyFrontDirection()));
|
|
||||||
|
|
||||||
// test whether shoulders are close enough to allow for reaching to touch hands
|
// test whether shoulders are close enough to allow for reaching to touch hands
|
||||||
glm::vec3 v(_position - otherAvatar->_position);
|
glm::vec3 v(_position - otherAvatar->_position);
|
||||||
float distance = glm::length(v);
|
float distance = glm::length(v);
|
||||||
|
@ -579,7 +687,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
|
|
||||||
_avatarTouch.setHasInteractingOther(true);
|
_avatarTouch.setHasInteractingOther(true);
|
||||||
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
||||||
_avatarTouch.setYourHandPosition(_interactingOther->_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
_avatarTouch.setYourHandPosition(_interactingOther->_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].position);
|
||||||
_avatarTouch.setYourOrientation (_interactingOther->getOrientation());
|
_avatarTouch.setYourOrientation (_interactingOther->getOrientation());
|
||||||
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
||||||
|
|
||||||
|
@ -650,32 +758,29 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_avatarTouch.setMyHandState(_handState);
|
_avatarTouch.setMyHandState(_handState);
|
||||||
_avatarTouch.setMyHandPosition(_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
_avatarTouch.setMyHandPosition(_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float deltaTime) {
|
void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float deltaTime) {
|
||||||
float myBodyApproximateBoundingRadius = 1.0f;
|
float myBodyApproximateBoundingRadius = 1.0f;
|
||||||
glm::vec3 vectorFromMyBodyToBigSphere(_position - position);
|
glm::vec3 vectorFromMyBodyToBigSphere(_position - position);
|
||||||
bool jointCollision = false;
|
|
||||||
|
|
||||||
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
||||||
if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) {
|
if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) {
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
glm::vec3 vectorFromJointToBigSphereCenter(_bodyBall[b].position - position);
|
glm::vec3 vectorFromBallToBigSphereCenter(_bodyBall[b].position - position);
|
||||||
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
float distanceToBigSphereCenter = glm::length(vectorFromBallToBigSphereCenter);
|
||||||
float combinedRadius = _bodyBall[b].radius + radius;
|
float combinedRadius = _bodyBall[b].radius + radius;
|
||||||
|
|
||||||
if (distanceToBigSphereCenter < combinedRadius) {
|
if (distanceToBigSphereCenter < combinedRadius) {
|
||||||
jointCollision = true;
|
|
||||||
if (distanceToBigSphereCenter > 0.0) {
|
if (distanceToBigSphereCenter > 0.0) {
|
||||||
glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter;
|
glm::vec3 directionVector = vectorFromBallToBigSphereCenter / distanceToBigSphereCenter;
|
||||||
|
|
||||||
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
||||||
glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration;
|
glm::vec3 collisionForce = vectorFromBallToBigSphereCenter * penetration;
|
||||||
|
|
||||||
_bodyBall[b].velocity += collisionForce * 0.0f * deltaTime;
|
_velocity += collisionForce * 40.0f * deltaTime;
|
||||||
_velocity += collisionForce * 40.0f * deltaTime;
|
|
||||||
_bodyBall[b].position = position + directionVector * combinedRadius;
|
_bodyBall[b].position = position + directionVector * combinedRadius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,7 +834,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) {
|
||||||
// Reset detector for nearest avatar
|
// Reset detector for nearest avatar
|
||||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
//loop through all the other avatars for potential interactions...
|
// loop through all the other avatars for potential interactions...
|
||||||
AgentList* agentList = AgentList::getInstance();
|
AgentList* agentList = AgentList::getInstance();
|
||||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||||
|
@ -739,7 +844,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) {
|
||||||
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
|
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
|
||||||
|
|
||||||
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
|
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
|
||||||
//apply forces from collision
|
// apply forces from collision
|
||||||
applyCollisionWithOtherAvatar(otherAvatar, deltaTime);
|
applyCollisionWithOtherAvatar(otherAvatar, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,30 +860,30 @@ void Avatar::updateAvatarCollisions(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//detect collisions with other avatars and respond
|
// detect collisions with other avatars and respond
|
||||||
void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
|
void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
|
||||||
|
|
||||||
glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f);
|
glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
// loop through the joints of each avatar to check for every possible collision
|
// loop through the body balls of each avatar to check for every possible collision
|
||||||
for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
|
for (int b = 1; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
if (_bodyBall[b].isCollidable) {
|
if (_bodyBall[b].isCollidable) {
|
||||||
|
|
||||||
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
|
for (int o = b+1; o < NUM_AVATAR_BODY_BALLS; o++) {
|
||||||
if (otherAvatar->_bodyBall[o].isCollidable) {
|
if (otherAvatar->_bodyBall[o].isCollidable) {
|
||||||
|
|
||||||
glm::vec3 vectorBetweenJoints(_bodyBall[b].position - otherAvatar->_bodyBall[o].position);
|
glm::vec3 vectorBetweenBalls(_bodyBall[b].position - otherAvatar->_bodyBall[o].position);
|
||||||
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
float distanceBetweenBalls = glm::length(vectorBetweenBalls);
|
||||||
|
|
||||||
if (distanceBetweenJoints > 0.0) { // to avoid divide by zero
|
if (distanceBetweenBalls > 0.0) { // to avoid divide by zero
|
||||||
float combinedRadius = _bodyBall[b].radius + otherAvatar->_bodyBall[o].radius;
|
float combinedRadius = _bodyBall[b].radius + otherAvatar->_bodyBall[o].radius;
|
||||||
|
|
||||||
// check for collision
|
// check for collision
|
||||||
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
if (distanceBetweenBalls < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
||||||
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
|
glm::vec3 directionVector = vectorBetweenBalls / distanceBetweenBalls;
|
||||||
|
|
||||||
// push balls away from each other and apply friction
|
// push balls away from each other and apply friction
|
||||||
float penetration = 1.0f - (distanceBetweenJoints / (combinedRadius * COLLISION_RADIUS_SCALAR));
|
float penetration = 1.0f - (distanceBetweenBalls / (combinedRadius * COLLISION_RADIUS_SCALAR));
|
||||||
|
|
||||||
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime;
|
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime;
|
||||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime;
|
bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime;
|
||||||
|
@ -793,7 +898,7 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime
|
||||||
} // b loop
|
} // b loop
|
||||||
} // collidable
|
} // collidable
|
||||||
|
|
||||||
//apply force on the whole body
|
// apply force on the whole body
|
||||||
_velocity += bodyPushForce;
|
_velocity += bodyPushForce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,7 +938,7 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
// render a simple round on the ground projected down from the avatar's position
|
// render a simple round on the ground projected down from the avatar's position
|
||||||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f);
|
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f);
|
||||||
|
|
||||||
//render body
|
// render body
|
||||||
renderBody(lookingInMirror);
|
renderBody(lookingInMirror);
|
||||||
|
|
||||||
// if this is my avatar, then render my interactions with the other avatar
|
// if this is my avatar, then render my interactions with the other avatar
|
||||||
|
@ -857,7 +962,7 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
glm::vec3 chatPosition = _bodyBall[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight;
|
glm::vec3 chatPosition = _bodyBall[BODY_BALL_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight;
|
||||||
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
|
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
|
||||||
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
|
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
|
||||||
glm::vec3 chatAxis = glm::axis(chatRotation);
|
glm::vec3 chatAxis = glm::axis(chatRotation);
|
||||||
|
@ -893,61 +998,73 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::resetBodyBalls() {
|
void Avatar::resetBodyBalls() {
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
_bodyBall[b].position = _skeleton.joint[b].position;
|
|
||||||
|
glm::vec3 targetPosition
|
||||||
|
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||||
|
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||||
|
|
||||||
|
_bodyBall[b].position = targetPosition; // put ball on target position
|
||||||
_bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
_bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateBodyBalls(float deltaTime) {
|
void Avatar::updateBodyBalls(float deltaTime) {
|
||||||
// Check for a large repositioning, and re-initialize balls if this has happened
|
// Check for a large repositioning, and re-initialize balls if this has happened
|
||||||
const float BEYOND_BODY_SPRING_RANGE = 2.f;
|
const float BEYOND_BODY_SPRING_RANGE = 2.f;
|
||||||
if (glm::length(_position - _bodyBall[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) {
|
if (glm::length(_position - _bodyBall[BODY_BALL_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) {
|
||||||
resetBodyBalls();
|
resetBodyBalls();
|
||||||
}
|
}
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
glm::vec3 springVector(_bodyBall[b].position);
|
|
||||||
|
if (_ballSpringsInitialized) {
|
||||||
if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) {
|
|
||||||
springVector -= _position;
|
// apply spring forces
|
||||||
}
|
glm::vec3 springVector(_bodyBall[b].position);
|
||||||
else {
|
|
||||||
springVector -= _bodyBall[ _skeleton.joint[b].parent ].position;
|
|
||||||
}
|
|
||||||
|
|
||||||
float length = glm::length(springVector);
|
|
||||||
|
|
||||||
if (length > 0.0f) { // to avoid divide by zero
|
|
||||||
glm::vec3 springDirection = springVector / length;
|
|
||||||
|
|
||||||
float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
|
||||||
_bodyBall[b].velocity -= springDirection * force;
|
|
||||||
|
|
||||||
if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) {
|
if (b == BODY_BALL_PELVIS) {
|
||||||
_bodyBall[_skeleton.joint[b].parent].velocity += springDirection * force;
|
springVector -= _position;
|
||||||
|
} else {
|
||||||
|
springVector -= _bodyBall[_bodyBall[b].parentBall].position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float length = glm::length(springVector);
|
||||||
|
|
||||||
|
if (length > 0.0f) { // to avoid divide by zero
|
||||||
|
glm::vec3 springDirection = springVector / length;
|
||||||
|
|
||||||
|
float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
||||||
|
_bodyBall[b].velocity -= springDirection * force;
|
||||||
|
|
||||||
|
if (_bodyBall[b].parentBall != BODY_BALL_NULL) {
|
||||||
|
_bodyBall[_bodyBall[b].parentBall].velocity += springDirection * force;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply tightness force - (causing ball position to be close to skeleton joint position)
|
// apply tightness force - (causing ball position to be close to skeleton joint position)
|
||||||
_bodyBall[b].velocity += (_skeleton.joint[b].position - _bodyBall[b].position) * _bodyBall[b].jointTightness * deltaTime;
|
glm::vec3 targetPosition
|
||||||
|
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||||
|
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||||
|
|
||||||
|
_bodyBall[b].velocity += (targetPosition - _bodyBall[b].position) * _bodyBall[b].jointTightness * deltaTime;
|
||||||
|
|
||||||
// apply decay
|
// apply decay
|
||||||
float decay = 1.0 - BODY_SPRING_DECAY * deltaTime;
|
float decay = 1.0 - BODY_SPRING_DECAY * deltaTime;
|
||||||
if (decay > 0.0) {
|
if (decay > 0.0) {
|
||||||
_bodyBall[b].velocity *= decay;
|
_bodyBall[b].velocity *= decay;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
_bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//apply forces from touch...
|
// apply forces from touch...
|
||||||
if (_skeleton.joint[b].touchForce > 0.0) {
|
if (_bodyBall[b].touchForce > 0.0) {
|
||||||
_skeleton.joint[b].springyVelocity += _mouseRayDirection * _skeleton.joint[b].touchForce * 0.7f;
|
_bodyBall[b].velocity += _mouseRayDirection * _bodyBall[b].touchForce * 0.7f;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//update position by velocity...
|
// update position by velocity...
|
||||||
_bodyBall[b].position += _bodyBall[b].velocity * deltaTime;
|
_bodyBall[b].position += _bodyBall[b].velocity * deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,8 +1127,8 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
const float RENDER_TRANSLUCENT_BEYOND = 0.5f;
|
const float RENDER_TRANSLUCENT_BEYOND = 0.5f;
|
||||||
|
|
||||||
// Render the body as balls and cones
|
// Render the body as balls and cones
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
float distanceToCamera = glm::length(_cameraPosition - _skeleton.joint[b].position);
|
float distanceToCamera = glm::length(_cameraPosition - _bodyBall[b].position);
|
||||||
|
|
||||||
float alpha = lookingInMirror ? 1.0f : glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) /
|
float alpha = lookingInMirror ? 1.0f : glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) /
|
||||||
(RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f);
|
(RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f);
|
||||||
|
@ -1021,18 +1138,18 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always render other people, and render myself when beyond threshold distance
|
// Always render other people, and render myself when beyond threshold distance
|
||||||
if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special
|
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
||||||
if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) {
|
if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) {
|
||||||
_head.render(lookingInMirror, _cameraPosition, alpha);
|
_head.render(lookingInMirror, _cameraPosition, alpha);
|
||||||
}
|
}
|
||||||
} else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND
|
} else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND
|
||||||
|| b == AVATAR_JOINT_RIGHT_ELBOW
|
|| b == BODY_BALL_RIGHT_ELBOW
|
||||||
|| b == AVATAR_JOINT_RIGHT_WRIST
|
|| b == BODY_BALL_RIGHT_WRIST
|
||||||
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
|| b == BODY_BALL_RIGHT_FINGERTIPS ) {
|
||||||
// Render the sphere at the joint
|
// Render the body ball sphere
|
||||||
if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW
|
if (_owningAgent || b == BODY_BALL_RIGHT_ELBOW
|
||||||
|| b == AVATAR_JOINT_RIGHT_WRIST
|
|| b == BODY_BALL_RIGHT_WRIST
|
||||||
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
|| b == BODY_BALL_RIGHT_FINGERTIPS ) {
|
||||||
glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f,
|
glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f,
|
||||||
SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f,
|
SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f,
|
||||||
SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f);
|
SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f);
|
||||||
|
@ -1043,36 +1160,36 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
alpha);
|
alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((b != AVATAR_JOINT_HEAD_TOP )
|
if ((b != BODY_BALL_HEAD_TOP )
|
||||||
&& (b != AVATAR_JOINT_HEAD_BASE )) {
|
&& (b != BODY_BALL_HEAD_BASE )) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_bodyBall[b].position.x, _bodyBall[b].position.y, _bodyBall[b].position.z);
|
glTranslatef(_bodyBall[b].position.x, _bodyBall[b].position.y, _bodyBall[b].position.z);
|
||||||
glutSolidSphere(_bodyBall[b].radius, 20.0f, 20.0f);
|
glutSolidSphere(_bodyBall[b].radius, 20.0f, 20.0f);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the cone connecting this joint to its parent
|
// Render the cone connecting this ball to its parent
|
||||||
if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) {
|
if (_bodyBall[b].parentBall != BODY_BALL_NULL) {
|
||||||
if ((b != AVATAR_JOINT_HEAD_TOP )
|
if ((b != BODY_BALL_HEAD_TOP )
|
||||||
&& (b != AVATAR_JOINT_HEAD_BASE )
|
&& (b != BODY_BALL_HEAD_BASE )
|
||||||
&& (b != AVATAR_JOINT_PELVIS )
|
&& (b != BODY_BALL_PELVIS )
|
||||||
&& (b != AVATAR_JOINT_TORSO )
|
&& (b != BODY_BALL_TORSO )
|
||||||
&& (b != AVATAR_JOINT_CHEST )
|
&& (b != BODY_BALL_CHEST )
|
||||||
&& (b != AVATAR_JOINT_LEFT_COLLAR )
|
&& (b != BODY_BALL_LEFT_COLLAR )
|
||||||
&& (b != AVATAR_JOINT_LEFT_SHOULDER )
|
&& (b != BODY_BALL_LEFT_SHOULDER )
|
||||||
&& (b != AVATAR_JOINT_RIGHT_COLLAR )
|
&& (b != BODY_BALL_RIGHT_COLLAR )
|
||||||
&& (b != AVATAR_JOINT_RIGHT_SHOULDER)) {
|
&& (b != BODY_BALL_RIGHT_SHOULDER)) {
|
||||||
glColor3fv(DARK_SKIN_COLOR);
|
glColor3fv(DARK_SKIN_COLOR);
|
||||||
|
|
||||||
float r1 = _bodyBall[_skeleton.joint[b].parent ].radius * 0.8;
|
float r1 = _bodyBall[_bodyBall[b].parentBall ].radius * 0.8;
|
||||||
float r2 = _bodyBall[b ].radius * 0.8;
|
float r2 = _bodyBall[b].radius * 0.8;
|
||||||
if (b == AVATAR_JOINT_HEAD_BASE) {
|
if (b == BODY_BALL_HEAD_BASE) {
|
||||||
r1 *= 0.5f;
|
r1 *= 0.5f;
|
||||||
}
|
}
|
||||||
renderJointConnectingCone
|
renderJointConnectingCone
|
||||||
(
|
(
|
||||||
_bodyBall[_skeleton.joint[b].parent ].position,
|
_bodyBall[_bodyBall[b].parentBall].position,
|
||||||
_bodyBall[b ].position, r2, r2
|
_bodyBall[b].position, r2, r2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1110,7 +1227,7 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity
|
||||||
_head.setYaw (angles.x);
|
_head.setYaw (angles.x);
|
||||||
_head.setPitch(angles.y);
|
_head.setPitch(angles.y);
|
||||||
_head.setRoll (angles.z);
|
_head.setRoll (angles.z);
|
||||||
//printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z);
|
// printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,40 @@
|
||||||
#include "Skeleton.h"
|
#include "Skeleton.h"
|
||||||
#include "Transmitter.h"
|
#include "Transmitter.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum AvatarBodyBallID
|
||||||
|
{
|
||||||
|
BODY_BALL_NULL = -1,
|
||||||
|
BODY_BALL_PELVIS,
|
||||||
|
BODY_BALL_TORSO,
|
||||||
|
BODY_BALL_CHEST,
|
||||||
|
BODY_BALL_NECK_BASE,
|
||||||
|
BODY_BALL_HEAD_BASE,
|
||||||
|
BODY_BALL_HEAD_TOP,
|
||||||
|
BODY_BALL_LEFT_COLLAR,
|
||||||
|
BODY_BALL_LEFT_SHOULDER,
|
||||||
|
BODY_BALL_LEFT_ELBOW,
|
||||||
|
BODY_BALL_LEFT_WRIST,
|
||||||
|
BODY_BALL_LEFT_FINGERTIPS,
|
||||||
|
BODY_BALL_RIGHT_COLLAR,
|
||||||
|
BODY_BALL_RIGHT_SHOULDER,
|
||||||
|
BODY_BALL_RIGHT_ELBOW,
|
||||||
|
BODY_BALL_RIGHT_WRIST,
|
||||||
|
BODY_BALL_RIGHT_FINGERTIPS,
|
||||||
|
BODY_BALL_LEFT_HIP,
|
||||||
|
BODY_BALL_LEFT_KNEE,
|
||||||
|
BODY_BALL_LEFT_HEEL,
|
||||||
|
BODY_BALL_LEFT_TOES,
|
||||||
|
BODY_BALL_RIGHT_HIP,
|
||||||
|
BODY_BALL_RIGHT_KNEE,
|
||||||
|
BODY_BALL_RIGHT_HEEL,
|
||||||
|
BODY_BALL_RIGHT_TOES,
|
||||||
|
|
||||||
|
//TEST!
|
||||||
|
//BODY_BALL_LEFT_MID_THIGH,
|
||||||
|
NUM_AVATAR_BODY_BALLS
|
||||||
|
};
|
||||||
|
|
||||||
enum DriveKeys
|
enum DriveKeys
|
||||||
{
|
{
|
||||||
FWD = 0,
|
FWD = 0,
|
||||||
|
@ -64,19 +98,14 @@ public:
|
||||||
void setOrientation (const glm::quat& orientation);
|
void setOrientation (const glm::quat& orientation);
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
|
float getHeadYawRate () const { return _head.yawRate;}
|
||||||
float getHeadYawRate () const { return _head.yawRate;}
|
float getBodyYaw () const { return _bodyYaw;}
|
||||||
float getBodyYaw () const { return _bodyYaw;}
|
bool getIsNearInteractingOther () const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
||||||
bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
const glm::vec3& getHeadJointPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;}
|
||||||
const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;}
|
const glm::vec3& getBallPosition (AvatarJointID j) const { return _bodyBall[j].position;}
|
||||||
const glm::vec3& getSpringyHeadPosition () const { return _bodyBall[ AVATAR_JOINT_HEAD_BASE ].position;}
|
glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; }
|
||||||
const glm::vec3& getJointPosition (AvatarJointID j) const { return _bodyBall[j].position;}
|
glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; }
|
||||||
|
glm::vec3 getBodyFrontDirection () const { return getOrientation() * AVATAR_FRONT; }
|
||||||
glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; }
|
|
||||||
glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; }
|
|
||||||
glm::vec3 getBodyFrontDirection () const { return getOrientation() * AVATAR_FRONT; }
|
|
||||||
|
|
||||||
|
|
||||||
const glm::vec3& getVelocity () const { return _velocity;}
|
const glm::vec3& getVelocity () const { return _velocity;}
|
||||||
float getSpeed () const { return _speed;}
|
float getSpeed () const { return _speed;}
|
||||||
float getHeight () const { return _height;}
|
float getHeight () const { return _height;}
|
||||||
|
@ -106,16 +135,21 @@ private:
|
||||||
|
|
||||||
struct AvatarBall
|
struct AvatarBall
|
||||||
{
|
{
|
||||||
glm::vec3 position;
|
AvatarJointID parentJoint; // the skeletal joint that serves as a reference for determining the position
|
||||||
glm::vec3 velocity;
|
glm::vec3 parentOffset; // a 3D vector in the frame of reference of the parent skeletal joint
|
||||||
float jointTightness;
|
AvatarBodyBallID parentBall; // the ball to which this ball is constrained for spring forces
|
||||||
float radius;
|
glm::vec3 position; // the actual dynamic position of the ball at any given time
|
||||||
bool isCollidable;
|
glm::vec3 velocity; // the velocity of the ball
|
||||||
float touchForce;
|
float springLength; // the ideal length of the spring between this ball and its parentBall
|
||||||
|
float jointTightness; // how tightly the ball position attempts to stay at its ideal position (determined by parentOffset)
|
||||||
|
float radius; // the radius of the ball
|
||||||
|
bool isCollidable; // whether or not the ball responds to collisions
|
||||||
|
float touchForce; // a scalar determining the amount that the cursor (or hand) is penetrating the ball
|
||||||
};
|
};
|
||||||
|
|
||||||
Head _head;
|
Head _head;
|
||||||
Skeleton _skeleton;
|
Skeleton _skeleton;
|
||||||
|
bool _ballSpringsInitialized;
|
||||||
float _TEST_bigSphereRadius;
|
float _TEST_bigSphereRadius;
|
||||||
glm::vec3 _TEST_bigSpherePosition;
|
glm::vec3 _TEST_bigSpherePosition;
|
||||||
bool _mousePressed;
|
bool _mousePressed;
|
||||||
|
@ -123,8 +157,7 @@ private:
|
||||||
float _bodyYawDelta;
|
float _bodyYawDelta;
|
||||||
float _bodyRollDelta;
|
float _bodyRollDelta;
|
||||||
glm::vec3 _movedHandOffset;
|
glm::vec3 _movedHandOffset;
|
||||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ];
|
||||||
AvatarBall _bodyBall[ NUM_AVATAR_JOINTS ];
|
|
||||||
AvatarMode _mode;
|
AvatarMode _mode;
|
||||||
glm::vec3 _cameraPosition;
|
glm::vec3 _cameraPosition;
|
||||||
glm::vec3 _handHoldingPosition;
|
glm::vec3 _handHoldingPosition;
|
||||||
|
|
|
@ -14,7 +14,7 @@ Skeleton::Skeleton() {
|
||||||
|
|
||||||
void Skeleton::initialize() {
|
void Skeleton::initialize() {
|
||||||
|
|
||||||
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||||
joint[b].parent = AVATAR_JOINT_NULL;
|
joint[b].parent = AVATAR_JOINT_NULL;
|
||||||
joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||||
joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0);
|
joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
@ -101,6 +101,7 @@ void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float Skeleton::getArmLength() {
|
float Skeleton::getArmLength() {
|
||||||
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
||||||
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
||||||
|
|
|
@ -55,14 +55,15 @@ public:
|
||||||
float getHeight();
|
float getHeight();
|
||||||
float getPelvisStandingHeight();
|
float getPelvisStandingHeight();
|
||||||
float getPelvisFloatingHeight();
|
float getPelvisFloatingHeight();
|
||||||
|
//glm::vec3 getJointVectorFromParent(AvatarJointID jointID) {return joint[jointID].position - joint[joint[jointID].parent].position; }
|
||||||
|
|
||||||
struct AvatarJoint
|
struct AvatarJoint
|
||||||
{
|
{
|
||||||
AvatarJointID parent; // which joint is this joint connected to?
|
AvatarJointID parent; // which joint is this joint connected to?
|
||||||
glm::vec3 position; // the position at the "end" of the joint - in global space
|
glm::vec3 position; // the position at the "end" of the joint - in global space
|
||||||
glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose"
|
glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the default pose
|
||||||
glm::quat rotation; // the parent-relative rotation (orientation) of the joint as a quaternion
|
glm::quat rotation; // the parent-relative rotation (orientation) of the joint as a quaternion
|
||||||
float length; // the length of vector connecting the joint and its parent
|
float length; // the length of vector between the joint and its parent
|
||||||
};
|
};
|
||||||
|
|
||||||
AvatarJoint joint[ NUM_AVATAR_JOINTS ];
|
AvatarJoint joint[ NUM_AVATAR_JOINTS ];
|
||||||
|
|
Loading…
Reference in a new issue