Merge branch 'master' of git://github.com/worklist/interface

Conflicts:
	main.cpp
This commit is contained in:
Yoz Grahame 2012-11-19 12:56:38 -08:00
commit 2bc588f4d0
14 changed files with 344 additions and 124 deletions

BIN
.DS_Store vendored

Binary file not shown.

View file

@ -58,8 +58,12 @@ int init_port(int baud)
int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_channels)
{
// Channels:
// 0, 1 = Head Pitch and Yaw
// 2,3,4 = Head XYZ Acceleration
//
int samples_read = 0;
const float AVG_RATE = 0.001; // 0.00001;
const float AVG_RATE[] = {0.001, 0.001, 0.01, 0.01, 0.01};
char bufchar[1];
while (read(serial_fd, bufchar, 1) > 0)
{
@ -72,20 +76,18 @@ int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_chan
// At end - Extract value from string to variables
if (serial_buffer[0] != 'p')
{
sscanf(serial_buffer, "%d %d %d %d %d %d %d %d", /* Needs to match Num Channels */
sscanf(serial_buffer, "%d %d %d %d %d", /* Needs to match Num Channels */
&adc_channels[0],
&adc_channels[1],
&adc_channels[2],
&adc_channels[3],
&adc_channels[4],
&adc_channels[5],
&adc_channels[6],
&adc_channels[7]);
&adc_channels[4]
);
for (int i = 0; i < NUM_CHANNELS; i++)
{
if (!first_measurement)
avg_adc_channels[i] = (1.f - AVG_RATE)*avg_adc_channels[i] +
AVG_RATE*(float)adc_channels[i];
avg_adc_channels[i] = (1.f - AVG_RATE[i])*avg_adc_channels[i] +
AVG_RATE[i]*(float)adc_channels[i];
else
{
avg_adc_channels[i] = (float)adc_channels[i];

View file

@ -9,7 +9,7 @@
int init_port (int baud);
int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_channels);
#define NUM_CHANNELS 8
#define SERIAL_PORT_NAME "/dev/tty.usbmodem411"
#define NUM_CHANNELS 5
#define SERIAL_PORT_NAME "/dev/tty.usbmodem641"
#endif

119
cloud.cpp Normal file
View file

@ -0,0 +1,119 @@
//
// cloud.cpp
// interface
//
// Created by Philip Rosedale on 11/17/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#include <iostream>
#include "cloud.h"
#include "util.h"
Cloud::Cloud(int num,
glm::vec3 box,
int wrap) {
// Create and initialize particles
int i;
bounds = box;
count = num;
wrapBounds = wrap;
particles = new Particle[count];
for (i = 0; i < count; i++) {
particles[i].position.x = randFloat()*box.x;
particles[i].position.y = randFloat()*box.y;
particles[i].position.z = randFloat()*box.z;
particles[i].velocity.x = 0; //randFloat() - 0.5;
particles[i].velocity.y = 0; //randFloat() - 0.5;
particles[i].velocity.z = 0; //randFloat() - 0.5;
}
}
void Cloud::render() {
float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.0f };
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, particle_attenuation_quadratic );
float maxSize = 0.0f;
glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize );
glPointSize( maxSize );
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 (int i = 0; i < count; i++)
{
glVertex3f(particles[i].position.x,
particles[i].position.y,
particles[i].position.z);
}
glEnd();
glDisable( GL_POINT_SPRITE_ARB );
glDisable( GL_TEXTURE_2D );
}
void Cloud::simulate (float deltaTime) {
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 = 1.0;
particles[i].velocity *= (1.f - CONSTANT_DAMPING*deltaTime);
// Interact with Field
const float FIELD_COUPLE = 0.0000001;
field_interact(&particles[i].position, &particles[i].velocity, FIELD_COUPLE);
// 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;
}
}
}
}

32
cloud.h Normal file
View file

@ -0,0 +1,32 @@
//
// cloud.h
// interface
//
// Created by Philip Rosedale on 11/17/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#ifndef interface_cloud_h
#define interface_cloud_h
#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;
} *particles;
unsigned int count;
glm::vec3 bounds;
bool wrapBounds;
};
#endif

View file

@ -60,6 +60,21 @@ void field_add(float* add, float *pos)
}
}
void field_interact(glm::vec3 * pos, glm::vec3 * vel, 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)) {
// Add velocity to particle from field
*vel += field[index].val;
// Add back to field from particle velocity
glm::vec3 temp = *vel;
temp *= coupling;
field[index].val += temp;
}
}
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);

12
field.h
View file

@ -27,17 +27,7 @@ void field_init();
int field_value(float *ret, float *pos);
void field_render();
void field_add(float* add, float *loc);
void field_interact(glm::vec3 * pos, glm::vec3 * vel, float coupling);
void field_simulate(float dt);
class Field {
public:
static void init ();
static int addTo (const glm::vec3 &pos, glm::vec3 &v);
private:
const static unsigned int fieldSize = 1000;
const static float fieldScale; // defined in cpp inline const float definitions not allowed in standard C++?! (allowed in C++0x)
static glm::vec3 field[fieldSize];
};
#endif

View file

@ -4,16 +4,16 @@ Read a set of analog input lines and echo their readings over the serial port wi
// ADC PIN MAPPINGS
//
// 0, 1 = Head Pitch, Yaw gyro
// 2,3,4 = Head Accelerometer
// 10,11,12 = Hand Accelerometer
// 15,16 = Head Pitch, Yaw gyro
// 17,18,19 = Head Accelerometer
#define NUM_CHANNELS 8
#define AVERAGE_COUNT 100
#define TOGGLE_LED_SAMPLES 1000
int inputPins[NUM_CHANNELS] = {0,1,2,3,4,10,11,12};
#define NUM_CHANNELS 5
#define MSECS_PER_SAMPLE 10
int inputPins[NUM_CHANNELS] = {19,20,15,16,17};
unsigned int time;
int measured[NUM_CHANNELS];
float accumulate[NUM_CHANNELS];
@ -29,24 +29,30 @@ void setup()
accumulate[i] = measured[i];
}
pinMode(BOARD_LED_PIN, OUTPUT);
time = millis();
}
void loop()
{
int i;
sampleCount++;
sampleCount++;
for (i = 0; i < NUM_CHANNELS; i++) {
if (sampleCount % AVERAGE_COUNT == 0) {
measured[i] = accumulate[i] / AVERAGE_COUNT;
SerialUSB.print(measured[i]);
SerialUSB.print(" ");
accumulate[i] = 0;
} else {
accumulate[i] += analogRead(inputPins[i]);
}
accumulate[i] += analogRead(inputPins[i]);
}
if (sampleCount % AVERAGE_COUNT == 0) SerialUSB.println("");
if (sampleCount % TOGGLE_LED_SAMPLES == 0) toggleLED();
if ((millis() - time) >= MSECS_PER_SAMPLE) {
time = millis();
for (i = 0; i < NUM_CHANNELS; i++) {
measured[i] = accumulate[i] / sampleCount;
SerialUSB.print(measured[i]);
SerialUSB.print(" ");
accumulate[i] = 0;
}
//SerialUSB.print("(");
//SerialUSB.print(sampleCount);
//SerialUSB.print(")");
SerialUSB.println("");
sampleCount = 0;
}
}

View file

@ -43,6 +43,8 @@ Head::Head()
PitchTarget = YawTarget = 0;
NoiseEnvelope = 1.0;
PupilConverge = 2.1;
leanForward = 0.0;
leanSideways = 0.0;
setNoise(0);
}
@ -51,10 +53,22 @@ void Head::reset()
position = glm::vec3(0,0,0);
Pitch = 0;
Yaw = 0;
leanForward = leanSideways = 0;
}
// Read the sensors
void readSensors()
{
}
void Head::addLean(float x, float z) {
// Add Body lean as impulse
leanSideways += x;
leanForward += z;
}
// Simulate the head over time
void Head::simulate(float deltaTime)
{
if (!noise)
@ -71,6 +85,9 @@ void Head::simulate(float deltaTime)
Roll *= (1.f - DECAY*deltaTime);
}
leanForward *= (1.f - DECAY*30.f*deltaTime);
leanSideways *= (1.f - DECAY*30.f*deltaTime);
if (noise)
{
Pitch += (randFloat() - 0.5)*0.05*NoiseEnvelope;
@ -118,6 +135,7 @@ void Head::render()
glPushMatrix();
glLoadIdentity();
glTranslatef(0.f, 0.f, -7.f);
glTranslatef(leanSideways, 0.f, leanForward);
glRotatef(Yaw/2.0, 0, 1, 0);
glRotatef(Pitch/2.0, 1, 0, 0);
glRotatef(Roll/2.0, 0, 0, 1);
@ -160,6 +178,7 @@ void Head::render()
}
glPopMatrix();
// Mouth
glPushMatrix();
glTranslatef(0,-0.3,0.75);

5
head.h
View file

@ -34,6 +34,8 @@ class Head {
float MouthYaw;
float MouthWidth;
float MouthHeight;
float leanForward;
float leanSideways;
float PitchTarget;
float YawTarget;
@ -44,6 +46,8 @@ class Head {
glm::vec3 position;
void readSensors();
public:
Head(void);
void reset();
@ -52,6 +56,7 @@ public:
void setYaw(float y) {Yaw = y; }
void addPitch(float p) {Pitch -= p; }
void addYaw(float y){Yaw -= y; }
void addLean(float x, float z);
void getPitch(float);
void render();
void simulate(float);

View file

@ -15,6 +15,7 @@
B6BDADE315F44AB0002A07DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */; };
B6BDADE415F44AC7002A07DF /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDC15F444D3002A07DF /* AudioUnit.framework */; };
B6BDAE4415F6BE53002A07DF /* particle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6BDAE4315F6BE53002A07DF /* particle.cpp */; };
D409B98A165849180099B0B3 /* cloud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D409B989165849180099B0B3 /* cloud.cpp */; };
D40BDFD513404BA300B0BE1F /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40BDFD413404BA300B0BE1F /* GLUT.framework */; };
D40BDFD713404BB300B0BE1F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40BDFD613404BB300B0BE1F /* OpenGL.framework */; };
D40FD5FB164AF1C200878184 /* int-texture256-v2.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = D40FD5FA164AF1A700878184 /* int-texture256-v2.png */; };
@ -66,6 +67,8 @@
B6BDAE4115F6BE4D002A07DF /* particle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = particle.h; sourceTree = "<group>"; };
B6BDAE4315F6BE53002A07DF /* particle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = particle.cpp; sourceTree = "<group>"; };
C6859E8B029090EE04C91782 /* test_c_plus.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = test_c_plus.1; sourceTree = "<group>"; };
D409B988165849030099B0B3 /* cloud.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cloud.h; sourceTree = "<group>"; };
D409B989165849180099B0B3 /* cloud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cloud.cpp; sourceTree = "<group>"; };
D40BDFD413404BA300B0BE1F /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = /System/Library/Frameworks/GLUT.framework; sourceTree = "<absolute>"; };
D40BDFD613404BB300B0BE1F /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
D40FD5FA164AF1A700878184 /* int-texture256-v2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "int-texture256-v2.png"; sourceTree = SOURCE_ROOT; };
@ -134,6 +137,8 @@
isa = PBXGroup;
children = (
08FB7796FE84155DC02AAC07 /* main.cpp */,
D409B988165849030099B0B3 /* cloud.h */,
D409B989165849180099B0B3 /* cloud.cpp */,
D4EE3BC015E746E900EE4C89 /* world.h */,
B6BDAE4315F6BE53002A07DF /* particle.cpp */,
B6BDAE4115F6BE4D002A07DF /* particle.h */,
@ -261,6 +266,7 @@
D4EFE3D0162A2DA000DC5C59 /* hand.cpp in Sources */,
F68135561648617D003040E3 /* texture.cpp in Sources */,
F681358B1648896D003040E3 /* lodepng.cpp in Sources */,
D409B98A165849180099B0B3 /* cloud.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -8,11 +8,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "field.cpp"
timestampString = "372274896.176083"
timestampString = "374955033.430214"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "83"
endingLineNumber = "83"
startingLineNumber = "98"
endingLineNumber = "98"
landmarkName = "field_avg_neighbors(int index, glm::vec3 * result)"
landmarkType = "7">
</FileBreakpoint>

188
main.cpp
View file

@ -49,12 +49,16 @@
#include "texture.h"
#include "cloud.h"
//TGAImg Img;
using namespace std;
// Junk for talking to the Serial Port
int serial_on = 0; // Is serial connection on/off? System will try
int audio_on = 0; // Whether to turn on the audio support
int simulate_on = 1;
// Network Socket Stuff
// For testing, add milliseconds of delay for received UDP packets
@ -73,6 +77,8 @@ int bytescount = 0;
int target_x, target_y;
int target_display = 0;
int head_mirror = 0; // Whether to mirror the head when viewing it
unsigned char last_key = 0;
double ping = 0;
@ -89,15 +95,18 @@ Hand myHand(HAND_RADIUS,
glm::vec3(0,1,1)); // My hand (used to manipulate things in world)
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
ParticleSystem balls(1000,
ParticleSystem balls(0,
box,
false, // Wrap?
0.02, // Noise
false, // Wrap?
0.02, // Noise
0.3, // Size scale
0.0 // Gravity
0.0 // Gravity
);
Cloud cloud(250000, // Particles
box, // Bounding Box
false // Wrap
);
// FIELD INFORMATION
// If the simulation 'world' is a box with 10M boundaries, the offset to a field cell is given by:
@ -112,15 +121,11 @@ ParticleSystem balls(1000,
#define RENDER_FRAME_MSECS 10
#define SLEEP 0
#define NUM_TRIS 100000
#define NUM_TRIS 0
struct {
float vertices[NUM_TRIS * 3];
// float normals [NUM_TRIS * 3];
// float colors [NUM_TRIS * 3];
float vel [NUM_TRIS * 3];
glm::vec3 vel1[NUM_TRIS];
glm::vec3 vel2[NUM_TRIS];
int element[NUM_TRIS];
}tris;
@ -153,8 +158,9 @@ int display_head = 0;
int display_hand = 0;
int display_field = 0;
int display_head_mouse = 1; // Display sample mouse pointer controlled by head movement
int head_mouse_x, head_mouse_y;
int display_head_mouse = 1; // Display sample mouse pointer controlled by head movement
int head_mouse_x, head_mouse_y;
int head_lean_x, head_lean_y;
int mouse_x, mouse_y; // Where is the mouse
int mouse_pressed = 0; // true if mouse has been pressed (clear when finished)
@ -194,7 +200,7 @@ double elapsedTime;
// 1. Add to the XCode project in the Resources/images group
// (ensure "Copy file" is checked
// 2. Add to the "Copy files" build phase in the project
char texture_filename[] = "int-texture256-v4.png";
char texture_filename[] = "./int-texture256-v4.png";
unsigned int texture_width = 256;
unsigned int texture_height = 256;
@ -264,8 +270,10 @@ void init(void)
load_png_as_texture(texture_filename);
printf("Texture loaded.\n");
Audio::init();
printf( "Audio started.\n" );
if (audio_on) {
Audio::init();
printf( "Audio started.\n" );
}
// Clear serial channels
for (i = i; i < NUM_CHANNELS; i++)
@ -276,6 +284,8 @@ void init(void)
head_mouse_x = WIDTH/2;
head_mouse_y = HEIGHT/2;
head_lean_x = WIDTH/2;
head_lean_y = HEIGHT/2;
// Initialize Field values
field_init();
@ -316,7 +326,6 @@ void init(void)
//tris.normals[i*3+2] = pos.z;
// Moving - white
tris.element[i] = 1;
//tris.colors[i*3] = 1.0; tris.colors[i*3+1] = 1.0; tris.colors[i*3+2] = 1.0;
tris.vel[i*3] = (randFloat() - 0.5)*VEL_SCALE;
tris.vel[i*3+1] = (randFloat() - 0.5)*VEL_SCALE;
@ -349,7 +358,9 @@ void terminate () {
// Close serial port
//close(serial_fd);
Audio::terminate();
if (audio_on) {
Audio::terminate();
}
exit(EXIT_SUCCESS);
}
@ -365,39 +376,34 @@ void update_tris()
float field_contrib[3];
for (i = 0; i < NUM_TRIS; i++)
{
if (tris.element[i] == 1) // If moving object, move and drag
{
// Update position
tris.vertices[i*3+0] += tris.vel[i*3];
tris.vertices[i*3+1] += tris.vel[i*3+1];
tris.vertices[i*3+2] += tris.vel[i*3+2];
// Add a little gravity
//tris.vel[i*3+1] -= 0.0001;
const float DRAG = 0.99;
// Drag: Decay velocity
tris.vel[i*3] *= DRAG;
tris.vel[i*3+1] *= DRAG;
tris.vel[i*3+2] *= DRAG;
}
// Update position
tris.vertices[i*3+0] += tris.vel[i*3];
tris.vertices[i*3+1] += tris.vel[i*3+1];
tris.vertices[i*3+2] += tris.vel[i*3+2];
// Add a little gravity
//tris.vel[i*3+1] -= 0.0001;
const float DRAG = 0.99;
// Drag: Decay velocity
tris.vel[i*3] *= DRAG;
tris.vel[i*3+1] *= DRAG;
tris.vel[i*3+2] *= DRAG;
if (tris.element[i] == 1)
{
// Read and add velocity from field
field_value(field_val, &tris.vertices[i*3]);
tris.vel[i*3] += field_val[0];
tris.vel[i*3+1] += field_val[1];
tris.vel[i*3+2] += field_val[2];
// Read and add velocity from field
field_value(field_val, &tris.vertices[i*3]);
tris.vel[i*3] += field_val[0];
tris.vel[i*3+1] += field_val[1];
tris.vel[i*3+2] += field_val[2];
// Add a tiny bit of energy back to the field
const float FIELD_COUPLE = 0.0000001;
field_contrib[0] = tris.vel[i*3]*FIELD_COUPLE;
field_contrib[1] = tris.vel[i*3+1]*FIELD_COUPLE;
field_contrib[2] = tris.vel[i*3+2]*FIELD_COUPLE;
field_add(field_contrib, &tris.vertices[i*3]);
// Add a tiny bit of energy back to the field
const float FIELD_COUPLE = 0.0000001;
field_contrib[0] = tris.vel[i*3]*FIELD_COUPLE;
field_contrib[1] = tris.vel[i*3+1]*FIELD_COUPLE;
field_contrib[2] = tris.vel[i*3+2]*FIELD_COUPLE;
field_add(field_contrib, &tris.vertices[i*3]);
}
// bounce at edge of world
for (j=0; j < 3; j++) {
if ((tris.vertices[i*3+j] > WORLD_SIZE) || (tris.vertices[i*3+j] < 0.0)) {
@ -424,6 +430,9 @@ void reset_sensors()
fwd_vel = 0.0;
head_mouse_x = WIDTH/2;
head_mouse_y = HEIGHT/2;
head_lean_x = WIDTH/2;
head_lean_y = HEIGHT/2;
myHead.reset();
myHand.reset();
if (serial_on) read_sensors(1, &avg_adc_channels[0], &adc_channels[0]);
@ -434,12 +443,21 @@ void update_pos(float frametime)
{
float measured_pitch_rate = adc_channels[0] - avg_adc_channels[0];
float measured_yaw_rate = adc_channels[1] - avg_adc_channels[1];
float measured_lateral_accel = adc_channels[2] - avg_adc_channels[2];
float measured_fwd_accel = avg_adc_channels[3] - adc_channels[3];
float measured_lateral_accel = adc_channels[3] - avg_adc_channels[3];
float measured_fwd_accel = avg_adc_channels[2] - adc_channels[2];
// Update avatar head position based on measured gyro rates
myHead.addYaw(measured_yaw_rate * 1.20 * frametime);
myHead.addPitch(measured_pitch_rate * -1.0 * frametime);
const float HEAD_ROTATION_SCALE = 0.10;
const float HEAD_LEAN_SCALE = 0.02;
if (head_mirror) {
myHead.addYaw(measured_yaw_rate * HEAD_ROTATION_SCALE * frametime);
myHead.addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
myHead.addLean(measured_lateral_accel * frametime * HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE);
} else {
myHead.addYaw(measured_yaw_rate * -HEAD_ROTATION_SCALE * frametime);
myHead.addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
myHead.addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE);
}
// Decay avatar head back toward zero
//pitch *= (1.f - 5.0*frametime);
//yaw *= (1.f - 7.0*frametime);
@ -459,6 +477,7 @@ void update_pos(float frametime)
head_mouse_y = min(head_mouse_y, HEIGHT);
// Update hand/manipulator location for measured forces from serial channel
/*
const float MIN_HAND_ACCEL = 30.0;
const float HAND_FORCE_SCALE = 0.5;
glm::vec3 hand_accel(-(avg_adc_channels[6] - adc_channels[6]),
@ -469,6 +488,7 @@ void update_pos(float frametime)
{
myHand.addVel(frametime*hand_accel*HAND_FORCE_SCALE);
}
*/
// Update render direction (pitch/yaw) based on measured gyro rates
const int MIN_YAW_RATE = 300;
@ -594,23 +614,25 @@ void display(void)
glPointSize( maxSize );
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 (i = 0; i < NUM_TRIS; i++)
{
glVertex3f(tris.vertices[i*3],
tris.vertices[i*3+1],
tris.vertices[i*3+2]);
}
}
glEnd();
glDisable( GL_TEXTURE_2D );
glDisable( GL_POINT_SPRITE_ARB );
glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
glEnable( GL_POINT_SPRITE_ARB );
if (!display_head) {
glBegin( GL_POINTS );
{
for (i = 0; i < NUM_TRIS; i++)
{
glVertex3f(tris.vertices[i*3],
tris.vertices[i*3+1],
tris.vertices[i*3+2]);
}
}
glEnd();
}
glDisable( GL_POINT_SPRITE_ARB );
glDisable( GL_TEXTURE_2D );
if (!display_head) cloud.render();
// Show field vectors
if (display_field) field_render();
@ -619,10 +641,10 @@ void display(void)
if (display_hand) myHand.render();
balls.render();
if (!display_head) balls.render();
// Render the world box
render_world_box();
if (!display_head) render_world_box();
glPopMatrix();
@ -635,10 +657,10 @@ void display(void)
glDisable(GL_LIGHTING);
//drawvec3(100, 100, 0.15, 0, 1.0, 0, myHead.getPos(), 0, 1, 0);
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, pointer_attenuation_quadratic );
if (mouse_pressed == 1)
{
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, pointer_attenuation_quadratic );
glPointSize( 10.0f );
glColor3f(1,1,1);
//glEnable(GL_POINT_SMOOTH);
@ -649,7 +671,7 @@ void display(void)
sprintf(val, "%d,%d", target_x, target_y);
drawtext(target_x, target_y-20, 0.08, 0, 1.0, 0, val, 0, 1, 0);
}
if (display_head_mouse)
if (display_head_mouse && !display_head)
{
glPointSize(10.0f);
glColor4f(1.0, 1.0, 0.0, 0.8);
@ -706,7 +728,7 @@ void key(unsigned char k, int x, int y)
if (k == '/') stats_on = !stats_on; // toggle stats
if (k == 'n')
{
noise_on = !noise_on; // Toggle noise
noise_on = !noise_on; // Toggle noise
if (noise_on)
{
myHand.setNoise(noise);
@ -731,6 +753,7 @@ void key(unsigned char k, int x, int y)
if (k == ' ') reset_sensors();
if (k == 'a') render_yaw_rate -= 0.25;
if (k == 'd') render_yaw_rate += 0.25;
if (k == 'o') simulate_on = !simulate_on;
if (k == 'p')
{
// Add to field vector
@ -738,7 +761,7 @@ void key(unsigned char k, int x, int y)
float add[] = {0.001, 0.001, 0.001};
field_add(add, pos);
}
if (k == 't') {
if ((k == 't') && (audio_on)) {
Audio::writeTone(0, 400, 1.0f, 0.5f);
}
if (k == '1')
@ -780,11 +803,14 @@ void idle(void)
{
// Simulation
update_pos(1.f/FPS);
update_tris();
field_simulate(1.f/FPS);
myHead.simulate(1.f/FPS);
myHand.simulate(1.f/FPS);
balls.simulate(1.f/FPS);
if (simulate_on) {
update_tris();
field_simulate(1.f/FPS);
myHead.simulate(1.f/FPS);
myHand.simulate(1.f/FPS);
balls.simulate(1.f/FPS);
cloud.simulate(1.f/FPS);
}
if (!step_on) glutPostRedisplay();
last_frame = check;