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) 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; 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]; char bufchar[1];
while (read(serial_fd, bufchar, 1) > 0) 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 // At end - Extract value from string to variables
if (serial_buffer[0] != 'p') 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[0],
&adc_channels[1], &adc_channels[1],
&adc_channels[2], &adc_channels[2],
&adc_channels[3], &adc_channels[3],
&adc_channels[4], &adc_channels[4]
&adc_channels[5], );
&adc_channels[6],
&adc_channels[7]);
for (int i = 0; i < NUM_CHANNELS; i++) for (int i = 0; i < NUM_CHANNELS; i++)
{ {
if (!first_measurement) if (!first_measurement)
avg_adc_channels[i] = (1.f - AVG_RATE)*avg_adc_channels[i] + avg_adc_channels[i] = (1.f - AVG_RATE[i])*avg_adc_channels[i] +
AVG_RATE*(float)adc_channels[i]; AVG_RATE[i]*(float)adc_channels[i];
else else
{ {
avg_adc_channels[i] = (float)adc_channels[i]; avg_adc_channels[i] = (float)adc_channels[i];

View file

@ -9,7 +9,7 @@
int init_port (int baud); int init_port (int baud);
int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_channels); int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_channels);
#define NUM_CHANNELS 8 #define NUM_CHANNELS 5
#define SERIAL_PORT_NAME "/dev/tty.usbmodem411" #define SERIAL_PORT_NAME "/dev/tty.usbmodem641"
#endif #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) { void field_avg_neighbors(int index, glm::vec3 * result) {
// Given index to field element i, return neighbor field values // Given index to field element i, return neighbor field values
glm::vec3 neighbors(0,0,0); 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); int field_value(float *ret, float *pos);
void field_render(); void field_render();
void field_add(float* add, float *loc); void field_add(float* add, float *loc);
void field_interact(glm::vec3 * pos, glm::vec3 * vel, float coupling);
void field_simulate(float dt); 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 #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 // ADC PIN MAPPINGS
// //
// 0, 1 = Head Pitch, Yaw gyro // 15,16 = Head Pitch, Yaw gyro
// 2,3,4 = Head Accelerometer // 17,18,19 = Head Accelerometer
// 10,11,12 = Hand 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]; int measured[NUM_CHANNELS];
float accumulate[NUM_CHANNELS]; float accumulate[NUM_CHANNELS];
@ -29,6 +29,7 @@ void setup()
accumulate[i] = measured[i]; accumulate[i] = measured[i];
} }
pinMode(BOARD_LED_PIN, OUTPUT); pinMode(BOARD_LED_PIN, OUTPUT);
time = millis();
} }
void loop() void loop()
@ -36,17 +37,22 @@ void loop()
int i; int i;
sampleCount++; sampleCount++;
for (i = 0; i < NUM_CHANNELS; i++) { for (i = 0; i < NUM_CHANNELS; i++) {
if (sampleCount % AVERAGE_COUNT == 0) { accumulate[i] += analogRead(inputPins[i]);
measured[i] = accumulate[i] / AVERAGE_COUNT; }
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(measured[i]);
SerialUSB.print(" "); SerialUSB.print(" ");
accumulate[i] = 0; accumulate[i] = 0;
} else {
accumulate[i] += analogRead(inputPins[i]);
} }
//SerialUSB.print("(");
//SerialUSB.print(sampleCount);
//SerialUSB.print(")");
SerialUSB.println("");
sampleCount = 0;
} }
if (sampleCount % AVERAGE_COUNT == 0) SerialUSB.println("");
if (sampleCount % TOGGLE_LED_SAMPLES == 0) toggleLED();
} }

View file

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

5
head.h
View file

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

View file

@ -15,6 +15,7 @@
B6BDADE315F44AB0002A07DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */; }; B6BDADE315F44AB0002A07DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */; };
B6BDADE415F44AC7002A07DF /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDC15F444D3002A07DF /* AudioUnit.framework */; }; B6BDADE415F44AC7002A07DF /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDC15F444D3002A07DF /* AudioUnit.framework */; };
B6BDAE4415F6BE53002A07DF /* particle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6BDAE4315F6BE53002A07DF /* particle.cpp */; }; 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 */; }; D40BDFD513404BA300B0BE1F /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40BDFD413404BA300B0BE1F /* GLUT.framework */; };
D40BDFD713404BB300B0BE1F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40BDFD613404BB300B0BE1F /* OpenGL.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 */; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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; }; D40FD5FA164AF1A700878184 /* int-texture256-v2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "int-texture256-v2.png"; sourceTree = SOURCE_ROOT; };
@ -134,6 +137,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
08FB7796FE84155DC02AAC07 /* main.cpp */, 08FB7796FE84155DC02AAC07 /* main.cpp */,
D409B988165849030099B0B3 /* cloud.h */,
D409B989165849180099B0B3 /* cloud.cpp */,
D4EE3BC015E746E900EE4C89 /* world.h */, D4EE3BC015E746E900EE4C89 /* world.h */,
B6BDAE4315F6BE53002A07DF /* particle.cpp */, B6BDAE4315F6BE53002A07DF /* particle.cpp */,
B6BDAE4115F6BE4D002A07DF /* particle.h */, B6BDAE4115F6BE4D002A07DF /* particle.h */,
@ -261,6 +266,7 @@
D4EFE3D0162A2DA000DC5C59 /* hand.cpp in Sources */, D4EFE3D0162A2DA000DC5C59 /* hand.cpp in Sources */,
F68135561648617D003040E3 /* texture.cpp in Sources */, F68135561648617D003040E3 /* texture.cpp in Sources */,
F681358B1648896D003040E3 /* lodepng.cpp in Sources */, F681358B1648896D003040E3 /* lodepng.cpp in Sources */,
D409B98A165849180099B0B3 /* cloud.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View file

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

View file

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