Merge branch 'master' of https://github.com/worklist/hifi into view_frustum_work

This commit is contained in:
ZappoMan 2013-04-29 06:18:25 -07:00
commit ff996c9946
12 changed files with 381 additions and 703 deletions

View file

@ -121,7 +121,7 @@ int main(int argc, const char* argv[]) {
// put her hand out so somebody can shake it
eve.setHandPosition(glm::vec3(eve.getPosition()[0] - 0.2,
0.25,
0.32, // this is the same as the pelvis standing height (as of 4/26/13)
eve.getPosition()[2] + 0.1));
// read eve's audio data
AudioInjector eveAudioInjector("eve.raw");

View file

@ -127,13 +127,9 @@ int audioCallback (const void *inputBuffer,
loudness /= BUFFER_LENGTH_SAMPLES;
data->lastInputLoudness = loudness;
// If scope is turned on, copy input buffer to scope
if (scope->getState()) {
for (int i = 0; i < BUFFER_LENGTH_SAMPLES; i++) {
scope->addData((float)inputLeft[i]/32767.0, 1, i);
}
}
// add data to the scope
scope->addSamples(0, inputLeft, BUFFER_LENGTH_SAMPLES);
if (data->mixerAddress != 0) {
sockaddr_in audioMixerSocket;
@ -278,6 +274,10 @@ int audioCallback (const void *inputBuffer,
outputRight[s] = rightSample;
}
// add data to the scope
scope->addSamples(1, outputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL);
scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL);
ringBuffer->setNextOutput(ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES);
if (ringBuffer->getNextOutput() == ringBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
@ -330,8 +330,9 @@ void *receiveAudioViaUDP(void *args) {
delete[] directory;
delete[] filename;
}
while (!stopAudioReceiveThread) {
if (sharedAudioData->audioSocket->receive((void *)receivedData, &receivedBytes)) {
gettimeofday(&currentReceiveTime, NULL);

View file

@ -50,23 +50,22 @@ Avatar::Avatar(bool isMine) {
_orientation.setToIdentity();
_velocity = glm::vec3( 0.0, 0.0, 0.0 );
_thrust = glm::vec3( 0.0, 0.0, 0.0 );
_rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f );
_bodyYaw = -90.0;
_bodyPitch = 0.0;
_bodyRoll = 0.0;
_bodyYawDelta = 0.0;
_mousePressed = false;
_mode = AVATAR_MODE_STANDING;
_isMine = isMine;
_maxArmLength = 0.0;
//_transmitterTimer = 0;
_transmitterHz = 0.0;
_transmitterPackets = 0;
_speed = 0.0;
_velocity = glm::vec3( 0.0, 0.0, 0.0 );
_thrust = glm::vec3( 0.0, 0.0, 0.0 );
_rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f );
_bodyYaw = -90.0;
_bodyPitch = 0.0;
_bodyRoll = 0.0;
_bodyYawDelta = 0.0;
_mousePressed = false;
_mode = AVATAR_MODE_STANDING;
_isMine = isMine;
_maxArmLength = 0.0;
_transmitterHz = 0.0;
_transmitterPackets = 0;
_speed = 0.0;
_pelvisStandingHeight = 0.0f;
_displayingHead = true;
_TEST_bigSphereRadius = 0.3f;
_TEST_bigSpherePosition = glm::vec3( 0.0f, _TEST_bigSphereRadius, 2.0f );
@ -329,11 +328,7 @@ void Avatar::simulate(float deltaTime) {
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
// check for collisions with other avatars and respond
updateAvatarCollisionDetectionAndResponse(otherAvatar->getPosition(),
0.1,
0.1,
otherAvatar->getBodyUpDirection(),
deltaTime);
updateCollisionWithOtherAvatar(otherAvatar, deltaTime );
// test other avatar hand position for proximity
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
@ -382,12 +377,8 @@ void Avatar::simulate(float deltaTime) {
}
if (usingBigSphereCollisionTest) {
// test for avatar collision response (using a big sphere :)
updateAvatarCollisionDetectionAndResponse(_TEST_bigSpherePosition,
_TEST_bigSphereRadius,
_TEST_bigSphereRadius,
glm::vec3( 0.0, 1.0, 0.0 ),
deltaTime);
// test for avatar collision response with the big sphere
updateCollisionWithSphere( _TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime );
}
if ( AVATAR_GRAVITY ) {
@ -541,31 +532,22 @@ void Avatar::simulate(float deltaTime) {
}
}
float Avatar::getGirth() {
return COLLISION_BODY_RADIUS;
}
float Avatar::getHeight() {
return COLLISION_HEIGHT;
return _height;
}
// This is a workspace for testing avatar body collision detection and response
void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPosition,
float collisionGirth,
float collisionHeight,
glm::vec3 collisionUpVector,
float deltaTime) {
void Avatar::updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ) {
float myBodyApproximateBoundingRadius = 1.0f;
glm::vec3 vectorFromMyBodyToBigSphere(_position - collisionPosition);
glm::vec3 vectorFromMyBodyToBigSphere(_position - position);
bool jointCollision = false;
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionGirth ) {
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + radius ) {
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - collisionPosition);
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - position);
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
float combinedRadius = _bone[b].radius + collisionGirth;
float combinedRadius = _bone[b].radius + radius;
if ( distanceToBigSphereCenter < combinedRadius ) {
jointCollision = true;
@ -577,7 +559,7 @@ void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPositi
_bone[b].springyVelocity += collisionForce * 30.0f * deltaTime;
_velocity += collisionForce * 100.0f * deltaTime;
_bone[b].springyPosition = collisionPosition + directionVector * combinedRadius;
_bone[b].springyPosition = position + directionVector * combinedRadius;
}
}
}
@ -591,6 +573,50 @@ void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPositi
}
}
//detect collisions with other avatars and respond
void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTime ) {
// check if the bounding spheres of the two avatars are colliding
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
if ( glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF ) {
// loop through the bones of each avatar to check for every possible collision
for (int b=1; b<NUM_AVATAR_BONES; b++) {
for (int o=b+1; o<NUM_AVATAR_BONES; o++) {
glm::vec3 vectorBetweenJoints(_bone[b].springyPosition - otherAvatar->_bone[o].springyPosition);
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
// to avoid divide by zero
if ( distanceBetweenJoints > 0.0 ) {
float combinedRadius = _bone[b].radius + otherAvatar->_bone[o].radius;
// check for collision
if ( distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
// push ball away from colliding other ball and puch avatar body (_velocity) as well
_bone[b].springyVelocity += directionVector * COLLISION_BALL_FORCE * deltaTime;
_velocity += directionVector * COLLISION_BODY_FORCE * deltaTime;
// apply fruction to _velocity
float momentum = 1.0 - COLLISION_FRICTION * deltaTime;
if ( momentum < 0.0 ) { momentum = 0.0;}
_velocity *= momentum;
}
}
}
}
}
}
void Avatar::setDisplayingHead( bool displayingHead ) {
_displayingHead = displayingHead;
}
void Avatar::render(bool lookingInMirror) {
/*
@ -618,8 +644,10 @@ void Avatar::render(bool lookingInMirror) {
renderBody();
// render head
renderHead(lookingInMirror);
if (_displayingHead) {
renderHead(lookingInMirror);
}
// if this is my avatar, then render my interactions with the other avatar
if ( _isMine )
{
@ -959,12 +987,22 @@ void Avatar::initializeSkeleton() {
calculateBoneLengths();
_pelvisStandingHeight =
_bone[ AVATAR_BONE_PELVIS_SPINE ].length +
_bone[ AVATAR_BONE_LEFT_THIGH ].length +
_bone[ AVATAR_BONE_LEFT_FOOT ].radius +
_bone[ AVATAR_BONE_LEFT_SHIN ].length +
_bone[ AVATAR_BONE_LEFT_FOOT ].length +
_bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
_bone[ AVATAR_BONE_LEFT_THIGH ].length +
_bone[ AVATAR_BONE_PELVIS_SPINE ].length;
//printf( "_pelvisStandingHeight = %f\n", _pelvisStandingHeight );
_height =
(
_pelvisStandingHeight +
_bone[ AVATAR_BONE_MID_SPINE ].length +
_bone[ AVATAR_BONE_CHEST_SPINE].length +
_bone[ AVATAR_BONE_NECK ].length +
_bone[ AVATAR_BONE_HEAD ].length +
_bone[ AVATAR_BONE_HEAD ].radius
);
// generate world positions
updateSkeleton();
}
@ -1131,25 +1169,27 @@ void Avatar::renderBody() {
// Render bone positions as spheres
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
//renderBoneAsBlock( (AvatarBoneID)b);
//render bone orientation
//renderOrientationDirections( _bone[b].springyPosition, _bone[b].orientation, _bone[b].radius * 2.0 );
if ( _usingBodySprings ) {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( _bone[b].springyPosition.x, _bone[b].springyPosition.y, _bone[b].springyPosition.z );
glutSolidSphere( _bone[b].radius, 20.0f, 20.0f );
glPopMatrix();
}
else {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( _bone[b].position.x, _bone[b].position.y, _bone[b].position.z );
glutSolidSphere( _bone[b].radius, 20.0f, 20.0f );
glPopMatrix();
}
if ( b != AVATAR_BONE_HEAD ) { // the head is rendered as a special case in "renderHead"
//render bone orientation
//renderOrientationDirections( _bone[b].springyPosition, _bone[b].orientation, _bone[b].radius * 2.0 );
if ( _usingBodySprings ) {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( _bone[b].springyPosition.x, _bone[b].springyPosition.y, _bone[b].springyPosition.z );
glutSolidSphere( _bone[b].radius, 20.0f, 20.0f );
glPopMatrix();
}
else {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( _bone[b].position.x, _bone[b].position.y, _bone[b].position.z );
glutSolidSphere( _bone[b].radius, 20.0f, 20.0f );
glPopMatrix();
}
}
}
// Render lines connecting the bone positions
@ -1194,18 +1234,6 @@ void Avatar::renderBody() {
}
}
void Avatar::renderBoneAsBlock( AvatarBoneID b ) {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( _bone[b].springyPosition.x, _bone[b].springyPosition.y, _bone[b].springyPosition.z );
glScalef( _bone[b].radius, _bone[b].length, _bone[b].radius );
glRotatef(_bone[b].yaw, 0, 1, 0 );
glRotatef(_bone[b].pitch, 1, 0, 0 );
glRotatef(_bone[b].roll, 0, 0, 1 );
glutSolidCube(1.0);
glPopMatrix();
}
void Avatar::SetNewHeadTarget(float pitch, float yaw) {
_head.pitchTarget = pitch;
_head.yawTarget = yaw;

View file

@ -12,7 +12,6 @@
#include <AvatarData.h>
#include <Orientation.h>
#include "Field.h"
#include "world.h"
#include "AvatarTouch.h"
@ -32,11 +31,29 @@ 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;
const float COLLISION_BODY_RADIUS = 0.1;
const float COLLISION_HEIGHT = 1.5;
const float COLLISION_FRICTION = 0.5;
const float COLLISION_RADIUS_SCALAR = 1.8;
const float COLLISION_BALL_FORCE = 0.1;
const float COLLISION_BODY_FORCE = 3.0;
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
enum DriveKeys
{
FWD = 0,
BACK,
LEFT,
RIGHT,
UP,
DOWN,
ROT_LEFT,
ROT_RIGHT,
MAX_DRIVE_KEYS
};
/*
#define FWD 0
#define BACK 1
#define LEFT 2
@ -46,8 +63,9 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
#define ROT_LEFT 6
#define ROT_RIGHT 7
#define MAX_DRIVE_KEYS 8
*/
#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
//#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
@ -89,16 +107,8 @@ enum AvatarBoneID
NUM_AVATAR_BONES
};
struct AvatarCollisionElipsoid
{
bool colliding;
glm::vec3 position;
float girth;
float height;
glm::vec3 upVector;
};
struct AvatarHandHolding
struct AvatarHandHolding //think of this as one half of a distributed spring :)
{
glm::vec3 position;
glm::vec3 velocity;
@ -111,7 +121,7 @@ struct AvatarBone
glm::vec3 position; // the position at the "end" of the bone
glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose"
glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position)
glm::dvec3 springyVelocity; // used for special effects ( the velocity of the springy position)
glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position)
float springBodyTightness; // how tightly the springy position tries to stay on the position
glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation)
float yaw; // the yaw Euler angle of the bone rotation off the parent
@ -181,6 +191,8 @@ public:
float getBodyYaw() {return _bodyYaw;};
void addBodyYaw(float y) {_bodyYaw += y;};
bool getIsNearInteractingOther() { return _interactingOtherIsNearby; }
float getAbsoluteHeadYaw() const;
void setLeanForward(float dist);
void setLeanSideways(float dist);
@ -208,6 +220,7 @@ public:
void setHandMovementValues( glm::vec3 movement );
void updateHandMovement( float deltaTime );
void updateArmIKAndConstraints( float deltaTime );
void setDisplayingHead( bool displayingHead );
float getAverageLoudness() {return _head.averageLoudness;};
void setAverageLoudness(float al) {_head.averageLoudness = al;};
@ -260,25 +273,20 @@ private:
Avatar* _interactingOther;
bool _interactingOtherIsNearby;
float _pelvisStandingHeight;
float _height;
Balls* _balls;
AvatarTouch _avatarTouch;
bool _displayingHead; // should be false if in first-person view
// private methods...
void initializeSkeleton();
void updateSkeleton();
void initializeBodySprings();
void updateBodySprings( float deltaTime );
void calculateBoneLengths();
void readSensors();
void renderBoneAsBlock( AvatarBoneID b );
void updateAvatarCollisionDetectionAndResponse
(
glm::vec3 collisionPosition,
float collisionGirth,
float collisionHeight,
glm::vec3 collisionUpVector,
float deltaTime
);
// private methods...
void initializeSkeleton();
void updateSkeleton();
void initializeBodySprings();
void updateBodySprings( float deltaTime );
void calculateBoneLengths();
void readSensors();
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
void updateCollisionWithOtherAvatar( Avatar * other, float deltaTime );
};
#endif

View file

@ -15,10 +15,10 @@ Balls::Balls(int numberOfBalls) {
_numberOfBalls = numberOfBalls;
_balls = new Ball[_numberOfBalls];
for (unsigned int i = 0; i < _numberOfBalls; ++i) {
_balls[i].position = glm::vec3(1.0 + randFloat()*0.5,
0.5 + randFloat()*0.5,
1.0 + randFloat()*0.5);
_balls[i].radius = 0.02 + randFloat()*0.06;
_balls[i].position = glm::vec3(1.0 + randFloat() * 0.5,
0.5 + randFloat() * 0.5,
1.0 + randFloat() * 0.5);
_balls[i].radius = 0.02 + randFloat() * 0.06;
for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) {
_balls[i].links[j] = rand() % (numberOfBalls + 1);
if (_balls[i].links[j]-1 == i) { _balls[i].links[j] = 0; }
@ -42,7 +42,7 @@ void Balls::render() {
// Render springs
if (RENDER_SPRINGS) {
glColor3f(0.74,0.91,0.62);
glColor3f(0.74, 0.91, 0.62);
for (unsigned int i = 0; i < _numberOfBalls; ++i) {
glBegin(GL_LINES);
for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) {
@ -73,7 +73,7 @@ void Balls::simulate(float deltaTime) {
_balls[i].position += _balls[i].velocity * deltaTime;
// Drag: decay velocity
_balls[i].velocity *= (1.f - CONSTANT_VELOCITY_DAMPING*deltaTime);
_balls[i].velocity *= (1.f - CONSTANT_VELOCITY_DAMPING * deltaTime);
// Add noise
_balls[i].velocity += glm::vec3((randFloat() - 0.5) * NOISE_SCALE,

View file

@ -1,143 +0,0 @@
//
// Cloud.cpp
// interface
//
// Created by Philip Rosedale on 11/17/12.
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#include <iostream>
#include <InterfaceConfig.h>
#include "Cloud.h"
#include "Util.h"
#define COLOR_MIN 0.2f // minimum R/G/B value at 0,0,0 - also needs setting in field.cpp
Cloud::Cloud(int num,
glm::vec3 box,
int wrap) {
// Create and initialize particles
unsigned int i;
bounds = box;
count = num;
wrapBounds = wrap != 0;
particles = new Particle[count];
field = new Field();
for (i = 0; i < count; i++) {
float x = randFloat()*box.x;
float y = randFloat()*box.y;
float z = randFloat()*box.z;
particles[i].position.x = x;
particles[i].position.y = y;
particles[i].position.z = z;
particles[i].velocity.x = randFloat() - 0.5f;
particles[i].velocity.y = randFloat() - 0.5f;
particles[i].velocity.z = randFloat() - 0.5f;
float color_mult = 1 - COLOR_MIN;
particles[i].color = glm::vec3(x*color_mult/WORLD_SIZE + COLOR_MIN,
y*color_mult/WORLD_SIZE + COLOR_MIN,
z*color_mult/WORLD_SIZE + COLOR_MIN);
}
}
void Cloud::render() {
float particleAttenuationQuadratic[] = { 0.0f, 0.0f, 2.0f };
float particleAttenuationConstant[] = { 1.0f, 0.0f, 0.0f };
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
float maxSize = 0.0f;
glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize );
glPointSize( maxSize );
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, particleAttenuationQuadratic );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 0.001f );
glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
glEnable( GL_POINT_SPRITE_ARB );
glBegin( GL_POINTS );
for (unsigned int i = 0; i < count; i++)
{
glColor3f(particles[i].color.x,
particles[i].color.y,
particles[i].color.z);
glVertex3f(particles[i].position.x,
particles[i].position.y,
particles[i].position.z);
}
glEnd();
glDisable( GL_POINT_SPRITE_ARB );
glDisable( GL_TEXTURE_2D );
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, particleAttenuationConstant );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, 1.0f );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 0.0f );
}
void Cloud::simulate (float deltaTime) {
unsigned int i;
for (i = 0; i < count; ++i) {
// Update position
particles[i].position += particles[i].velocity*deltaTime;
//particles[i].position += particles[i].velocity;
// Decay Velocity (Drag)
const float CONSTANT_DAMPING = 0.5;
particles[i].velocity *= (1.f - CONSTANT_DAMPING*deltaTime);
// Interact with Field
const float FIELD_COUPLE = 0.005f; //0.0000001;
field->interact(deltaTime, &particles[i].position, &particles[i].velocity, &particles[i].color, FIELD_COUPLE);
// Update color to velocity
particles[i].color = (glm::normalize(particles[i].velocity)*0.5f);
particles[i].color += 0.5f;
// Bounce or Wrap
if (wrapBounds) {
// wrap around bounds
if (particles[i].position.x > bounds.x)
particles[i].position.x -= bounds.x;
else if (particles[i].position.x < 0.0f)
particles[i].position.x += bounds.x;
if (particles[i].position.y > bounds.y)
particles[i].position.y -= bounds.y;
else if (particles[i].position.y < 0.0f)
particles[i].position.y += bounds.y;
if (particles[i].position.z > bounds.z)
particles[i].position.z -= bounds.z;
else if (particles[i].position.z < 0.0f)
particles[i].position.z += bounds.z;
} else {
// Bounce at bounds
if (particles[i].position.x > bounds.x
|| particles[i].position.x < 0.f) {
if (particles[i].position.x > bounds.x) particles[i].position.x = bounds.x;
else particles[i].position.x = 0.f;
particles[i].velocity.x *= -1;
}
if (particles[i].position.y > bounds.y
|| particles[i].position.y < 0.f) {
if (particles[i].position.y > bounds.y) particles[i].position.y = bounds.y;
else particles[i].position.y = 0.f;
particles[i].velocity.y *= -1;
}
if (particles[i].position.z > bounds.z
|| particles[i].position.z < 0.f) {
if (particles[i].position.z > bounds.z) particles[i].position.z = bounds.z;
else particles[i].position.z = 0.f;
particles[i].velocity.z *= -1;
}
}
}
}

View file

@ -1,34 +0,0 @@
//
// Cloud.h
// interface
//
// Created by Philip Rosedale on 11/17/12.
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Cloud__
#define __interface__Cloud__
#include "Field.h"
class Cloud {
public:
Cloud(int num,
glm::vec3 box,
int wrap);
void simulate(float deltaTime);
void render();
private:
struct Particle {
glm::vec3 position, velocity, color;
} *particles;
unsigned int count;
glm::vec3 bounds;
bool wrapBounds;
Field *field;
};
#endif

View file

@ -1,229 +0,0 @@
//
// Field.cpp
// interface
//
// Created by Philip Rosedale on 8/23/12.
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#include "Field.h"
#define FIELD_SCALE 0.00050
#define FIELD_SCALEf 0.00050f
#define COLOR_DRIFT_RATE 0.001f // per-frame drift of particle color towards field element color
#define COLOR_MIN 0.2f // minimum R/G/B value at 0,0,0 - also needs setting in cloud.cpp
#define USE_SCALAR 0
// A vector-valued field over an array of elements arranged as a 3D lattice
int Field::value(float *value, float *pos)
// sets the vector value (3 floats) to field value at location pos in space.
// returns zero if the location is outside world bounds
{
int index = (int)(pos[0]/WORLD_SIZE*10.0) +
(int)(pos[1]/WORLD_SIZE*10.0)*10 +
(int)(pos[2]/WORLD_SIZE*10.0)*100;
if ((index >= 0) && (index < FIELD_ELEMENTS))
{
value[0] = field[index].val.x;
value[1] = field[index].val.y;
value[2] = field[index].val.z;
return 1;
}
else return 0;
}
Field::Field()
// Initializes the field to some random values
{
int i;
float fx, fy, fz;
for (i = 0; i < FIELD_ELEMENTS; i++)
{
field[i].val.x = (randFloat() - 0.5f)*FIELD_SCALEf;
field[i].val.y = (randFloat() - 0.5f)*FIELD_SCALEf;
field[i].val.z = (randFloat() - 0.5f)*FIELD_SCALEf;
field[i].scalar = 0;
// Record center point for this field cell
fx = static_cast<float>(i % 10);
fy = static_cast<float>(i%100 / 10);
fz = static_cast<float>(i / 100);
field[i].center.x = fx + 0.5f;
field[i].center.y = fy + 0.5f;
field[i].center.z = fz + 0.5f;
// and set up the RGB values for each field element.
float color_mult = 1 - COLOR_MIN;
fieldcolors[i].rgb = glm::vec3(((i%10)*(color_mult/10.0f)) + COLOR_MIN,
((i%100)*(color_mult/100.0f)) + COLOR_MIN,
(i*(color_mult/1000.0f)) + COLOR_MIN);
}
}
void Field::add(float* add, float *pos)
// At location loc, add vector add to the field values
{
int index = (int)(pos[0]/WORLD_SIZE*10.0) +
(int)(pos[1]/WORLD_SIZE*10.0)*10 +
(int)(pos[2]/WORLD_SIZE*10.0)*100;
if ((index >= 0) && (index < FIELD_ELEMENTS))
{
field[index].val.x += add[0];
field[index].val.y += add[1];
field[index].val.z += add[2];
}
}
void Field::interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * color, float coupling) {
int index = (int)(pos->x/WORLD_SIZE*10.0) +
(int)(pos->y/WORLD_SIZE*10.0)*10 +
(int)(pos->z/WORLD_SIZE*10.0)*100;
if ((index >= 0) && (index < FIELD_ELEMENTS)) {
//
// Vector Coupling with particle velocity
//
*vel += field[index].val*dt; // Particle influenced by field
glm::vec3 temp = *vel*dt; // Field influenced by particle
temp *= coupling;
field[index].val += temp;
//
// Scalar coupling: Damp particle as function of local density
//
if (USE_SCALAR) {
//*vel *= (1.f + field[index].scalar*0.01*dt);
const float SCALAR_PARTICLE_ADD = 1.0;
field[index].scalar += SCALAR_PARTICLE_ADD*dt;
}
// add a fraction of the field color to the particle color
//*color = (*color * (1 - COLOR_DRIFT_RATE)) + (fieldcolors[index].rgb * COLOR_DRIFT_RATE);
}
}
void Field::avg_neighbors(int index, glm::vec3 * result) {
// Given index to field element i, return neighbor field values
glm::vec3 neighbors(0,0,0);
int x,y,z;
x = (int)(index % 10);
y = (int)(index%100 / 10);
z = (int)(index / 100);
neighbors += field[(x+1)%10 + y*10 + z*100].val;
neighbors += field[(x-1)%10 + y*10 + z*100].val;
neighbors += field[x + ((y+1)%10)*10 + z*100].val;
neighbors += field[x + ((y-1)%10)*10 + z*100].val;
neighbors += field[x + y*10 + ((z+1)%10)*100].val;
neighbors += field[x%10 + y*10 + ((z-1)%10)*100].val;
neighbors /= 6;
result->x = neighbors.x;
result->y = neighbors.y;
result->z = neighbors.z;
}
void Field::simulate(float dt) {
glm::vec3 neighbors, add, diff;
float size, distance;
int i, j;
for (i = 0; i < FIELD_ELEMENTS; i++)
{
if (0) { //(randFloat() > 0.01) {
avg_neighbors(i, &neighbors);
size = powf(field[i].val.x*field[i].val.x +
field[i].val.y*field[i].val.y +
field[i].val.z*field[i].val.z, 0.5);
neighbors *= 0.0001;
field[i].val = glm::normalize(field[i].val);
field[i].val *= size * 0.99;
add = glm::normalize(neighbors);
add *= size * 0.01;
field[i].val += add;
}
else {
const float CONSTANT_DAMPING = 0.5;
const float CONSTANT_SCALAR_DAMPING = 2.5;
field[i].val *= (1.f - CONSTANT_DAMPING*dt);
field[i].scalar *= (1.f - CONSTANT_SCALAR_DAMPING*dt);
}
if (USE_SCALAR) {
//
// Compute a field value from sum of all other field values (electrostatics, etc)
//
field[i].fld.x = field[i].fld.y = field[i].fld.z = 0;
for (j = 0; j < FIELD_ELEMENTS; j++)
{
if (i != j) {
// Compute vector field from scalar densities
diff = field[j].center - field[i].center;
distance = glm::length(diff);
diff = glm::normalize(diff);
field[i].fld += diff*field[j].scalar*(1/distance);
}
}
}
}
}
void Field::render()
// Render the field lines
{
int i;
float fx, fy, fz;
float scale_view = 0.1f;
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
for (i = 0; i < FIELD_ELEMENTS; i++)
{
fx = field[i].center.x;
fy = field[i].center.y;
fz = field[i].center.z;
glColor3f(0, 1, 0);
glVertex3f(fx, fy, fz);
glVertex3f(fx + field[i].val.x*scale_view,
fy + field[i].val.y*scale_view,
fz + field[i].val.z*scale_view);
if (USE_SCALAR) {
glColor3f(1, 0, 0);
glVertex3f(fx, fy, fz);
glVertex3f(fx, fy+field[i].scalar*0.01f, fz);
glColor3f(1, 1, 0);
glVertex3f(fx, fy, fz);
glVertex3f(fx + field[i].fld.x*0.0001f,
fy + field[i].fld.y*0.0001f,
fz + field[i].fld.z*0.0001f);
}
}
glEnd();
glColor3f(0, 1, 0);
glPointSize(4.0);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
for (i = 0; i < FIELD_ELEMENTS; i++)
{
fx = static_cast<float>(i % 10);
fy = static_cast<float>(i%100 / 10);
fz = static_cast<float>(i / 100);
glVertex3f(fx, fy, fz);
}
glEnd();
}

View file

@ -1,45 +0,0 @@
//
// Field.h
// interface
//
// Created by Philip Rosedale on 8/23/12.
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Field__
#define __interface__Field__
#include <glm/glm.hpp>
#include "InterfaceConfig.h"
#include "world.h"
#include "Util.h"
// Field is a lattice of vectors uniformly distributed FIELD_ELEMENTS^(1/3) on side
const int FIELD_ELEMENTS = 1000;
class Field {
public:
struct FieldElement {
glm::vec3 val;
glm::vec3 center;
glm::vec3 fld;
float scalar;
} field[FIELD_ELEMENTS];
// Pre-calculated RGB values for each field element
struct FieldColor {
glm::vec3 rgb;
} fieldcolors[FIELD_ELEMENTS];
Field();
int value(float *ret, float *pos);
void render();
void add(float* add, float *loc);
void interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * color, float coupling);
void simulate(float dt);
glm::vec3 hsv2rgb(glm::vec3 in);
private:
void avg_neighbors(int index, glm::vec3 * result);
};
#endif

View file

@ -8,38 +8,123 @@
#include "Oscilloscope.h"
Oscilloscope::Oscilloscope(int w,
int h, bool isOn) {
width = w;
height = h;
data1 = new float[width];
data2 = new float[width];
for (int i = 0; i < width; i++) {
data1[i] = 0.0;
data2[i] = 0.0;
#include "InterfaceConfig.h"
#include <limits>
#include <cstring>
#include <algorithm>
// Reimplemented 4/26/13 (tosh) - don't blame Philip for bugs
using namespace std;
namespace { // everything in here only exists while compiling this .cpp file
// one sample buffer per channel
unsigned const N_SAMPLES_ALLOC = Oscilloscope::MAX_SAMPLES * Oscilloscope::MAX_CHANNELS;
// adding an x-coordinate yields twice the amount of vertices
unsigned const MAX_COORDS = Oscilloscope::MAX_SAMPLES * 2;
unsigned const N_COORDS_ALLOC = MAX_COORDS * Oscilloscope::MAX_CHANNELS;
unsigned const N_ALLOC_TOTAL = N_SAMPLES_ALLOC + N_COORDS_ALLOC;
}
Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) :
_valWidth(w), _valHeight(h),
_arrSamples(0l), _arrVertices(0l),
_valLowpass(0.4f), _valDownsample(3),
enabled(isEnabled), inputPaused(false) {
// allocate enough space for the sample data and to turn it into
// vertices and since they're all 'short', do so in one shot
_arrSamples = new short[N_ALLOC_TOTAL];
memset(_arrSamples, 0, N_ALLOC_TOTAL * sizeof(short));
_arrVertices = _arrSamples + N_SAMPLES_ALLOC;
// initialize write positions
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
_arrWritePos[ch] = MAX_SAMPLES * ch;
}
state = isOn;
current_sample = 0;
}
void Oscilloscope::addData(float d, int channel, int position) {
if (channel == 1) data1[position] = d;
else data2[position] = d;
Oscilloscope::~Oscilloscope() {
delete[] _arrSamples;
}
void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
if (! enabled || inputPaused) {
return;
}
unsigned baseOffs = MAX_SAMPLES * ch;
unsigned endOffs = baseOffs + MAX_SAMPLES;
unsigned writePos = _arrWritePos[ch];
unsigned newWritePos = writePos + n;
unsigned n2 = 0;
if (newWritePos >= endOffs) {
n2 = newWritePos - endOffs;
newWritePos = baseOffs + n2;
n -= n2;
}
memcpy(_arrSamples + writePos, data, n * sizeof(short));
if (n2 > 0) {
memcpy(_arrSamples + baseOffs, data + n, n2 * sizeof(short));
}
_arrWritePos[ch] = newWritePos;
}
void Oscilloscope::render() {
glColor3f(1,1,1);
glBegin(GL_LINES);
for (int i = 0; i < width; i++) {
glVertex2f((float)i, height/2 + data1[i]*(float)height);
if (! enabled) {
return;
}
glEnd();
glColor3f(0,1,1);
glBegin(GL_LINES);
for (int i = 0; i < width; i++) {
glVertex2f((float)i, height/2 + data2[i]*(float)height);
}
glEnd();
// expand data to vertex data, now
int lowpass = -int(std::numeric_limits<short>::min()) * _valLowpass;
unsigned downsample = _valDownsample;
// keep half of the buffer for writing and ensure an even vertex count
unsigned usedWidth = min(_valWidth, MAX_SAMPLES / (downsample * 2)) & ~1u;
unsigned usedSamples = usedWidth * downsample;
}
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
short const* basePtr = _arrSamples + MAX_SAMPLES * ch;
short const* endPtr = basePtr + MAX_SAMPLES;
short const* inPtr = _arrSamples + _arrWritePos[ch];
short* outPtr = _arrVertices + MAX_COORDS * ch;
int sample = 0, x = usedWidth;
for (int i = int(usedSamples); --i >= 0 ;) {
if (inPtr == basePtr) {
inPtr = endPtr;
}
sample += ((*--inPtr - sample) * lowpass) >> 15;
if (i % downsample == 0) {
*outPtr++ = short(--x);
*outPtr++ = short(sample);
}
}
}
glPushMatrix();
glTranslatef(0.0f, _valHeight / 2.0f, 0.0f);
glScaled(1.0f, _valHeight / 32767.0f, 1.0f);
glVertexPointer(2, GL_SHORT, 0, _arrVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColor3f(1.0f, 1.0f, 1.0f);
glDrawArrays(GL_LINES, MAX_SAMPLES * 0, usedWidth);
glColor3f(0.0f, 1.0f ,1.0f);
glDrawArrays(GL_LINES, MAX_SAMPLES * 1, usedWidth);
glColor3f(1.0f, 1.0f ,0.0f);
glDrawArrays(GL_LINES, MAX_SAMPLES * 2, usedWidth);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}

View file

@ -9,24 +9,45 @@
#ifndef __interface__Oscilloscope__
#define __interface__Oscilloscope__
#include <glm/glm.hpp>
#include "Util.h"
#include "world.h"
#include "InterfaceConfig.h"
#include <cassert>
class Oscilloscope {
public:
Oscilloscope(int width,
int height, bool isOn);
void addData(float d, int channel, int position);
void render();
void setState(bool s) {state = s;};
bool getState() {return state;};
static unsigned const MAX_CHANNELS = 3;
static unsigned const MAX_SAMPLES = 4096; // per channel
private:
int width;
int height;
float *data1, *data2;
int current_sample;
bool state;
unsigned _valWidth;
unsigned _valHeight;
short* _arrSamples;
short* _arrVertices;
unsigned _arrWritePos[MAX_CHANNELS];
float _valLowpass;
unsigned _valDownsample;
public:
Oscilloscope(int width, int height, bool isEnabled);
~Oscilloscope();
volatile bool enabled;
volatile bool inputPaused;
void addSamples(unsigned ch, short const* data, unsigned n);
void render();
void setLowpass(float w) { assert(w > 0.0f && w <= 1.0f); _valLowpass = w; }
void setDownsampling(unsigned f) { assert(f > 0); _valDownsample = f; }
private:
// don't copy/assign
Oscilloscope(Oscilloscope const&); // = delete;
Oscilloscope& operator=(Oscilloscope const&); // = delete;
// implementation
inline short* bufferBase(int i, int channel);
};
#endif /* defined(__interface__oscilloscope__) */

View file

@ -50,7 +50,6 @@
#include "voxels_Log.h"
#include "avatars_Log.h"
#include "Field.h"
#include "world.h"
#include "Util.h"
#ifndef _WIN32
@ -67,7 +66,6 @@
#include "ChatEntry.h"
#include "Avatar.h"
#include "Texture.h"
#include "Cloud.h"
#include <AgentList.h>
#include <AgentTypes.h>
#include "VoxelSystem.h"
@ -124,13 +122,7 @@ bool showingVoxels = true;
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
Cloud cloud(0, // Particles
box, // Bounding Box
false // Wrap
);
VoxelSystem voxels;
Field field;
#ifndef _WIN32
Audio audio(&audioScope, &myAvatar);
@ -139,10 +131,6 @@ Audio audio(&audioScope, &myAvatar);
#define IDLE_SIMULATE_MSECS 8 // How often should call simulate and other stuff
// in the idle loop?
float startYaw = 122.f;
float renderYawRate = 0.f;
float renderPitchRate = 0.f;
// Where one's own agent begins in the world (needs to become a dynamic thing passed to the program)
glm::vec3 start_location(6.1f, 0, 1.4f);
@ -158,11 +146,10 @@ bool logOn = true; // Whether to show on-screen log
int noiseOn = 0; // Whether to add random noise
float noise = 1.0; // Overall magnitude scaling for random noise levels
bool gyroLook = false; // Whether to allow the gyro data from head to move your view
bool gyroLook = true; // Whether to allow the gyro data from head to move your view
int displayLevels = 0;
bool lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror?
int displayField = 0;
int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement
int headMouseX, headMouseY;
@ -312,7 +299,6 @@ void init(void)
{
voxels.init();
voxels.setViewerAvatar(&myAvatar);
myAvatar.setRenderYaw(startYaw);
handControl.setScreenDimensions(WIDTH, HEIGHT);
@ -320,10 +306,7 @@ void init(void)
headMouseY = HEIGHT/2;
stars.readInput(starFile, starCacheFile, 0);
// Initialize Field values
field = Field();
if (noiseOn) {
myAvatar.setNoise(noise);
}
@ -365,13 +348,7 @@ void terminate () {
void reset_sensors()
{
//
// Reset serial I/O sensors
//
myAvatar.setRenderYaw(startYaw);
renderYawRate = 0;
renderPitchRate = 0;
myAvatar.setPosition(start_location);
headMouseX = WIDTH/2;
headMouseY = HEIGHT/2;
@ -409,28 +386,30 @@ void updateAvatar(float frametime)
headMouseY = max(headMouseY, 0);
headMouseY = min(headMouseY, HEIGHT);
// Update render direction (pitch/yaw) based on measured gyro rates
const float MIN_YAW_RATE = 5;
const float YAW_SENSITIVITY = 1.0;
// If enabled, Update render pitch and yaw based on gyro data
if (::gyroLook) {
if (fabs(gyroYawRate) > MIN_YAW_RATE) {
myAvatar.addBodyYaw(-gyroYawRate * YAW_SENSITIVITY * frametime);
}
}
float renderPitch = myAvatar.getRenderPitch();
// Decay renderPitch toward zero because we never look constantly up/down
renderPitch *= (1.f - 2.0*frametime);
// Update head and body pitch and yaw based on measured gyro rates
if (::gyroLook) {
// Yaw
const float MIN_YAW_RATE = 50;
const float YAW_SENSITIVITY = 1.0;
// Decay angular rates toward zero
renderPitchRate *= (1.f - 5.0*frametime);
renderYawRate *= (1.f - 7.0*frametime);
// Update own avatar data
myAvatar.setRenderYaw(myAvatar.getRenderYaw() + renderYawRate);
myAvatar.setRenderPitch(renderPitch + renderPitchRate);
if (fabs(gyroYawRate) > MIN_YAW_RATE) {
float addToBodyYaw = (gyroYawRate > 0.f)
? gyroYawRate - MIN_YAW_RATE : gyroYawRate + MIN_YAW_RATE;
myAvatar.addBodyYaw(-addToBodyYaw * YAW_SENSITIVITY * frametime);
}
// Pitch NOTE: PER - Need to make camera able to pitch first!
/*
const float MIN_PITCH_RATE = 50;
const float PITCH_SENSITIVITY = 1.0;
if (fabs(gyroPitchRate) > MIN_PITCH_RATE) {
float addToBodyPitch = (gyroPitchRate > 0.f)
? gyroPitchRate - MIN_PITCH_RATE : gyroPitchRate + MIN_PITCH_RATE;
myAvatar.addBodyPitch(addToBodyPitch * PITCH_SENSITIVITY * frametime);
*/
}
// Get audio loudness data from audio input device
#ifndef _WIN32
@ -720,9 +699,9 @@ void display(void)
GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 }; //{ 0.125, 0.305, 0.5 };
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 }; //{ 0.5, 0.42, 0.33 };
GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
@ -742,9 +721,14 @@ void display(void)
myCamera.setTightness ( 100.0f );
} else {
//float firstPersonPitch = 20.0f;
//float firstPersonUpShift = 0.0f;
//float firstPersonDistance = 0.0f;
//float firstPersonTightness = 100.0f;
float firstPersonPitch = 20.0f;
float firstPersonUpShift = 0.1f;
float firstPersonDistance = 0.0f;
float firstPersonDistance = 0.4f;
float firstPersonTightness = 100.0f;
float thirdPersonPitch = 0.0f;
@ -753,14 +737,44 @@ void display(void)
float thirdPersonTightness = 8.0f;
if ( USING_FIRST_PERSON_EFFECT ) {
float ff = 0.0;
float min = 0.1;
float max = 0.5;
if ( myAvatar.getIsNearInteractingOther()){
if ( myAvatar.getSpeed() < max ) {
float s = (myAvatar.getSpeed()- min)/max ;
ff = 1.0 - s;
}
}
/*
if ( ff < 0.8 ) {
myAvatar.setDisplayingHead( true );
} else {
myAvatar.setDisplayingHead( false );
}
*/
//printf( "ff = %f\n", ff );
myCamera.setPitch ( thirdPersonPitch + ff * ( firstPersonPitch - thirdPersonPitch ));
myCamera.setUpShift ( thirdPersonUpShift + ff * ( firstPersonUpShift - thirdPersonUpShift ));
myCamera.setDistance ( thirdPersonDistance + ff * ( firstPersonDistance - thirdPersonDistance ));
myCamera.setTightness ( thirdPersonTightness + ff * ( firstPersonTightness - thirdPersonTightness ));
// this version uses a ramp-up/ramp-down timer in the camera to determine shift between first and thirs-person view
/*
if ( myAvatar.getSpeed() < 0.02 ) {
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
}
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
//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 ));
@ -770,13 +784,14 @@ void display(void)
myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
}
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
//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 );
@ -834,19 +849,6 @@ void display(void)
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
/*
// Test - Draw a blue sphere around a body part of mine!
glPushMatrix();
glColor4f(0,0,1, 0.7);
glTranslatef(myAvatar.getBonePosition(AVATAR_BONE_RIGHT_HAND).x,
myAvatar.getBonePosition(AVATAR_BONE_RIGHT_HAND).y,
myAvatar.getBonePosition(AVATAR_BONE_RIGHT_HAND).z);
glutSolidSphere(0.03, 10, 10);
glPopMatrix();
*/
// draw a red sphere
float sphereRadius = 0.25f;
glColor3f(1,0,0);
@ -854,21 +856,15 @@ void display(void)
glutSolidSphere( sphereRadius, 15, 15 );
glPopMatrix();
//draw a grid gound plane....
//draw a grid ground plane....
drawGroundPlaneGrid( 5.0f, 9 );
// Draw cloud of dots
if (!::lookingInMirror) cloud.render();
// Draw voxels
if ( showingVoxels )
{
voxels.render();
}
// Draw field vectors
if (displayField) field.render();
// Render avatars of other agents
AgentList* agentList = AgentList::getInstance();
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
@ -900,7 +896,7 @@ void display(void)
#ifndef _WIN32
audio.render(WIDTH, HEIGHT);
if (audioScope.getState()) audioScope.render();
audioScope.render();
#endif
if (displayHeadMouse && !::lookingInMirror && statsOn) {
@ -1007,10 +1003,6 @@ int setHead(int state) {
return setValue(state, &::lookingInMirror);
}
int setField(int state) {
return setValue(state, &displayField);
}
int setNoise(int state) {
int iRet = setValue(state, &noiseOn);
if (noiseOn) {
@ -1161,7 +1153,6 @@ void initMenu() {
menuColumnRender = menu.addColumn("Render");
menuColumnRender->addRow("Voxels (V)", setVoxels);
menuColumnRender->addRow("Stars (*)", setStars);
menuColumnRender->addRow("Field (f)", setField);
// Tools
menuColumnTools = menu.addColumn("Tools");
@ -1399,16 +1390,13 @@ void key(unsigned char k, int x, int y)
if (k == 'm' || k == 'M') setMenu(MENU_ROW_PICKED);
if (k == 'f') displayField = !displayField;
if (k == 'l') displayLevels = !displayLevels;
if (k == 'e') myAvatar.setDriveKeys(UP, 1);
if (k == 'c') myAvatar.setDriveKeys(DOWN, 1);
if (k == 'w') myAvatar.setDriveKeys(FWD, 1);
if (k == 's') myAvatar.setDriveKeys(BACK, 1);
if (k == ' ') reset_sensors();
if (k == 't') renderPitchRate -= KEYBOARD_PITCH_RATE;
if (k == 'g') renderPitchRate += KEYBOARD_PITCH_RATE;
if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1);
if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1);
if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 1);
if (k == '\r') {
@ -1505,9 +1493,7 @@ void idle(void) {
}
}
field.simulate (deltaTime);
myAvatar.simulate(deltaTime);
cloud.simulate (deltaTime);
glutPostRedisplay();
lastTimeIdle = check;