Added HandControl class and also Avatar Touch class

This commit is contained in:
Jeffrey Ventrella 2013-04-25 23:32:04 -07:00
parent 7a94310d4e
commit ce1ceb849f
7 changed files with 280 additions and 146 deletions

View file

@ -303,7 +303,7 @@ void Avatar::simulate(float deltaTime) {
// if the avatar being simulated is mine, then loop through
// all the other avatars for potential interactions...
if ( _isMine )
{
{
float closestDistance = 10000.0f;
AgentList * agentList = AgentList::getInstance();
@ -330,7 +330,7 @@ void Avatar::simulate(float deltaTime) {
float distance = glm::length( v );
if ( distance < _maxArmLength + _maxArmLength ) {
//if ( distance < closestDistance ) { // perhaps I don't need this if we want to allow multi-avatar interactions
{
closestDistance = distance;
@ -341,14 +341,18 @@ void Avatar::simulate(float deltaTime) {
if (( _handState == 1 ) || ( _interactingOther->_handState == 1 )) {
glm::vec3 vectorToOtherHand = _interactingOther->_handPosition - _handHolding.position;
glm::vec3 vectorToMyHand = _bone[ AVATAR_BONE_RIGHT_HAND ].position - _handHolding.position;
_handHolding.velocity *= 0.7;
_handHolding.velocity += ( vectorToOtherHand + vectorToMyHand ) * _handHolding.force * deltaTime;
_handHolding.position += _handHolding.velocity;
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _handHolding.position;
}
}
_avatarTouch.setMyHandPosition( _bone[ AVATAR_BONE_RIGHT_HAND ].position );
_avatarTouch.setYourPosition( otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND ) );
}
}
}
@ -356,9 +360,11 @@ void Avatar::simulate(float deltaTime) {
// Set the vector we send for hand position to other people to be our right hand
setHandPosition(_bone[ AVATAR_BONE_RIGHT_HAND ].position);
//update the effects of touching another avatar
_avatarTouch.simulate(deltaTime);
}//if ( _isMine )
updateArmIKAndConstraints( deltaTime );
if (!_interactingOtherIsNearby) {
@ -413,30 +419,14 @@ void Avatar::simulate(float deltaTime) {
_thrust = glm::vec3( 0.0, 0.0, 0.0 );
if (_driveKeys[FWD]) {
_thrust += _orientation.getFront() * THRUST_MAG;
}
if (_driveKeys[BACK]) {
_thrust -= _orientation.getFront() * THRUST_MAG;
}
if (_driveKeys[RIGHT]) {
_thrust += _orientation.getRight() * THRUST_MAG;
}
if (_driveKeys[LEFT]) {
_thrust -= _orientation.getRight() * THRUST_MAG;
}
if (_driveKeys[UP]) {
_thrust += _orientation.getUp() * THRUST_MAG;
}
if (_driveKeys[DOWN]) {
_thrust -= _orientation.getUp() * THRUST_MAG;
}
if (_driveKeys[ROT_RIGHT]) {
_bodyYawDelta -= YAW_MAG * deltaTime;
}
if (_driveKeys[ROT_LEFT]) {
_bodyYawDelta += YAW_MAG * deltaTime;
}
if (_driveKeys[FWD ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getFront();}
if (_driveKeys[BACK ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getFront();}
if (_driveKeys[RIGHT ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getRight();}
if (_driveKeys[LEFT ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getRight();}
if (_driveKeys[UP ]) {_thrust += THRUST_MAG * deltaTime * _orientation.getUp();}
if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG * deltaTime * _orientation.getUp();}
if (_driveKeys[ROT_RIGHT]) {_bodyYawDelta -= YAW_MAG * deltaTime;}
if (_driveKeys[ROT_LEFT ]) {_bodyYawDelta += YAW_MAG * deltaTime;}
}
// update body yaw by body yaw delta
@ -658,21 +648,12 @@ void Avatar::render(bool lookingInMirror) {
// if this is my avatar, then render my interactions with the other avatar
if ( _isMine )
{
if ( _interactingOtherIsNearby ) {
glm::vec3 v1( _bone[ AVATAR_BONE_RIGHT_HAND ].position );
glm::vec3 v2( _interactingOther->_handPosition );
glLineWidth( 8.0 );
glColor4f( 0.7f, 0.4f, 0.1f, 0.6 );
glBegin( GL_LINE_STRIP );
glVertex3f( v1.x, v1.y, v1.z );
glVertex3f( v2.x, v2.y, v2.z );
glEnd();
_avatarTouch.render();
}
}
}
void Avatar::renderHead(bool lookingInMirror) {
int side = 0;
@ -835,7 +816,7 @@ void Avatar::renderHead(bool lookingInMirror) {
glPopMatrix();
}
void Avatar::startHandMovement() {
if (!_usingBodySprings) {

View file

@ -14,6 +14,7 @@
#include "Field.h"
#include "world.h"
#include "AvatarTouch.h"
#include "InterfaceConfig.h"
#include "SerialInterface.h"
@ -24,7 +25,7 @@
const bool AVATAR_GRAVITY = true;
const float DECAY = 0.1;
const float THRUST_MAG = 10.0;
const float THRUST_MAG = 1200.0;
const float YAW_MAG = 500.0; //JJV - changed from 300.0;
const float TEST_YAW_DECAY = 5.0;
const float LIN_VEL_DECAY = 5.0;
@ -46,6 +47,8 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
enum AvatarMode
{
AVATAR_MODE_STANDING = 0,
@ -84,6 +87,16 @@ enum AvatarBoneID
NUM_AVATAR_BONES
};
/*
static glm::vec3 avatarDefaultPose[NUM_AVATAR_BONES] =
{
glm::vec3( 0.0f, 0.0f, 0.0f ),
glm::vec3( 0.0f, 0.0f, 0.0f )
};
*/
struct AvatarCollisionElipsoid
{
bool colliding;
@ -252,6 +265,7 @@ class Avatar : public AvatarData {
Avatar* _interactingOther;
bool _interactingOtherIsNearby;
float _pelvisStandingHeight;
AvatarTouch _avatarTouch;
// private methods...
void initializeSkeleton();

View file

@ -0,0 +1,43 @@
//
// AvatarTouch.cpp
// interface
//
// Created by Jeffrey Ventrella
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#include <iostream>
#include <glm/glm.hpp>
#include "AvatarTouch.h"
#include "InterfaceConfig.h"
AvatarTouch::AvatarTouch() {
_myHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
_yourHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
}
void AvatarTouch::setMyHandPosition( glm::vec3 position ) {
_myHandPosition = position;
}
void AvatarTouch::setYourPosition( glm::vec3 position ) {
_yourHandPosition = position;
}
void AvatarTouch::render() {
glm::vec3 v1( _myHandPosition );
glm::vec3 v2( _yourHandPosition );
glLineWidth( 8.0 );
glColor4f( 0.7f, 0.4f, 0.1f, 0.6 );
glBegin( GL_LINE_STRIP );
glVertex3f( v1.x, v1.y, v1.z );
glVertex3f( v2.x, v2.y, v2.z );
glEnd();
}
void AvatarTouch::simulate (float deltaTime) {
}

View file

@ -0,0 +1,28 @@
//
// AvatarTouch.h
// interface
//
// Created by Jeffrey Ventrella
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__AvatarTouch__
#define __interface__AvatarTouch__
#include <glm/glm.hpp>
class AvatarTouch {
public:
AvatarTouch();
void setMyHandPosition( glm::vec3 position );
void setYourPosition ( glm::vec3 position );
void simulate(float deltaTime);
void render();
private:
glm::vec3 _myHandPosition;
glm::vec3 _yourHandPosition;
};
#endif

View file

@ -0,0 +1,93 @@
//
// HandControl.cpp
// interface
//
// Created by Jeffrey Ventrella
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "HandControl.h"
// this class takes mouse movements normalized within the screen
// dimensions and uses those to determine avatar hand movements, as well
// as states for ramping up and ramping down the amplitude of such movements.
//
// This class might expand to accommodate 3D input devices
//
HandControl::HandControl() {
_enabled = false;
_width = 0;
_height = 0;
_startX = 0;
_startY = 0;
_x = 0;
_y = 0;
_lastX = 0;
_lastY = 0;
_velocityX = 0;
_velocityY = 0;
_rampUpRate = 0.05;
_rampDownRate = 0.02;
_envelope = 0.0f;
}
void HandControl::setScreenDimensions( int width, int height ) {
_width = width;
_height = height;
_startX = _width / 2;
_startY = _height / 2;
}
void HandControl::update( int x, int y ) {
_lastX = _x;
_lastY = _y;
_x = x;
_y = y;
_velocityX = _x - _lastX;
_velocityY = _y - _lastY;
// if the mouse is moving, ramp up the envelope to increase amplitude of hand movement...
if (( _velocityX != 0 )
|| ( _velocityY != 0 )) {
_enabled = true;
if ( _envelope < 1.0 ) {
_envelope += _rampUpRate;
if ( _envelope >= 1.0 ) {
_envelope = 1.0;
}
}
}
// if not enabled ramp down the envelope to decrease amplitude of hand movement...
if ( ! _enabled ) {
if ( _envelope > 0.0 ) {
_envelope -= _rampDownRate;
if ( _envelope <= 0.0 ) {
_startX = _width / 2;
_startY = _height / 2;
_envelope = 0.0;
}
}
}
_leftRight = 0.0;
_downUp = 0.0;
_backFront = 0.0;
// if envelope is greater than zero, apply mouse movement to values to be output
if ( _envelope > 0.0 ) {
_leftRight += ( ( _x - _startX ) / (float)_width ) * _envelope;
_downUp += ( ( _y - _startY ) / (float)_height ) * _envelope;
}
}
glm::vec3 HandControl::getValues() {
return glm::vec3( _leftRight, _downUp, _backFront );
}
void HandControl::stop() {
_enabled = false;
}

View file

@ -0,0 +1,42 @@
//
// HandControl.h
// interface
//
// Created by Jeffrey Ventrella
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__HandControl__
#define __interface__HandControl__
#include <glm/glm.hpp>
class HandControl {
public:
HandControl();
void setScreenDimensions(int width, int height);
void update( int x, int y );
glm::vec3 getValues();
void stop();
private:
bool _enabled;
int _width;
int _height;
int _startX;
int _startY;
int _x;
int _y;
int _lastX;
int _lastY;
int _velocityX;
int _velocityY;
float _rampUpRate;
float _rampDownRate;
float _envelope;
float _leftRight;
float _downUp;
float _backFront;
};
#endif

View file

@ -81,6 +81,7 @@
#include <SimpleMovingAverage.h>
#include "ViewFrustum.h"
#include "HandControl.h"
using namespace std;
@ -101,6 +102,8 @@ int HEIGHT = 800;
int fullscreen = 0;
float aspectRatio = 1.0f;
bool USING_FIRST_PERSON_EFFECT = false;
bool wantColorRandomizer = true; // for addSphere and load file
Oscilloscope audioScope(256,200,true);
@ -171,6 +174,8 @@ int displayField = 0;
int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement
int headMouseX, headMouseY;
HandControl handControl;
int mouseX = 0;
int mouseY = 0;
@ -180,80 +185,6 @@ int mousePressed = 0; // true if mouse has been pressed (clear when finished)
Menu menu; // main menu
int menuOn = 1; // Whether to show onscreen menu
struct HandController
{
bool enabled;
int startX;
int startY;
int x;
int y;
int lastX;
int lastY;
int velocityX;
int velocityY;
float rampUpRate;
float rampDownRate;
float envelope;
};
HandController handController;
void initializeHandController() {
handController.enabled = false;
handController.startX = WIDTH / 2;
handController.startY = HEIGHT / 2;
handController.x = 0;
handController.y = 0;
handController.lastX = 0;
handController.lastY = 0;
handController.velocityX = 0;
handController.velocityY = 0;
handController.rampUpRate = 0.05;
handController.rampDownRate = 0.02;
handController.envelope = 0.0f;
}
void updateHandController( int x, int y ) {
handController.lastX = handController.x;
handController.lastY = handController.y;
handController.x = x;
handController.y = y;
handController.velocityX = handController.x - handController.lastX;
handController.velocityY = handController.y - handController.lastY;
if (( handController.velocityX != 0 )
|| ( handController.velocityY != 0 )) {
handController.enabled = true;
myAvatar.startHandMovement();
if ( handController.envelope < 1.0 ) {
handController.envelope += handController.rampUpRate;
if ( handController.envelope >= 1.0 ) {
handController.envelope = 1.0;
}
}
}
if ( ! handController.enabled ) {
if ( handController.envelope > 0.0 ) {
handController.envelope -= handController.rampDownRate;
if ( handController.envelope <= 0.0 ) {
handController.startX = WIDTH / 2;
handController.startY = HEIGHT / 2;
handController.envelope = 0.0;
}
}
}
if ( handController.envelope > 0.0 ) {
float leftRight = ( ( handController.x - handController.startX ) / (float)WIDTH ) * handController.envelope;
float downUp = ( ( handController.y - handController.startY ) / (float)HEIGHT ) * handController.envelope;
float backFront = 0.0;
myAvatar.setHandMovementValues( glm::vec3( leftRight, downUp, backFront ) );
}
}
//
// Serial USB Variables
//
@ -385,7 +316,7 @@ void init(void)
voxels.setViewerAvatar(&myAvatar);
myAvatar.setRenderYaw(startYaw);
initializeHandController();
handControl.setScreenDimensions(WIDTH, HEIGHT);
headMouseX = WIDTH/2;
headMouseY = HEIGHT/2;
@ -820,37 +751,38 @@ void display(void)
float thirdPersonDistance = 1.f;
float thirdPersonTightness = 8.0f;
myCamera.setPitch (thirdPersonPitch );
myCamera.setUpShift (thirdPersonUpShift );
myCamera.setDistance (thirdPersonDistance );
myCamera.setTightness(thirdPersonTightness);
/*
if ( myAvatar.getSpeed() < 0.02 ) {
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
}
if ( USING_FIRST_PERSON_EFFECT ) {
if ( myAvatar.getSpeed() < 0.02 ) {
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
}
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
myCamera.setPitch ( thirdPersonPitch + myCamera.getModeShift() * ( firstPersonPitch - thirdPersonPitch ));
myCamera.setUpShift ( thirdPersonUpShift + myCamera.getModeShift() * ( firstPersonUpShift - thirdPersonUpShift ));
myCamera.setDistance ( thirdPersonDistance + myCamera.getModeShift() * ( firstPersonDistance - thirdPersonDistance ));
myCamera.setTightness ( thirdPersonTightness + myCamera.getModeShift() * ( firstPersonTightness - thirdPersonTightness ));
} else {
if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON ) {
myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
myCamera.setPitch ( thirdPersonPitch + myCamera.getModeShift() * ( firstPersonPitch - thirdPersonPitch ));
myCamera.setUpShift ( thirdPersonUpShift + myCamera.getModeShift() * ( firstPersonUpShift - thirdPersonUpShift ));
myCamera.setDistance ( thirdPersonDistance + myCamera.getModeShift() * ( firstPersonDistance - thirdPersonDistance ));
myCamera.setTightness ( thirdPersonTightness + myCamera.getModeShift() * ( firstPersonTightness - thirdPersonTightness ));
} else {
if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON ) {
myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
}
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
myCamera.setPitch ( firstPersonPitch + myCamera.getModeShift() * ( thirdPersonPitch - firstPersonPitch ));
myCamera.setUpShift ( firstPersonUpShift + myCamera.getModeShift() * ( thirdPersonUpShift - firstPersonUpShift ));
myCamera.setDistance ( firstPersonDistance + myCamera.getModeShift() * ( thirdPersonDistance - firstPersonDistance ));
myCamera.setTightness ( firstPersonTightness + myCamera.getModeShift() * ( thirdPersonTightness - firstPersonTightness ));
}
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
myCamera.setPitch ( firstPersonPitch + myCamera.getModeShift() * ( thirdPersonPitch - firstPersonPitch ));
myCamera.setUpShift ( firstPersonUpShift + myCamera.getModeShift() * ( thirdPersonUpShift - firstPersonUpShift ));
myCamera.setDistance ( firstPersonDistance + myCamera.getModeShift() * ( thirdPersonDistance - firstPersonDistance ));
myCamera.setTightness ( firstPersonTightness + myCamera.getModeShift() * ( thirdPersonTightness - firstPersonTightness ));
} else {
myCamera.setPitch (thirdPersonPitch );
myCamera.setUpShift (thirdPersonUpShift );
myCamera.setDistance (thirdPersonDistance );
myCamera.setTightness(thirdPersonTightness);
}
*/
myCamera.setTargetPosition( myAvatar.getHeadPosition() );
myCamera.setTargetYaw ( 180.0 - myAvatar.getBodyYaw() );
myCamera.setRoll ( 0.0 );
@ -1503,7 +1435,8 @@ void idle(void) {
float deltaTime = 1.f/FPS;
// update behaviors for avatar hand movement
updateHandController( mouseX, mouseY );
handControl.update( mouseX, mouseY );
myAvatar.setHandMovementValues( handControl.getValues() );
// tell my avatar if the mouse is being pressed...
if ( mousePressed == 1 ) {
@ -1513,9 +1446,9 @@ void idle(void) {
myAvatar.setMousePressed( false );
}
// walking triggers the handController to stop
// walking triggers the handControl to stop
if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) {
handController.enabled = false;
handControl.stop();
}
//