mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 00:54:26 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into voxel_animation
This commit is contained in:
commit
1a2921e3e8
22 changed files with 437 additions and 116 deletions
|
@ -167,7 +167,8 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
float minCoefficient = std::min(1.0f,
|
float minCoefficient = std::min(1.0f,
|
||||||
powf(0.5,
|
powf(0.5,
|
||||||
(logf(DISTANCE_RATIO * distanceToAgent) / logf(2)) - 1));
|
(logf(DISTANCE_RATIO * distanceToAgent) / logf(2.5))
|
||||||
|
- 1));
|
||||||
distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient;
|
distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *
|
||||||
|
|
||||||
void attachAvatarDataToAgent(Agent* newAgent) {
|
void attachAvatarDataToAgent(Agent* newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new AvatarData());
|
newAgent->setLinkedData(new AvatarData(newAgent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ void *receiveAgentData(void *args) {
|
||||||
|
|
||||||
void createAvatarDataForAgent(Agent* agent) {
|
void createAvatarDataForAgent(Agent* agent) {
|
||||||
if (!agent->getLinkedData()) {
|
if (!agent->getLinkedData()) {
|
||||||
agent->setLinkedData(new AvatarData());
|
agent->setLinkedData(new AvatarData(agent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include <AgentTypes.h>
|
#include <AgentTypes.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
#include <AudioInjectionManager.h>
|
||||||
|
#include <AudioInjector.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
|
@ -128,7 +130,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_viewFrustumOffsetDistance(25.0),
|
_viewFrustumOffsetDistance(25.0),
|
||||||
_viewFrustumOffsetUp(0.0),
|
_viewFrustumOffsetUp(0.0),
|
||||||
_audioScope(256, 200, true),
|
_audioScope(256, 200, true),
|
||||||
_myAvatar(true),
|
|
||||||
_manualFirstPerson(false),
|
_manualFirstPerson(false),
|
||||||
_mouseX(0),
|
_mouseX(0),
|
||||||
_mouseY(0),
|
_mouseY(0),
|
||||||
|
@ -352,9 +353,8 @@ void Application::paintGL() {
|
||||||
whichCamera = _viewFrustumOffsetCamera;
|
whichCamera = _viewFrustumOffsetCamera;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_oculusOn->isChecked()) {
|
if (OculusManager::isConnected()) {
|
||||||
displayOculus(whichCamera);
|
displayOculus(whichCamera);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -377,7 +377,7 @@ void Application::resizeGL(int width, int height) {
|
||||||
float farClip = camera.getFarClip();
|
float farClip = camera.getFarClip();
|
||||||
float fov;
|
float fov;
|
||||||
|
|
||||||
if (_oculusOn->isChecked()) {
|
if (OculusManager::isConnected()) {
|
||||||
// more magic numbers; see Oculus SDK docs, p. 32
|
// more magic numbers; see Oculus SDK docs, p. 32
|
||||||
camera.setAspectRatio(aspectRatio *= 0.5);
|
camera.setAspectRatio(aspectRatio *= 0.5);
|
||||||
camera.setFieldOfView(fov = 2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PI));
|
camera.setFieldOfView(fov = 2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PI));
|
||||||
|
@ -884,7 +884,7 @@ void Application::idle() {
|
||||||
|
|
||||||
// Read serial port interface devices
|
// Read serial port interface devices
|
||||||
if (_serialPort.active) {
|
if (_serialPort.active) {
|
||||||
_serialPort.readData();
|
_serialPort.readData(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sample hardware, update view frustum if needed, and send avatar data to mixer/agents
|
// Sample hardware, update view frustum if needed, and send avatar data to mixer/agents
|
||||||
|
@ -1009,11 +1009,6 @@ void Application::setRenderFirstPerson(bool firstPerson) {
|
||||||
_manualFirstPerson = firstPerson;
|
_manualFirstPerson = firstPerson;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setOculus(bool oculus) {
|
|
||||||
resizeGL(_glWidget->width(), _glWidget->height());
|
|
||||||
updateCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::setFrustumOffset(bool frustumOffset) {
|
void Application::setFrustumOffset(bool frustumOffset) {
|
||||||
// reshape so that OpenGL will get the right lens details for the camera of choice
|
// reshape so that OpenGL will get the right lens details for the camera of choice
|
||||||
resizeGL(_glWidget->width(), _glWidget->height());
|
resizeGL(_glWidget->width(), _glWidget->height());
|
||||||
|
@ -1164,7 +1159,7 @@ void Application::initMenu() {
|
||||||
(_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true);
|
(_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true);
|
||||||
_transmitterDrives->setChecked(true);
|
_transmitterDrives->setChecked(true);
|
||||||
|
|
||||||
optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F)->setCheckable(true);
|
(_fullScreenMode = optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F))->setCheckable(true);
|
||||||
|
|
||||||
QMenu* renderMenu = menuBar->addMenu("Render");
|
QMenu* renderMenu = menuBar->addMenu("Render");
|
||||||
(_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true);
|
(_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true);
|
||||||
|
@ -1186,8 +1181,6 @@ void Application::initMenu() {
|
||||||
|
|
||||||
renderMenu->addAction("First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P)->setCheckable(true);
|
renderMenu->addAction("First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P)->setCheckable(true);
|
||||||
|
|
||||||
(_oculusOn = renderMenu->addAction("Oculus", this, SLOT(setOculus(bool)), Qt::Key_O))->setCheckable(true);
|
|
||||||
|
|
||||||
QMenu* toolsMenu = menuBar->addMenu("Tools");
|
QMenu* toolsMenu = menuBar->addMenu("Tools");
|
||||||
|
|
||||||
(_renderStatsOn = toolsMenu->addAction("Stats"))->setCheckable(true);
|
(_renderStatsOn = toolsMenu->addAction("Stats"))->setCheckable(true);
|
||||||
|
@ -1302,6 +1295,9 @@ void Application::init() {
|
||||||
QCursor::setPos(_headMouseX, _headMouseY);
|
QCursor::setPos(_headMouseX, _headMouseY);
|
||||||
|
|
||||||
OculusManager::connect();
|
OculusManager::connect();
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
QMetaObject::invokeMethod(_fullScreenMode, "trigger", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
gettimeofday(&_timerStart, NULL);
|
gettimeofday(&_timerStart, NULL);
|
||||||
gettimeofday(&_lastTimeIdle, NULL);
|
gettimeofday(&_lastTimeIdle, NULL);
|
||||||
|
@ -1673,7 +1669,8 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
//draw a grid ground plane....
|
//draw a grid ground plane....
|
||||||
drawGroundPlaneGrid(10.f);
|
const float EDGE_SIZE_GROUND_PLANE = 20.f;
|
||||||
|
drawGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE);
|
||||||
|
|
||||||
// Draw voxels
|
// Draw voxels
|
||||||
if (_renderVoxels->isChecked()) {
|
if (_renderVoxels->isChecked()) {
|
||||||
|
@ -1708,13 +1705,13 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
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) {
|
||||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||||
avatar->render(false);
|
avatar->render(false, _myCamera.getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
agentList->unlock();
|
agentList->unlock();
|
||||||
|
|
||||||
// Render my own Avatar
|
// Render my own Avatar
|
||||||
_myAvatar.render(_lookingInMirror->isChecked());
|
_myAvatar.render(_lookingInMirror->isChecked(), _myCamera.getPosition());
|
||||||
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
|
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2018,6 +2015,7 @@ void Application::shiftPaintingColor() {
|
||||||
_paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
|
_paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::maybeEditVoxelUnderCursor() {
|
void Application::maybeEditVoxelUnderCursor() {
|
||||||
if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) {
|
if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) {
|
||||||
if (_mouseVoxel.s != 0) {
|
if (_mouseVoxel.s != 0) {
|
||||||
|
@ -2031,6 +2029,60 @@ void Application::maybeEditVoxelUnderCursor() {
|
||||||
|
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_justEditedVoxel = true;
|
_justEditedVoxel = true;
|
||||||
|
|
||||||
|
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025);
|
||||||
|
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||||
|
//_myAvatar.getPosition()
|
||||||
|
voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
|
||||||
|
voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value
|
||||||
|
// printf("mousevoxelscale is %f\n", _mouseVoxel.s);
|
||||||
|
|
||||||
|
/* for (int i = 0; i
|
||||||
|
< 22050; i++) {
|
||||||
|
if (i % 4 == 0) {
|
||||||
|
voxelInjector->addSample(4000);
|
||||||
|
} else if (i % 4 == 1) {
|
||||||
|
voxelInjector->addSample(0);
|
||||||
|
} else if (i % 4 == 2) {
|
||||||
|
voxelInjector->addSample(-4000);
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(0);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
const float BIG_VOXEL_MIN_SIZE = .01f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 11025; i++) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
A440 square wave
|
||||||
|
if (sin(i * 2 * PIE / 50)>=0) {
|
||||||
|
voxelInjector->addSample(4000);
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(-4000);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) {
|
||||||
|
voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200))));
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80
|
||||||
|
//voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808
|
||||||
|
//voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808
|
||||||
|
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave
|
||||||
|
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation
|
||||||
|
|
||||||
|
//FM library
|
||||||
|
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep
|
||||||
|
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep
|
||||||
|
//voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse
|
||||||
|
|
||||||
|
AudioInjectionManager::threadInjector(voxelInjector);
|
||||||
}
|
}
|
||||||
} else if (_deleteVoxelMode->isChecked()) {
|
} else if (_deleteVoxelMode->isChecked()) {
|
||||||
deleteVoxelUnderCursor();
|
deleteVoxelUnderCursor();
|
||||||
|
@ -2041,11 +2093,22 @@ void Application::deleteVoxelUnderCursor() {
|
||||||
if (_mouseVoxel.s != 0) {
|
if (_mouseVoxel.s != 0) {
|
||||||
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
||||||
sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel);
|
sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel);
|
||||||
|
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000);
|
||||||
|
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||||
|
voxelInjector->setBearing(0); //straight down the z axis
|
||||||
|
voxelInjector->setVolume (255); //255 is max, and also default value
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 5000; i++) {
|
||||||
|
voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse
|
||||||
|
// voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioInjectionManager::threadInjector(voxelInjector);
|
||||||
|
}
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_justEditedVoxel = true;
|
_justEditedVoxel = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Application::goHome() {
|
void Application::goHome() {
|
||||||
_myAvatar.setPosition(START_LOCATION);
|
_myAvatar.setPosition(START_LOCATION);
|
||||||
|
@ -2083,7 +2146,7 @@ void Application::setMenuShortcutsEnabled(bool enabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateCursor() {
|
void Application::updateCursor() {
|
||||||
_glWidget->setCursor(_oculusOn->isChecked() && _window->windowState().testFlag(Qt::WindowFullScreen) ?
|
_glWidget->setCursor(OculusManager::isConnected() && _window->windowState().testFlag(Qt::WindowFullScreen) ?
|
||||||
Qt::BlankCursor : Qt::ArrowCursor);
|
Qt::BlankCursor : Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2100,7 +2163,7 @@ QAction* Application::checkedVoxelModeAction() const {
|
||||||
|
|
||||||
void Application::attachNewHeadToAgent(Agent* newAgent) {
|
void Application::attachNewHeadToAgent(Agent* newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new Avatar(false));
|
newAgent->setLinkedData(new Avatar(newAgent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,6 @@ private slots:
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
|
||||||
void setRenderFirstPerson(bool firstPerson);
|
void setRenderFirstPerson(bool firstPerson);
|
||||||
void setOculus(bool oculus);
|
|
||||||
|
|
||||||
void setFrustumOffset(bool frustumOffset);
|
void setFrustumOffset(bool frustumOffset);
|
||||||
void cycleFrustumRenderMode();
|
void cycleFrustumRenderMode();
|
||||||
|
@ -148,7 +147,6 @@ private:
|
||||||
QAction* _renderStarsOn; // Whether to display the stars
|
QAction* _renderStarsOn; // Whether to display the stars
|
||||||
QAction* _renderAtmosphereOn; // Whether to display the atmosphere
|
QAction* _renderAtmosphereOn; // Whether to display the atmosphere
|
||||||
QAction* _renderAvatarsOn; // Whether to render avatars
|
QAction* _renderAvatarsOn; // Whether to render avatars
|
||||||
QAction* _oculusOn; // Whether to configure the display for the Oculus Rift
|
|
||||||
QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats
|
QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats
|
||||||
QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats
|
QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats
|
||||||
QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something
|
QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something
|
||||||
|
@ -162,6 +160,7 @@ private:
|
||||||
QAction* _frustumOn; // Whether or not to display the debug view frustum
|
QAction* _frustumOn; // Whether or not to display the debug view frustum
|
||||||
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
|
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
|
||||||
QAction* _cameraFrustum; // which frustum to look at
|
QAction* _cameraFrustum; // which frustum to look at
|
||||||
|
QAction* _fullScreenMode; // whether we are in full screen mode
|
||||||
QAction* _frustumRenderModeAction;
|
QAction* _frustumRenderModeAction;
|
||||||
|
|
||||||
SerialInterface _serialPort;
|
SerialInterface _serialPort;
|
||||||
|
|
|
@ -67,10 +67,11 @@ float lightBlue [] = {0.7, 0.8, 1.0 };
|
||||||
bool usingBigSphereCollisionTest = true;
|
bool usingBigSphereCollisionTest = true;
|
||||||
|
|
||||||
float chatMessageScale = 0.0015;
|
float chatMessageScale = 0.0015;
|
||||||
float chatMessageHeight = 0.10;
|
float chatMessageHeight = 0.20;
|
||||||
|
|
||||||
Avatar::Avatar(bool isMine) :
|
Avatar::Avatar(Agent* owningAgent) :
|
||||||
_isMine(isMine),
|
AvatarData(owningAgent),
|
||||||
|
_head(this),
|
||||||
_TEST_bigSphereRadius(0.4f),
|
_TEST_bigSphereRadius(0.4f),
|
||||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||||
_mousePressed(false),
|
_mousePressed(false),
|
||||||
|
@ -79,6 +80,7 @@ Avatar::Avatar(bool isMine) :
|
||||||
_bodyRollDelta(0.0f),
|
_bodyRollDelta(0.0f),
|
||||||
_movedHandOffset(0.0f, 0.0f, 0.0f),
|
_movedHandOffset(0.0f, 0.0f, 0.0f),
|
||||||
_rotation(0.0f, 0.0f, 0.0f, 0.0f),
|
_rotation(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
_cameraPosition(0.0f, 0.0f, 0.0f),
|
||||||
_mode(AVATAR_MODE_STANDING),
|
_mode(AVATAR_MODE_STANDING),
|
||||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||||
_velocity(0.0f, 0.0f, 0.0f),
|
_velocity(0.0f, 0.0f, 0.0f),
|
||||||
|
@ -229,7 +231,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
updateSkeleton();
|
updateSkeleton();
|
||||||
|
|
||||||
//detect and respond to collisions with other avatars...
|
//detect and respond to collisions with other avatars...
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
updateAvatarCollisions(deltaTime);
|
updateAvatarCollisions(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +241,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
_avatarTouch.simulate(deltaTime);
|
_avatarTouch.simulate(deltaTime);
|
||||||
|
|
||||||
// apply gravity and collision with the ground/floor
|
// apply gravity and collision with the ground/floor
|
||||||
if (_isMine && USING_AVATAR_GRAVITY) {
|
if (!_owningAgent && USING_AVATAR_GRAVITY) {
|
||||||
_velocity += _gravity * (GRAVITY_SCALE * deltaTime);
|
_velocity += _gravity * (GRAVITY_SCALE * deltaTime);
|
||||||
|
|
||||||
updateCollisionWithEnvironment();
|
updateCollisionWithEnvironment();
|
||||||
|
@ -254,12 +256,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// collision response with voxels
|
// collision response with voxels
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
updateCollisionWithVoxels();
|
updateCollisionWithVoxels();
|
||||||
}
|
}
|
||||||
|
|
||||||
// driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely)
|
// driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely)
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
|
|
||||||
_thrust = glm::vec3(0.0f, 0.0f, 0.0f);
|
_thrust = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
@ -304,7 +306,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update body yaw by body yaw delta
|
// update body yaw by body yaw delta
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
_bodyPitch += _bodyPitchDelta * deltaTime;
|
_bodyPitch += _bodyPitchDelta * deltaTime;
|
||||||
_bodyYaw += _bodyYawDelta * deltaTime;
|
_bodyYaw += _bodyYawDelta * deltaTime;
|
||||||
_bodyRoll += _bodyRollDelta * deltaTime;
|
_bodyRoll += _bodyRollDelta * deltaTime;
|
||||||
|
@ -365,7 +367,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If another avatar is near, dampen velocity as a function of closeness
|
// If another avatar is near, dampen velocity as a function of closeness
|
||||||
if (_isMine && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) {
|
if (!_owningAgent && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) {
|
||||||
float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS);
|
float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS);
|
||||||
float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime;
|
float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime;
|
||||||
if ( drag > 0.0f ) {
|
if ( drag > 0.0f ) {
|
||||||
|
@ -414,7 +416,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set head lookat position
|
// set head lookat position
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
if (_interactingOther) {
|
if (_interactingOther) {
|
||||||
_head.setLookAtPosition(_interactingOther->caclulateAverageEyePosition());
|
_head.setLookAtPosition(_interactingOther->caclulateAverageEyePosition());
|
||||||
} else {
|
} else {
|
||||||
|
@ -427,7 +429,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
_head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius);
|
_head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius);
|
||||||
_head.setAudioLoudness(_audioLoudness);
|
_head.setAudioLoudness(_audioLoudness);
|
||||||
_head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2]));
|
_head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2]));
|
||||||
_head.simulate(deltaTime, _isMine);
|
_head.simulate(deltaTime, !_owningAgent);
|
||||||
|
|
||||||
// use speed and angular velocity to determine walking vs. standing
|
// use speed and angular velocity to determine walking vs. standing
|
||||||
if (_speed + fabs(_bodyYawDelta) > 0.2) {
|
if (_speed + fabs(_bodyYawDelta) > 0.2) {
|
||||||
|
@ -466,7 +468,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
|
|
||||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement;
|
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement;
|
||||||
|
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
_avatarTouch.setMyBodyPosition(_position);
|
_avatarTouch.setMyBodyPosition(_position);
|
||||||
|
|
||||||
float closestDistance = std::numeric_limits<float>::max();
|
float closestDistance = std::numeric_limits<float>::max();
|
||||||
|
@ -558,7 +560,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
updateArmIKAndConstraints(deltaTime);
|
updateArmIKAndConstraints(deltaTime);
|
||||||
|
|
||||||
//Set right hand position and state to be transmitted, and also tell AvatarTouch about it
|
//Set right hand position and state to be transmitted, and also tell AvatarTouch about it
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
|
||||||
|
|
||||||
if (_mousePressed) {
|
if (_mousePressed) {
|
||||||
|
@ -725,9 +727,11 @@ void Avatar::setGravity(glm::vec3 gravity) {
|
||||||
_head.setGravity(_gravity);
|
_head.setGravity(_gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::render(bool lookingInMirror) {
|
void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||||
|
|
||||||
if (_isMine && usingBigSphereCollisionTest) {
|
_cameraPosition = cameraPosition;
|
||||||
|
|
||||||
|
if (!_owningAgent && usingBigSphereCollisionTest) {
|
||||||
// show TEST big sphere
|
// show TEST big sphere
|
||||||
glColor4f(0.5f, 0.6f, 0.8f, 0.7);
|
glColor4f(0.5f, 0.6f, 0.8f, 0.7);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -744,7 +748,7 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
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
|
||||||
if (_isMine) {
|
if (!_owningAgent) {
|
||||||
_avatarTouch.render(getCameraPosition());
|
_avatarTouch.render(getCameraPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,6 +841,8 @@ void Avatar::initializeSkeleton() {
|
||||||
_joint[ AVATAR_JOINT_RIGHT_COLLAR ].parent = AVATAR_JOINT_CHEST;
|
_joint[ AVATAR_JOINT_RIGHT_COLLAR ].parent = AVATAR_JOINT_CHEST;
|
||||||
_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR;
|
_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR;
|
||||||
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].parent = AVATAR_JOINT_RIGHT_SHOULDER;
|
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].parent = AVATAR_JOINT_RIGHT_SHOULDER;
|
||||||
|
_joint[ AVATAR_JOINT_RIGHT_WRIST ].parent = AVATAR_JOINT_RIGHT_ELBOW;
|
||||||
|
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].parent = AVATAR_JOINT_RIGHT_WRIST;
|
||||||
_joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS;
|
_joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS;
|
||||||
_joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP;
|
_joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP;
|
||||||
_joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE;
|
_joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE;
|
||||||
|
@ -999,7 +1005,7 @@ void Avatar::updateSkeleton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (! _isMine) {
|
if (_owningAgent) {
|
||||||
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,15 +1138,20 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
|
|
||||||
// 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_JOINTS; b++) {
|
||||||
float distanceToCamera = glm::length(getCameraPosition() - _joint[b].position);
|
float distanceToCamera = glm::length(_cameraPosition - _joint[b].position);
|
||||||
// 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 case
|
if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case
|
||||||
if (lookingInMirror || !_isMine || distanceToCamera > RENDER_OPAQUE_BEYOND) {
|
if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) {
|
||||||
_head.render(lookingInMirror);
|
_head.render(lookingInMirror, _cameraPosition);
|
||||||
}
|
}
|
||||||
} else if (!_isMine || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) {
|
} else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND
|
||||||
|
|| b == AVATAR_JOINT_RIGHT_ELBOW
|
||||||
|
|| b == AVATAR_JOINT_RIGHT_WRIST
|
||||||
|
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
||||||
// Render the sphere at the joint
|
// Render the sphere at the joint
|
||||||
if (!_isMine) {
|
if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW
|
||||||
|
|| b == AVATAR_JOINT_RIGHT_WRIST
|
||||||
|
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
||||||
glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f,
|
glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f,
|
||||||
skinColor[1] - _joint[b].touchForce * 0.2f,
|
skinColor[1] - _joint[b].touchForce * 0.2f,
|
||||||
skinColor[2] - _joint[b].touchForce * 0.1f);
|
skinColor[2] - _joint[b].touchForce * 0.1f);
|
||||||
|
|
|
@ -76,7 +76,7 @@ enum AvatarJointID
|
||||||
|
|
||||||
class Avatar : public AvatarData {
|
class Avatar : public AvatarData {
|
||||||
public:
|
public:
|
||||||
Avatar(bool isMine);
|
Avatar(Agent* owningAgent = NULL);
|
||||||
~Avatar();
|
~Avatar();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
Head& getHead() { return _head; }
|
Head& getHead() { return _head; }
|
||||||
|
|
||||||
void setMousePressed(bool pressed);
|
void setMousePressed(bool pressed);
|
||||||
void render(bool lookingInMirror);
|
void render(bool lookingInMirror, glm::vec3 cameraPosition);
|
||||||
void renderBody(bool lookingInMirror);
|
void renderBody(bool lookingInMirror);
|
||||||
void simulate(float deltaTime, Transmitter* transmitter);
|
void simulate(float deltaTime, Transmitter* transmitter);
|
||||||
void setMovedHandOffset(glm::vec3 movedHandOffset) { _movedHandOffset = movedHandOffset; }
|
void setMovedHandOffset(glm::vec3 movedHandOffset) { _movedHandOffset = movedHandOffset; }
|
||||||
|
@ -151,7 +151,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
Head _head;
|
Head _head;
|
||||||
bool _isMine;
|
|
||||||
float _TEST_bigSphereRadius;
|
float _TEST_bigSphereRadius;
|
||||||
glm::vec3 _TEST_bigSpherePosition;
|
glm::vec3 _TEST_bigSpherePosition;
|
||||||
bool _mousePressed;
|
bool _mousePressed;
|
||||||
|
@ -162,6 +161,7 @@ private:
|
||||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||||
AvatarJoint _joint[ NUM_AVATAR_JOINTS ];
|
AvatarJoint _joint[ NUM_AVATAR_JOINTS ];
|
||||||
AvatarMode _mode;
|
AvatarMode _mode;
|
||||||
|
glm::vec3 _cameraPosition;
|
||||||
glm::vec3 _handHoldingPosition;
|
glm::vec3 _handHoldingPosition;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
glm::vec3 _thrust;
|
glm::vec3 _thrust;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <lodepng.h>
|
#include <lodepng.h>
|
||||||
|
#include <AgentList.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -22,6 +23,13 @@ const float HEAD_MOTION_DECAY = 0.1;
|
||||||
const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off
|
const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off
|
||||||
const float EYEBALL_RADIUS = 0.017;
|
const float EYEBALL_RADIUS = 0.017;
|
||||||
const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f };
|
const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f };
|
||||||
|
const float HAIR_COLOR[3] = { 0.8f, 0.6f, 0.5f };
|
||||||
|
const float HAIR_SPRING_FORCE = 10.0f;
|
||||||
|
const float HAIR_TORQUE_FORCE = 0.1f;
|
||||||
|
const float HAIR_GRAVITY_FORCE = 0.05f;
|
||||||
|
const float HAIR_DRAG = 10.0f;
|
||||||
|
const float HAIR_LENGTH = 0.09f;
|
||||||
|
const float HAIR_THICKNESS = 0.03f;
|
||||||
const float IRIS_RADIUS = 0.007;
|
const float IRIS_RADIUS = 0.007;
|
||||||
const float IRIS_PROTRUSION = 0.0145f;
|
const float IRIS_PROTRUSION = 0.0145f;
|
||||||
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
|
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
|
||||||
|
@ -30,8 +38,8 @@ unsigned int IRIS_TEXTURE_WIDTH = 768;
|
||||||
unsigned int IRIS_TEXTURE_HEIGHT = 498;
|
unsigned int IRIS_TEXTURE_HEIGHT = 498;
|
||||||
vector<unsigned char> irisTexture;
|
vector<unsigned char> irisTexture;
|
||||||
|
|
||||||
Head::Head() :
|
Head::Head(Avatar* owningAvatar) :
|
||||||
|
HeadData((AvatarData*)owningAvatar),
|
||||||
yawRate(0.0f),
|
yawRate(0.0f),
|
||||||
_returnHeadToCenter(false),
|
_returnHeadToCenter(false),
|
||||||
_audioLoudness(0.0f),
|
_audioLoudness(0.0f),
|
||||||
|
@ -54,16 +62,36 @@ Head::Head() :
|
||||||
_audioAttack(0.0f),
|
_audioAttack(0.0f),
|
||||||
_returnSpringScale(1.0f),
|
_returnSpringScale(1.0f),
|
||||||
_bodyRotation(0.0f, 0.0f, 0.0f),
|
_bodyRotation(0.0f, 0.0f, 0.0f),
|
||||||
_headRotation(0.0f, 0.0f, 0.0f),
|
_mohawkTriangleFan(NULL),
|
||||||
|
_mohawkColors(NULL),
|
||||||
_renderLookatVectors(false) {
|
_renderLookatVectors(false) {
|
||||||
createMohawk();
|
|
||||||
|
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
|
||||||
|
_hairTuft[t].length = HAIR_LENGTH;
|
||||||
|
_hairTuft[t].thickness = HAIR_THICKNESS;
|
||||||
|
_hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
_hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].endPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::reset() {
|
void Head::reset() {
|
||||||
_yaw = _pitch = _roll = 0.0f;
|
_yaw = _pitch = _roll = 0.0f;
|
||||||
_leanForward = _leanSideways = 0.0f;
|
_leanForward = _leanSideways = 0.0f;
|
||||||
}
|
|
||||||
|
|
||||||
|
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
|
||||||
|
|
||||||
|
_hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f;
|
||||||
|
_hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF;
|
||||||
|
_hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF;
|
||||||
|
_hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Head::simulate(float deltaTime, bool isMine) {
|
void Head::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
|
@ -112,6 +140,8 @@ void Head::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
|
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
|
||||||
determineIfLookingAtSomething();
|
determineIfLookingAtSomething();
|
||||||
|
|
||||||
|
updateHair(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::determineIfLookingAtSomething() {
|
void Head::determineIfLookingAtSomething() {
|
||||||
|
@ -170,19 +200,20 @@ void Head::calculateGeometry(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Head::render(bool lookingInMirror) {
|
void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||||
|
|
||||||
calculateGeometry(lookingInMirror);
|
calculateGeometry(lookingInMirror);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_RESCALE_NORMAL);
|
glEnable(GL_RESCALE_NORMAL);
|
||||||
|
|
||||||
renderMohawk();
|
renderMohawk(lookingInMirror);
|
||||||
renderHeadSphere();
|
renderHeadSphere();
|
||||||
renderEyeBalls();
|
renderEyeBalls();
|
||||||
renderEars();
|
renderEars();
|
||||||
renderMouth();
|
renderMouth();
|
||||||
renderEyeBrows();
|
renderEyeBrows();
|
||||||
|
renderHair(cameraPosition);
|
||||||
|
|
||||||
if (_renderLookatVectors && _lookingAtSomething) {
|
if (_renderLookatVectors && _lookingAtSomething) {
|
||||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||||
|
@ -190,14 +221,25 @@ void Head::render(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::createMohawk() {
|
void Head::createMohawk() {
|
||||||
float height = 0.05f + randFloat() * 0.10f;
|
uint16_t agentId = 0;
|
||||||
float variance = 0.05 + randFloat() * 0.05f;
|
if (_owningAvatar->getOwningAgent()) {
|
||||||
|
agentId = _owningAvatar->getOwningAgent()->getAgentID();
|
||||||
|
} else {
|
||||||
|
agentId = AgentList::getInstance()->getOwnerID();
|
||||||
|
if (agentId == UNKNOWN_AGENT_ID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srand(agentId);
|
||||||
|
float height = 0.08f + randFloat() * 0.05f;
|
||||||
|
float variance = 0.03 + randFloat() * 0.03f;
|
||||||
const float RAD_PER_TRIANGLE = (2.3f + randFloat() * 0.2f) / (float)MOHAWK_TRIANGLES;
|
const float RAD_PER_TRIANGLE = (2.3f + randFloat() * 0.2f) / (float)MOHAWK_TRIANGLES;
|
||||||
_mohawkTriangleFan = new glm::vec3[MOHAWK_TRIANGLES];
|
_mohawkTriangleFan = new glm::vec3[MOHAWK_TRIANGLES];
|
||||||
_mohawkColors = new glm::vec3[MOHAWK_TRIANGLES];
|
_mohawkColors = new glm::vec3[MOHAWK_TRIANGLES];
|
||||||
_mohawkTriangleFan[0] = glm::vec3(0, 0, 0);
|
_mohawkTriangleFan[0] = glm::vec3(0, 0, 0);
|
||||||
glm::vec3 basicColor(randFloat(), randFloat(), randFloat());
|
glm::vec3 basicColor(randFloat(), randFloat(), randFloat());
|
||||||
_mohawkColors[0] = basicColor;
|
_mohawkColors[0] = basicColor;
|
||||||
|
|
||||||
for (int i = 1; i < MOHAWK_TRIANGLES; i++) {
|
for (int i = 1; i < MOHAWK_TRIANGLES; i++) {
|
||||||
_mohawkTriangleFan[i] = glm::vec3((randFloat() - 0.5f) * variance,
|
_mohawkTriangleFan[i] = glm::vec3((randFloat() - 0.5f) * variance,
|
||||||
height * cosf(i * RAD_PER_TRIANGLE - PI / 2.f)
|
height * cosf(i * RAD_PER_TRIANGLE - PI / 2.f)
|
||||||
|
@ -207,13 +249,18 @@ void Head::createMohawk() {
|
||||||
_mohawkColors[i] = randFloat() * basicColor;
|
_mohawkColors[i] = randFloat() * basicColor;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::renderMohawk() {
|
void Head::renderMohawk(bool lookingInMirror) {
|
||||||
|
if (!_mohawkTriangleFan) {
|
||||||
|
createMohawk();
|
||||||
|
} else {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_position.x, _position.y, _position.z);
|
glTranslatef(_position.x, _position.y, _position.z);
|
||||||
glRotatef(_bodyRotation.y, 0, 1, 0);
|
glRotatef((lookingInMirror ? (_bodyRotation.y - _yaw) : (_bodyRotation.y + _yaw)), 0, 1, 0);
|
||||||
|
glRotatef(lookingInMirror ? _roll: -_roll, 0, 0, 1);
|
||||||
|
glRotatef(-_pitch - _bodyRotation.x, 1, 0, 0);
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
for (int i = 0; i < MOHAWK_TRIANGLES; i++) {
|
for (int i = 0; i < MOHAWK_TRIANGLES; i++) {
|
||||||
glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z);
|
glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z);
|
||||||
|
@ -223,6 +270,7 @@ void Head::renderMohawk() {
|
||||||
glEnd();
|
glEnd();
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Head::renderHeadSphere() {
|
void Head::renderHeadSphere() {
|
||||||
|
@ -264,6 +312,15 @@ void Head::renderMouth() {
|
||||||
glm::vec3 leftBottom = _mouthPosition - r * 0.4f - u * 1.0f + f * 0.7f;
|
glm::vec3 leftBottom = _mouthPosition - r * 0.4f - u * 1.0f + f * 0.7f;
|
||||||
glm::vec3 rightBottom = _mouthPosition + r * 0.4f - u * 1.0f + f * 0.7f;
|
glm::vec3 rightBottom = _mouthPosition + r * 0.4f - u * 1.0f + f * 0.7f;
|
||||||
|
|
||||||
|
// constrain all mouth vertices to a sphere slightly larger than the head...
|
||||||
|
float constrainedRadius = _scale + 0.001f;
|
||||||
|
leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius;
|
||||||
|
rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius;
|
||||||
|
leftTop = _position + glm::normalize(leftTop - _position) * constrainedRadius;
|
||||||
|
rightTop = _position + glm::normalize(rightTop - _position) * constrainedRadius;
|
||||||
|
leftBottom = _position + glm::normalize(leftBottom - _position) * constrainedRadius;
|
||||||
|
rightBottom = _position + glm::normalize(rightBottom - _position) * constrainedRadius;
|
||||||
|
|
||||||
glColor3f(0.2f, 0.0f, 0.0f);
|
glColor3f(0.2f, 0.0f, 0.0f);
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
|
@ -469,4 +526,133 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Head::updateHair(float deltaTime) {
|
||||||
|
|
||||||
|
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
|
||||||
|
|
||||||
|
float fraction = (float)t / (float)(NUM_HAIR_TUFTS - 1);
|
||||||
|
|
||||||
|
float angle = -20.0f + 40.0f * fraction;
|
||||||
|
|
||||||
|
float radian = angle * PI_OVER_180;
|
||||||
|
glm::vec3 baseDirection
|
||||||
|
= _orientation.getFront() * sinf(radian)
|
||||||
|
+ _orientation.getUp() * cosf(radian);
|
||||||
|
|
||||||
|
_hairTuft[t].basePosition = _position + _scale * 0.9f * baseDirection;
|
||||||
|
|
||||||
|
glm::vec3 midAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
|
||||||
|
glm::vec3 endAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
|
||||||
|
|
||||||
|
float midLength = glm::length(midAxis);
|
||||||
|
float endLength = glm::length(endAxis);
|
||||||
|
|
||||||
|
glm::vec3 midDirection;
|
||||||
|
glm::vec3 endDirection;
|
||||||
|
|
||||||
|
if (midLength > 0.0f) {
|
||||||
|
midDirection = midAxis / midLength;
|
||||||
|
} else {
|
||||||
|
midDirection = _orientation.getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endLength > 0.0f) {
|
||||||
|
endDirection = endAxis / endLength;
|
||||||
|
} else {
|
||||||
|
endDirection = _orientation.getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// add spring force
|
||||||
|
float midForce = midLength - _hairTuft[t].length * ONE_HALF;
|
||||||
|
float endForce = endLength - _hairTuft[t].length * ONE_HALF;
|
||||||
|
_hairTuft[t].midVelocity -= midDirection * midForce * HAIR_SPRING_FORCE * deltaTime;
|
||||||
|
_hairTuft[t].endVelocity -= endDirection * endForce * HAIR_SPRING_FORCE * deltaTime;
|
||||||
|
|
||||||
|
// add gravity force
|
||||||
|
glm::vec3 gravityForce = _gravity * HAIR_GRAVITY_FORCE * deltaTime;
|
||||||
|
_hairTuft[t].midVelocity += gravityForce;
|
||||||
|
_hairTuft[t].endVelocity += gravityForce;
|
||||||
|
|
||||||
|
// add torque force
|
||||||
|
_hairTuft[t].midVelocity += baseDirection * HAIR_TORQUE_FORCE * deltaTime;
|
||||||
|
_hairTuft[t].endVelocity += midDirection * HAIR_TORQUE_FORCE * deltaTime;
|
||||||
|
|
||||||
|
// add drag force
|
||||||
|
float momentum = 1.0f - (HAIR_DRAG * deltaTime);
|
||||||
|
if (momentum < 0.0f) {
|
||||||
|
_hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
} else {
|
||||||
|
_hairTuft[t].midVelocity *= momentum;
|
||||||
|
_hairTuft[t].endVelocity *= momentum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update position by velocity
|
||||||
|
_hairTuft[t].midPosition += _hairTuft[t].midVelocity;
|
||||||
|
_hairTuft[t].endPosition += _hairTuft[t].endVelocity;
|
||||||
|
|
||||||
|
// clamp lengths
|
||||||
|
glm::vec3 newMidVector = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
|
||||||
|
glm::vec3 newEndVector = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
|
||||||
|
|
||||||
|
float newMidLength = glm::length(newMidVector);
|
||||||
|
float newEndLength = glm::length(newEndVector);
|
||||||
|
|
||||||
|
glm::vec3 newMidDirection;
|
||||||
|
glm::vec3 newEndDirection;
|
||||||
|
|
||||||
|
if (newMidLength > 0.0f) {
|
||||||
|
newMidDirection = newMidVector/newMidLength;
|
||||||
|
} else {
|
||||||
|
newMidDirection = _orientation.getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newEndLength > 0.0f) {
|
||||||
|
newEndDirection = newEndVector/newEndLength;
|
||||||
|
} else {
|
||||||
|
newEndDirection = _orientation.getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hairTuft[t].endPosition = _hairTuft[t].midPosition + newEndDirection * _hairTuft[t].length * ONE_HALF;
|
||||||
|
_hairTuft[t].midPosition = _hairTuft[t].basePosition + newMidDirection * _hairTuft[t].length * ONE_HALF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Head::renderHair(glm::vec3 cameraPosition) {
|
||||||
|
|
||||||
|
for (int t = 0; t < NUM_HAIR_TUFTS; t ++) {
|
||||||
|
|
||||||
|
glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition;
|
||||||
|
glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition;
|
||||||
|
glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition;
|
||||||
|
|
||||||
|
glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector));
|
||||||
|
glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector));
|
||||||
|
|
||||||
|
glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF;
|
||||||
|
glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF;
|
||||||
|
glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF;
|
||||||
|
glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF;
|
||||||
|
|
||||||
|
glColor3fv(HAIR_COLOR);
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
glVertex3f(base1.x, base1.y, base1.z );
|
||||||
|
glVertex3f(base2.x, base2.y, base2.z );
|
||||||
|
glVertex3f(mid1.x, mid1.y, mid1.z );
|
||||||
|
|
||||||
|
glVertex3f(base2.x, base2.y, base2.z );
|
||||||
|
glVertex3f(mid1.x, mid1.y, mid1.z );
|
||||||
|
glVertex3f(mid2.x, mid2.y, mid2.z );
|
||||||
|
|
||||||
|
glVertex3f(mid1.x, mid1.y, mid1.z );
|
||||||
|
glVertex3f(mid2.x, mid2.y, mid2.z );
|
||||||
|
glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z );
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,19 +24,23 @@ enum eyeContactTargets
|
||||||
MOUTH
|
MOUTH
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int NUM_HAIR_TUFTS = 4;
|
||||||
|
const int NUM_HAIR_SEGMENTS = 4;
|
||||||
|
|
||||||
|
class Avatar;
|
||||||
|
|
||||||
class Head : public HeadData {
|
class Head : public HeadData {
|
||||||
public:
|
public:
|
||||||
Head();
|
Head(Avatar* owningAvatar);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine);
|
void simulate(float deltaTime, bool isMine);
|
||||||
void render(bool lookingInMirror);
|
void render(bool lookingInMirror, glm::vec3 cameraPosition);
|
||||||
void renderMohawk();
|
void renderMohawk(bool lookingInMirror);
|
||||||
|
|
||||||
void setScale (float scale ) { _scale = scale; }
|
void setScale (float scale ) { _scale = scale; }
|
||||||
void setPosition (glm::vec3 position ) { _position = position; }
|
void setPosition (glm::vec3 position ) { _position = position; }
|
||||||
void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; }
|
void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; }
|
||||||
void setRotationOffBody(glm::vec3 headRotation ) { _headRotation = headRotation; }
|
|
||||||
void setGravity (glm::vec3 gravity ) { _gravity = gravity; }
|
void setGravity (glm::vec3 gravity ) { _gravity = gravity; }
|
||||||
void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; }
|
void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; }
|
||||||
void setSpringScale (float returnSpringScale ) { _returnSpringScale = returnSpringScale; }
|
void setSpringScale (float returnSpringScale ) { _returnSpringScale = returnSpringScale; }
|
||||||
|
@ -57,6 +61,18 @@ private:
|
||||||
Head(const Head&);
|
Head(const Head&);
|
||||||
Head& operator= (const Head&);
|
Head& operator= (const Head&);
|
||||||
|
|
||||||
|
struct HairTuft
|
||||||
|
{
|
||||||
|
float length;
|
||||||
|
float thickness;
|
||||||
|
|
||||||
|
glm::vec3 basePosition;
|
||||||
|
glm::vec3 midPosition;
|
||||||
|
glm::vec3 endPosition;
|
||||||
|
glm::vec3 midVelocity;
|
||||||
|
glm::vec3 endVelocity;
|
||||||
|
};
|
||||||
|
|
||||||
bool _returnHeadToCenter;
|
bool _returnHeadToCenter;
|
||||||
float _audioLoudness;
|
float _audioLoudness;
|
||||||
glm::vec3 _skinColor;
|
glm::vec3 _skinColor;
|
||||||
|
@ -79,8 +95,8 @@ private:
|
||||||
float _returnSpringScale; //strength of return springs
|
float _returnSpringScale; //strength of return springs
|
||||||
Orientation _orientation;
|
Orientation _orientation;
|
||||||
glm::vec3 _bodyRotation;
|
glm::vec3 _bodyRotation;
|
||||||
glm::vec3 _headRotation;
|
|
||||||
bool _renderLookatVectors;
|
bool _renderLookatVectors;
|
||||||
|
HairTuft _hairTuft[NUM_HAIR_TUFTS];
|
||||||
glm::vec3* _mohawkTriangleFan;
|
glm::vec3* _mohawkTriangleFan;
|
||||||
glm::vec3* _mohawkColors;
|
glm::vec3* _mohawkColors;
|
||||||
|
|
||||||
|
@ -94,6 +110,8 @@ private:
|
||||||
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||||
void calculateGeometry( bool lookingInMirror);
|
void calculateGeometry( bool lookingInMirror);
|
||||||
void determineIfLookingAtSomething();
|
void determineIfLookingAtSomething();
|
||||||
|
void updateHair(float deltaTime);
|
||||||
|
void renderHair(glm::vec3 cameraPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
const short NO_READ_MAXIMUM_MSECS = 3000;
|
const short NO_READ_MAXIMUM_MSECS = 3000;
|
||||||
const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values
|
const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values
|
||||||
|
const int LONG_TERM_RATE_SAMPLES = 1000;
|
||||||
|
|
||||||
const bool USING_INVENSENSE_MPU9150 = 1;
|
const bool USING_INVENSENSE_MPU9150 = 1;
|
||||||
|
|
||||||
|
@ -136,6 +137,16 @@ void SerialInterface::renderLevels(int width, int height) {
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastPitchRate(), LEVEL_CORNER_Y + 12);
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastPitchRate(), LEVEL_CORNER_Y + 12);
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 27);
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 27);
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastRollRate(), LEVEL_CORNER_Y + 27);
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastRollRate(), LEVEL_CORNER_Y + 27);
|
||||||
|
// Gyro Estimated Rotation
|
||||||
|
glColor4f(0, 1, 1, 1);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 1);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.y, LEVEL_CORNER_Y - 1);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 14);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.z, LEVEL_CORNER_Y + 14);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 29);
|
||||||
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.x, LEVEL_CORNER_Y + 29);
|
||||||
|
|
||||||
|
|
||||||
// Acceleration
|
// Acceleration
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 42);
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 42);
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)((_lastAccelX - _gravity.x)* ACCEL_VIEW_SCALING),
|
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)((_lastAccelX - _gravity.x)* ACCEL_VIEW_SCALING),
|
||||||
|
@ -169,7 +180,7 @@ void convertHexToInt(unsigned char* sourceBuffer, int& destinationInt) {
|
||||||
|
|
||||||
destinationInt = result;
|
destinationInt = result;
|
||||||
}
|
}
|
||||||
void SerialInterface::readData() {
|
void SerialInterface::readData(float deltaTime) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
int initialSamples = totalSamples;
|
int initialSamples = totalSamples;
|
||||||
|
@ -207,6 +218,11 @@ void SerialInterface::readData() {
|
||||||
_lastYawRate = ((float) -yawRate) * LSB_TO_DEGREES_PER_SECOND;
|
_lastYawRate = ((float) -yawRate) * LSB_TO_DEGREES_PER_SECOND;
|
||||||
_lastPitchRate = ((float) -pitchRate) * LSB_TO_DEGREES_PER_SECOND;
|
_lastPitchRate = ((float) -pitchRate) * LSB_TO_DEGREES_PER_SECOND;
|
||||||
|
|
||||||
|
// Update raw rotation estimates
|
||||||
|
_estimatedRotation += deltaTime * glm::vec3(_lastRollRate - _averageGyroRates[0],
|
||||||
|
_lastYawRate - _averageGyroRates[1],
|
||||||
|
_lastPitchRate - _averageGyroRates[2]);
|
||||||
|
|
||||||
// Accumulate a set of initial baseline readings for setting gravity
|
// Accumulate a set of initial baseline readings for setting gravity
|
||||||
if (totalSamples == 0) {
|
if (totalSamples == 0) {
|
||||||
_averageGyroRates[0] = _lastRollRate;
|
_averageGyroRates[0] = _lastRollRate;
|
||||||
|
@ -217,16 +233,19 @@ void SerialInterface::readData() {
|
||||||
_gravity.z = _lastAccelZ;
|
_gravity.z = _lastAccelZ;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (totalSamples < GRAVITY_SAMPLES) {
|
else {
|
||||||
|
// Cumulate long term average to (hopefully) take DC bias out of rotation rates
|
||||||
|
_averageGyroRates[0] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[0] +
|
||||||
|
1.f/(float)LONG_TERM_RATE_SAMPLES * _lastRollRate;
|
||||||
|
_averageGyroRates[1] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[1] +
|
||||||
|
1.f/(float)LONG_TERM_RATE_SAMPLES * _lastYawRate;
|
||||||
|
_averageGyroRates[2] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[2] +
|
||||||
|
1.f/(float)LONG_TERM_RATE_SAMPLES * _lastPitchRate;
|
||||||
|
|
||||||
|
if (totalSamples < GRAVITY_SAMPLES) {
|
||||||
_gravity = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _gravity +
|
_gravity = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _gravity +
|
||||||
1.f/(float)GRAVITY_SAMPLES * glm::vec3(_lastAccelX, _lastAccelY, _lastAccelZ);
|
1.f/(float)GRAVITY_SAMPLES * glm::vec3(_lastAccelX, _lastAccelY, _lastAccelZ);
|
||||||
|
}
|
||||||
_averageGyroRates[0] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[0] +
|
|
||||||
1.f/(float)GRAVITY_SAMPLES * _lastRollRate;
|
|
||||||
_averageGyroRates[1] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[1] +
|
|
||||||
1.f/(float)GRAVITY_SAMPLES * _lastYawRate;
|
|
||||||
_averageGyroRates[2] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[2] +
|
|
||||||
1.f/(float)GRAVITY_SAMPLES * _lastPitchRate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
totalSamples++;
|
totalSamples++;
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
SerialInterface() : active(false),
|
SerialInterface() : active(false),
|
||||||
_gravity(0,0,0),
|
_gravity(0,0,0),
|
||||||
_averageGyroRates(0, 0, 0),
|
_averageGyroRates(0, 0, 0),
|
||||||
|
_estimatedRotation(0, 0, 0),
|
||||||
_lastAccelX(0),
|
_lastAccelX(0),
|
||||||
_lastAccelY(0),
|
_lastAccelY(0),
|
||||||
_lastAccelZ(0),
|
_lastAccelZ(0),
|
||||||
|
@ -47,7 +48,7 @@ public:
|
||||||
_lastRollRate(0) {}
|
_lastRollRate(0) {}
|
||||||
|
|
||||||
void pair();
|
void pair();
|
||||||
void readData();
|
void readData(float deltaTime);
|
||||||
|
|
||||||
float getLastYawRate() const { return _lastYawRate - _averageGyroRates[1]; }
|
float getLastYawRate() const { return _lastYawRate - _averageGyroRates[1]; }
|
||||||
float getLastPitchRate() const { return _lastPitchRate - _averageGyroRates[2]; }
|
float getLastPitchRate() const { return _lastPitchRate - _averageGyroRates[2]; }
|
||||||
|
@ -68,6 +69,7 @@ private:
|
||||||
timeval lastGoodRead;
|
timeval lastGoodRead;
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
glm::vec3 _averageGyroRates;
|
glm::vec3 _averageGyroRates;
|
||||||
|
glm::vec3 _estimatedRotation;
|
||||||
float _lastAccelX;
|
float _lastAccelX;
|
||||||
float _lastAccelY;
|
float _lastAccelY;
|
||||||
float _lastAccelZ;
|
float _lastAccelZ;
|
||||||
|
|
|
@ -44,7 +44,7 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- .
|
||||||
10,11,15, 10,15,14, // Y+
|
10,11,15, 10,15,14, // Y+
|
||||||
4,5,6, 4,6,7 }; // Z+ .
|
4,5,6, 4,6,7 }; // Z+ .
|
||||||
|
|
||||||
VoxelSystem::VoxelSystem() {
|
VoxelSystem::VoxelSystem() : AgentData(NULL) {
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
||||||
_writeRenderFullVBO = true;
|
_writeRenderFullVBO = true;
|
||||||
_readRenderFullVBO = true;
|
_readRenderFullVBO = true;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "AudioRingBuffer.h"
|
#include "AudioRingBuffer.h"
|
||||||
|
|
||||||
AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) :
|
AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) :
|
||||||
|
AgentData(NULL),
|
||||||
_ringBufferLengthSamples(ringSamples),
|
_ringBufferLengthSamples(ringSamples),
|
||||||
_bufferLengthSamples(bufferSamples),
|
_bufferLengthSamples(bufferSamples),
|
||||||
_endOfLastWrite(NULL),
|
_endOfLastWrite(NULL),
|
||||||
|
|
|
@ -31,7 +31,8 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
|
||||||
return sizeof(uint16_t);
|
return sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData(Agent* owningAgent) :
|
||||||
|
AgentData(owningAgent),
|
||||||
_handPosition(0,0,0),
|
_handPosition(0,0,0),
|
||||||
_bodyYaw(-90.0),
|
_bodyYaw(-90.0),
|
||||||
_bodyPitch(0.0),
|
_bodyPitch(0.0),
|
||||||
|
@ -67,7 +68,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
|
|
||||||
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||||
if (!_headData) {
|
if (!_headData) {
|
||||||
_headData = new HeadData();
|
_headData = new HeadData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body world position
|
// Body world position
|
||||||
|
@ -148,7 +149,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
|
|
||||||
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||||
if (!_headData) {
|
if (!_headData) {
|
||||||
_headData = new HeadData();
|
_headData = new HeadData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment to push past the packet header
|
// increment to push past the packet header
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum KeyState
|
||||||
|
|
||||||
class AvatarData : public AgentData {
|
class AvatarData : public AgentData {
|
||||||
public:
|
public:
|
||||||
AvatarData();
|
AvatarData(Agent* owningAgent = NULL);
|
||||||
~AvatarData();
|
~AvatarData();
|
||||||
|
|
||||||
const glm::vec3& getPosition() const { return _position; }
|
const glm::vec3& getPosition() const { return _position; }
|
||||||
|
|
|
@ -8,13 +8,14 @@
|
||||||
|
|
||||||
#include "HeadData.h"
|
#include "HeadData.h"
|
||||||
|
|
||||||
HeadData::HeadData() :
|
HeadData::HeadData(AvatarData* owningAvatar) :
|
||||||
_yaw(0.0f),
|
_yaw(0.0f),
|
||||||
_pitch(0.0f),
|
_pitch(0.0f),
|
||||||
_roll(0.0f),
|
_roll(0.0f),
|
||||||
_lookAtPosition(0.0f, 0.0f, 0.0f),
|
_lookAtPosition(0.0f, 0.0f, 0.0f),
|
||||||
_leanSideways(0.0f),
|
_leanSideways(0.0f),
|
||||||
_leanForward(0.0f)
|
_leanForward(0.0f),
|
||||||
|
_owningAvatar(owningAvatar)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,11 @@ const float MAX_HEAD_PITCH = 60;
|
||||||
const float MIN_HEAD_ROLL = -50;
|
const float MIN_HEAD_ROLL = -50;
|
||||||
const float MAX_HEAD_ROLL = 50;
|
const float MAX_HEAD_ROLL = 50;
|
||||||
|
|
||||||
|
class AvatarData;
|
||||||
|
|
||||||
class HeadData {
|
class HeadData {
|
||||||
public:
|
public:
|
||||||
HeadData();
|
HeadData(AvatarData* owningAvatar);
|
||||||
|
|
||||||
float getLeanSideways() const { return _leanSideways; }
|
float getLeanSideways() const { return _leanSideways; }
|
||||||
void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; }
|
void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; }
|
||||||
|
@ -55,6 +57,7 @@ protected:
|
||||||
glm::vec3 _lookAtPosition;
|
glm::vec3 _lookAtPosition;
|
||||||
float _leanSideways;
|
float _leanSideways;
|
||||||
float _leanForward;
|
float _leanForward;
|
||||||
|
AvatarData* _owningAvatar;
|
||||||
private:
|
private:
|
||||||
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
||||||
HeadData(const HeadData&);
|
HeadData(const HeadData&);
|
||||||
|
|
|
@ -8,4 +8,10 @@
|
||||||
|
|
||||||
#include "AgentData.h"
|
#include "AgentData.h"
|
||||||
|
|
||||||
|
AgentData::AgentData(Agent* owningAgent) :
|
||||||
|
_owningAgent(owningAgent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
AgentData::~AgentData() {}
|
AgentData::~AgentData() {}
|
|
@ -3,16 +3,24 @@
|
||||||
// hifi
|
// hifi
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 2/19/13.
|
// Created by Stephen Birarda on 2/19/13.
|
||||||
//
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_AgentData_h
|
#ifndef hifi_AgentData_h
|
||||||
#define hifi_AgentData_h
|
#define hifi_AgentData_h
|
||||||
|
|
||||||
|
class Agent;
|
||||||
|
|
||||||
class AgentData {
|
class AgentData {
|
||||||
public:
|
public:
|
||||||
|
AgentData(Agent* owningAgent);
|
||||||
|
|
||||||
virtual ~AgentData() = 0;
|
virtual ~AgentData() = 0;
|
||||||
virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0;
|
virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0;
|
||||||
|
|
||||||
|
Agent* getOwningAgent() { return _owningAgent; }
|
||||||
|
protected:
|
||||||
|
Agent* _owningAgent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
VoxelAgentData::VoxelAgentData() :
|
VoxelAgentData::VoxelAgentData(Agent* owningAgent) :
|
||||||
|
AvatarData(owningAgent),
|
||||||
_viewSent(false),
|
_viewSent(false),
|
||||||
_voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE),
|
_voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE),
|
||||||
_maxSearchLevel(1),
|
_maxSearchLevel(1),
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class VoxelAgentData : public AvatarData {
|
class VoxelAgentData : public AvatarData {
|
||||||
public:
|
public:
|
||||||
VoxelAgentData();
|
VoxelAgentData(Agent* owningAgent);
|
||||||
~VoxelAgentData();
|
~VoxelAgentData();
|
||||||
|
|
||||||
void resetVoxelPacket(); // resets voxel packet to after "V" header
|
void resetVoxelPacket(); // resets voxel packet to after "V" header
|
||||||
|
|
|
@ -452,7 +452,7 @@ void *distributeVoxelsToListeners(void *args) {
|
||||||
|
|
||||||
void attachVoxelAgentDataToAgent(Agent* newAgent) {
|
void attachVoxelAgentDataToAgent(Agent* newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new VoxelAgentData());
|
newAgent->setLinkedData(new VoxelAgentData(newAgent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,12 +562,13 @@ int main(int argc, const char * argv[]) {
|
||||||
environmentData[1].setGravity(1.0f);
|
environmentData[1].setGravity(1.0f);
|
||||||
environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
|
environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
|
||||||
environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
|
environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
|
||||||
environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.025f);
|
environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
|
||||||
environmentData[2].setID(2);
|
environmentData[2].setID(2);
|
||||||
environmentData[2].setGravity(1.0f);
|
environmentData[2].setGravity(1.0f);
|
||||||
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
|
||||||
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
|
||||||
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.025f);
|
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
|
||||||
|
environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
|
||||||
|
|
||||||
pthread_t sendVoxelThread;
|
pthread_t sendVoxelThread;
|
||||||
pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);
|
pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);
|
||||||
|
|
Loading…
Reference in a new issue