From 69277ec8bac727cbf7827f1a5ece484216313e27 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Oct 2013 21:49:13 -0700 Subject: [PATCH 01/13] Added back field and cloud files --- interface/src/Cloud.cpp | 141 +++++++++++++++++++++++++ interface/src/Cloud.h | 34 ++++++ interface/src/Field.cpp | 229 ++++++++++++++++++++++++++++++++++++++++ interface/src/Field.h | 46 ++++++++ 4 files changed, 450 insertions(+) create mode 100644 interface/src/Cloud.cpp create mode 100644 interface/src/Cloud.h create mode 100644 interface/src/Field.cpp create mode 100644 interface/src/Field.h diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp new file mode 100644 index 0000000000..e612d042a9 --- /dev/null +++ b/interface/src/Cloud.cpp @@ -0,0 +1,141 @@ +// +// Cloud.cpp +// interface +// +// Created by Philip Rosedale on 11/17/12. +// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. +// + +#include +#include +#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 particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.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, particle_attenuation_quadratic ); + 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 ); +} + +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; + } + } + } + } diff --git a/interface/src/Cloud.h b/interface/src/Cloud.h new file mode 100644 index 0000000000..06cb5a9d7d --- /dev/null +++ b/interface/src/Cloud.h @@ -0,0 +1,34 @@ +// +// 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 diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp new file mode 100644 index 0000000000..8471d05b0d --- /dev/null +++ b/interface/src/Field.cpp @@ -0,0 +1,229 @@ +// +// 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(i % 10); + fy = static_cast(i%100 / 10); + fz = static_cast(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(i % 10); + fy = static_cast(i%100 / 10); + fz = static_cast(i / 100); + + glVertex3f(fx, fy, fz); + } + glEnd(); +} + + + diff --git a/interface/src/Field.h b/interface/src/Field.h new file mode 100644 index 0000000000..e8b5eff2a9 --- /dev/null +++ b/interface/src/Field.h @@ -0,0 +1,46 @@ +// +// 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 +#include +#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 From ce2e31ddd5589f6f2317bf92c9fd6ddbd92d2024 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Oct 2013 22:21:55 -0700 Subject: [PATCH 02/13] reconnecting particle cloud --- interface/src/Application.cpp | 9 ++++++++- interface/src/Application.h | 3 +++ interface/src/Cloud.cpp | 17 ++++++++++------- interface/src/Cloud.h | 4 +--- interface/src/Field.cpp | 2 ++ interface/src/Field.h | 2 ++ interface/src/world.h | 4 +--- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46a2b9afde..ce4aa3cd79 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1972,6 +1972,9 @@ void Application::update(float deltaTime) { _myAvatar.simulate(deltaTime, NULL); } + // Simulate particle cloud movements + _cloud.simulate(deltaTime); + // no transmitter drive implies transmitter pick if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) { _transmitterPickStart = _myAvatar.getSkeleton().joint[AVATAR_JOINT_CHEST].position; @@ -2489,7 +2492,10 @@ void Application::displaySide(Camera& whichCamera) { glDisable(GL_NORMALIZE); //renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude()); - } + } + // Draw Cloud Particles + _cloud.render(); + // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), @@ -2499,6 +2505,7 @@ void Application::displaySide(Camera& whichCamera) { } } + // restore default, white specular glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR); diff --git a/interface/src/Application.h b/interface/src/Application.h index 620d6d57f5..c3c5b8220e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -29,6 +29,7 @@ #include "BandwidthMeter.h" #include "Camera.h" +#include "Cloud.h" #include "Environment.h" #include "GLCanvas.h" #include "PacketHeaders.h" @@ -261,6 +262,8 @@ private: Stars _stars; + Cloud _cloud; + VoxelSystem _voxels; VoxelTree _clipboard; // if I copy/paste VoxelImporter _voxelImporter; diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index e612d042a9..e1149b8355 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -10,17 +10,19 @@ #include #include "Cloud.h" #include "Util.h" +#include "Field.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) { +const int NUM_PARTICLES = 20000; + +#define COLOR_MIN 0.2f + +Cloud::Cloud() { // Create and initialize particles unsigned int i; - bounds = box; - count = num; - wrapBounds = wrap != 0; + glm::vec3 box = glm::vec3(WORLD_SIZE); + count = NUM_PARTICLES; + wrapBounds = false; particles = new Particle[count]; field = new Field(); @@ -80,6 +82,7 @@ void Cloud::render() { void Cloud::simulate (float deltaTime) { unsigned int i; + field->simulate(deltaTime); for (i = 0; i < count; ++i) { // Update position diff --git a/interface/src/Cloud.h b/interface/src/Cloud.h index 06cb5a9d7d..507ca2c9c9 100644 --- a/interface/src/Cloud.h +++ b/interface/src/Cloud.h @@ -13,9 +13,7 @@ class Cloud { public: - Cloud(int num, - glm::vec3 box, - int wrap); + Cloud(); void simulate(float deltaTime); void render(); diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 8471d05b0d..0beb9e0cf0 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -15,6 +15,8 @@ #define USE_SCALAR 0 +#define WORLD_SIZE 100.0 + // A vector-valued field over an array of elements arranged as a 3D lattice int Field::value(float *value, float *pos) diff --git a/interface/src/Field.h b/interface/src/Field.h index e8b5eff2a9..bca1415f09 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -15,6 +15,8 @@ #include "world.h" #include "Util.h" +#define WORLD_SIZE 100.0 + // Field is a lattice of vectors uniformly distributed FIELD_ELEMENTS^(1/3) on side const int FIELD_ELEMENTS = 1000; diff --git a/interface/src/world.h b/interface/src/world.h index f53db4ff49..a226dc228e 100644 --- a/interface/src/world.h +++ b/interface/src/world.h @@ -4,9 +4,7 @@ // // Created by Philip Rosedale on 8/23/12. // Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -// Simulation happens in positive cube with edge of size WORLD_SIZE +// #ifndef __interface__world__ #define __interface__world__ From 906f3c8c60d4c4a422e01e24b51ce74889a776da Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Oct 2013 23:15:29 -0700 Subject: [PATCH 03/13] got basic cloud working --- interface/src/Cloud.cpp | 22 +++++++++++++++------- interface/src/Field.cpp | 24 ++++++++++++------------ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index e1149b8355..3f4b0b2c82 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -21,6 +21,7 @@ Cloud::Cloud() { // Create and initialize particles unsigned int i; glm::vec3 box = glm::vec3(WORLD_SIZE); + bounds = box; count = NUM_PARTICLES; wrapBounds = false; particles = new Particle[count]; @@ -33,10 +34,10 @@ Cloud::Cloud() { 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; + + const float INIT_VEL_SCALE = 0.10; + particles[i].velocity = randVector(); + particles[i].velocity *= WORLD_SIZE * INIT_VEL_SCALE; float color_mult = 1 - COLOR_MIN; particles[i].color = glm::vec3(x*color_mult/WORLD_SIZE + COLOR_MIN, @@ -48,12 +49,13 @@ Cloud::Cloud() { void Cloud::render() { + field->render(); + /* float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.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 ); @@ -65,6 +67,12 @@ void Cloud::render() { glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE ); glEnable( GL_POINT_SPRITE_ARB ); + */ + glPointSize(3.0f); + glDisable(GL_TEXTURE_2D); + + glEnable(GL_POINT_SMOOTH); + glBegin( GL_POINTS ); for (unsigned int i = 0; i < count; i++) { @@ -90,7 +98,7 @@ void Cloud::simulate (float deltaTime) { //particles[i].position += particles[i].velocity; // Decay Velocity (Drag) - const float CONSTANT_DAMPING = 0.5; + const float CONSTANT_DAMPING = 0.15; particles[i].velocity *= (1.f - CONSTANT_DAMPING*deltaTime); // Interact with Field diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 0beb9e0cf0..5015a3e9f5 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -9,7 +9,7 @@ #include "Field.h" #define FIELD_SCALE 0.00050 -#define FIELD_SCALEf 0.00050f +#define FIELD_SCALEf 0.1f #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 @@ -43,9 +43,9 @@ Field::Field() 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].val.x = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; + field[i].val.y = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; + field[i].val.z = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; field[i].scalar = 0; // Record center point for this field cell fx = static_cast(i % 10); @@ -182,21 +182,21 @@ void Field::render() { int i; float fx, fy, fz; - float scale_view = 0.1f; + float scale_view = 0.1f * WORLD_SIZE; 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; + fx = field[i].center.x * WORLD_SIZE; + fy = field[i].center.y * WORLD_SIZE; + fz = field[i].center.z * WORLD_SIZE; 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); + 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); @@ -222,7 +222,7 @@ void Field::render() fy = static_cast(i%100 / 10); fz = static_cast(i / 100); - glVertex3f(fx, fy, fz); + glVertex3f(fx / 10.f * WORLD_SIZE, fy / 10.f * WORLD_SIZE, fz / 10.f * WORLD_SIZE); } glEnd(); } From 58d6c4c97aafe8a218744f9124e8d2062cc319c0 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 14:28:00 -0700 Subject: [PATCH 04/13] Cleaning up particle code --- interface/src/Application.cpp | 9 ++- interface/src/Cloud.cpp | 12 ++-- interface/src/Cloud.h | 2 + interface/src/Field.cpp | 130 +++++++++------------------------- interface/src/Field.h | 6 +- interface/src/Menu.cpp | 3 + interface/src/Menu.h | 1 + 7 files changed, 55 insertions(+), 108 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ddcd98ece8..3849d6f618 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1988,7 +1988,9 @@ void Application::update(float deltaTime) { } // Simulate particle cloud movements - _cloud.simulate(deltaTime); + if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) { + _cloud.simulate(deltaTime); + } // no transmitter drive implies transmitter pick if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) { @@ -2508,8 +2510,9 @@ void Application::displaySide(Camera& whichCamera) { //renderGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE, _audio.getCollisionSoundMagnitude()); } // Draw Cloud Particles - _cloud.render(); - + if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) { + _cloud.render(); + } // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index 3f4b0b2c82..3f434a8cd6 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -20,12 +20,12 @@ const int NUM_PARTICLES = 20000; Cloud::Cloud() { // Create and initialize particles unsigned int i; - glm::vec3 box = glm::vec3(WORLD_SIZE); + glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE); bounds = box; count = NUM_PARTICLES; wrapBounds = false; particles = new Particle[count]; - field = new Field(); + field = new Field(PARTICLE_WORLD_SIZE); for (i = 0; i < count; i++) { float x = randFloat()*box.x; @@ -37,12 +37,12 @@ Cloud::Cloud() { const float INIT_VEL_SCALE = 0.10; particles[i].velocity = randVector(); - particles[i].velocity *= WORLD_SIZE * INIT_VEL_SCALE; + particles[i].velocity *= PARTICLE_WORLD_SIZE * INIT_VEL_SCALE; 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); + particles[i].color = glm::vec3(x*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN, + y*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN, + z*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN); } } diff --git a/interface/src/Cloud.h b/interface/src/Cloud.h index 507ca2c9c9..35784db843 100644 --- a/interface/src/Cloud.h +++ b/interface/src/Cloud.h @@ -11,6 +11,8 @@ #include "Field.h" +#define PARTICLE_WORLD_SIZE 128.0 + class Cloud { public: Cloud(); diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 5015a3e9f5..6876d732a1 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -9,13 +9,9 @@ #include "Field.h" #define FIELD_SCALE 0.00050 -#define FIELD_SCALEf 0.1f #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 - -#define WORLD_SIZE 100.0 // A vector-valued field over an array of elements arranged as a 3D lattice @@ -23,9 +19,10 @@ 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; + int index = (int)(pos[0] / _worldSize * 10.0) + + (int)(pos[1] / _worldSize * 10.0) * 10 + + (int)(pos[2] / _worldSize * 10.0) * 100; + if ((index >= 0) && (index < FIELD_ELEMENTS)) { value[0] = field[index].val.x; @@ -36,24 +33,25 @@ int Field::value(float *value, float *pos) else return 0; } -Field::Field() +Field::Field(float worldSize) // Initializes the field to some random values { + _worldSize = worldSize; int i; float fx, fy, fz; for (i = 0; i < FIELD_ELEMENTS; i++) { - field[i].val.x = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; - field[i].val.y = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; - field[i].val.z = (randFloat() - 0.5f)*FIELD_SCALEf * WORLD_SIZE; + const float FIELD_INITIAL_MAG = 0.3f; + field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; field[i].scalar = 0; // Record center point for this field cell fx = static_cast(i % 10); - fy = static_cast(i%100 / 10); + fy = static_cast(i % 100 / 10); fz = static_cast(i / 100); - field[i].center.x = fx + 0.5f; - field[i].center.y = fy + 0.5f; - field[i].center.z = fz + 0.5f; + field[i].center.x = (fx + 0.5f); + field[i].center.y = (fy + 0.5f); + field[i].center.z = (fz + 0.5f); + field[i].center *= _worldSize / 10.f; // and set up the RGB values for each field element. float color_mult = 1 - COLOR_MIN; @@ -66,9 +64,10 @@ Field::Field() 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; + int index = (int)(pos[0] / _worldSize * 10.0) + + (int)(pos[1] / _worldSize * 10.0)*10 + + (int)(pos[2] / _worldSize * 10.0)*100; + if ((index >= 0) && (index < FIELD_ELEMENTS)) { field[index].val.x += add[0]; @@ -79,9 +78,9 @@ void Field::add(float* add, float *pos) 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; + int index = (int)(pos->x/ _worldSize * 10.0) + + (int)(pos->y/_worldSize*10.0)*10 + + (int)(pos->z/_worldSize*10.0)*100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { // // Vector Coupling with particle velocity @@ -95,13 +94,6 @@ void Field::interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * col // 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); } @@ -134,80 +126,31 @@ void Field::avg_neighbors(int index, glm::vec3 * result) { void Field::simulate(float dt) { glm::vec3 neighbors, add, diff; - float size, distance; - int i, j; - for (i = 0; i < FIELD_ELEMENTS; i++) + + for (int 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); - } - } - } - } + 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); + } } void Field::render() // Render the field lines { int i; - float fx, fy, fz; - float scale_view = 0.1f * WORLD_SIZE; + float scale_view = 0.05f * _worldSize; glDisable(GL_LIGHTING); glBegin(GL_LINES); for (i = 0; i < FIELD_ELEMENTS; i++) - { - fx = field[i].center.x * WORLD_SIZE; - fy = field[i].center.y * WORLD_SIZE; - fz = field[i].center.z * WORLD_SIZE; - + { 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); - } - + glVertex3fv(&field[i].center.x); + glVertex3f(field[i].center.x + field[i].val.x * scale_view, + field[i].center.y + field[i].val.y * scale_view, + field[i].center.z + field[i].val.z * scale_view); } glEnd(); @@ -215,14 +158,9 @@ void Field::render() glPointSize(4.0); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); - for (i = 0; i < FIELD_ELEMENTS; i++) { - fx = static_cast(i % 10); - fy = static_cast(i%100 / 10); - fz = static_cast(i / 100); - - glVertex3f(fx / 10.f * WORLD_SIZE, fy / 10.f * WORLD_SIZE, fz / 10.f * WORLD_SIZE); + glVertex3fv(&field[i].center.x); } glEnd(); } diff --git a/interface/src/Field.h b/interface/src/Field.h index bca1415f09..44d3388206 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -15,8 +15,6 @@ #include "world.h" #include "Util.h" -#define WORLD_SIZE 100.0 - // Field is a lattice of vectors uniformly distributed FIELD_ELEMENTS^(1/3) on side const int FIELD_ELEMENTS = 1000; @@ -34,7 +32,8 @@ class Field { glm::vec3 rgb; } fieldcolors[FIELD_ELEMENTS]; - Field(); + Field(float worldSize); + int value(float *ret, float *pos); void render(); void add(float* add, float *loc); @@ -43,6 +42,7 @@ class Field { glm::vec3 hsv2rgb(glm::vec3 in); private: void avg_neighbors(int index, glm::vec3 * result); + float _worldSize; }; #endif diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0f5e3fc58e..23743f3cc3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -234,6 +234,9 @@ Menu::Menu() : 0, appInstance->getGlowEffect(), SLOT(cycleRenderMode())); + + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false); + QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index f54d3767a1..ed7f0adce4 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -169,6 +169,7 @@ namespace MenuOption { const QString GoHome = "Go Home"; const QString Gravity = "Use Gravity"; const QString GroundPlane = "Ground Plane"; + const QString ParticleCloud = "Particle Cloud"; const QString GyroLook = "Smooth Gyro Look"; const QString ListenModeNormal = "Listen Mode Normal"; const QString ListenModePoint = "Listen Mode Point"; From 85a15a22fac8b35427211f4e20e5435714558e3c Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 15:10:03 -0700 Subject: [PATCH 05/13] Further code cleanup on particle cloud --- interface/src/Cloud.cpp | 122 ++++++++++------------------------------ interface/src/Cloud.h | 3 +- interface/src/Field.cpp | 30 +++------- interface/src/Field.h | 7 +-- 4 files changed, 40 insertions(+), 122 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index 3f434a8cd6..7ab2418573 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -12,10 +12,7 @@ #include "Util.h" #include "Field.h" - -const int NUM_PARTICLES = 20000; - -#define COLOR_MIN 0.2f +const int NUM_PARTICLES = 100000; Cloud::Cloud() { // Create and initialize particles @@ -23,57 +20,24 @@ Cloud::Cloud() { glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE); bounds = box; count = NUM_PARTICLES; - wrapBounds = false; particles = new Particle[count]; field = new Field(PARTICLE_WORLD_SIZE); 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; - - const float INIT_VEL_SCALE = 0.10; - particles[i].velocity = randVector(); - particles[i].velocity *= PARTICLE_WORLD_SIZE * INIT_VEL_SCALE; - - float color_mult = 1 - COLOR_MIN; - particles[i].color = glm::vec3(x*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN, - y*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN, - z*color_mult/PARTICLE_WORLD_SIZE + COLOR_MIN); - } + particles[i].position = randVector() * box; + const float INIT_VEL_SCALE = 0.03f; + particles[i].velocity = randVector() * ((float)PARTICLE_WORLD_SIZE * INIT_VEL_SCALE); + particles[i].color = randVector(); + } } - void Cloud::render() { + //field->render(); - field->render(); - /* - float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.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, particle_attenuation_quadratic ); - 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 ); - */ glPointSize(3.0f); glDisable(GL_TEXTURE_2D); - glEnable(GL_POINT_SMOOTH); - - glBegin( GL_POINTS ); + glBegin(GL_POINTS); for (unsigned int i = 0; i < count; i++) { glColor3f(particles[i].color.x, @@ -84,8 +48,6 @@ void Cloud::render() { particles[i].position.z); } glEnd(); - glDisable( GL_POINT_SPRITE_ARB ); - glDisable( GL_TEXTURE_2D ); } void Cloud::simulate (float deltaTime) { @@ -94,59 +56,35 @@ void Cloud::simulate (float deltaTime) { for (i = 0; i < count; ++i) { // Update position - particles[i].position += particles[i].velocity*deltaTime; - //particles[i].position += particles[i].velocity; + particles[i].position += particles[i].velocity * deltaTime; // Decay Velocity (Drag) - const float CONSTANT_DAMPING = 0.15; - particles[i].velocity *= (1.f - CONSTANT_DAMPING*deltaTime); + const float CONSTANT_DAMPING = 0.15f; + 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); + const float FIELD_COUPLE = 0.005f; + 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; + particles[i].color = (glm::normalize(particles[i].velocity) * 0.5f) + 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; - } + // Bounce at bounds + if ((particles[i].position.x > bounds.x) || (particles[i].position.x < 0.f)) { + particles[i].position.x = glm::clamp(particles[i].position.x, 0.f, bounds.x); + particles[i].velocity.x *= -1.f; + } + if ((particles[i].position.y > bounds.y) || (particles[i].position.y < 0.f)) { + particles[i].position.y = glm::clamp(particles[i].position.y, 0.f, bounds.y); + particles[i].velocity.y *= -1.f; + } + if ((particles[i].position.z > bounds.z) || (particles[i].position.z < 0.f)) { + particles[i].position.z = glm::clamp(particles[i].position.z, 0.f, bounds.z); + particles[i].velocity.z *= -1.f; } } } diff --git a/interface/src/Cloud.h b/interface/src/Cloud.h index 35784db843..44ff8c54a6 100644 --- a/interface/src/Cloud.h +++ b/interface/src/Cloud.h @@ -11,7 +11,7 @@ #include "Field.h" -#define PARTICLE_WORLD_SIZE 128.0 +#define PARTICLE_WORLD_SIZE 256.0 class Cloud { public: @@ -27,7 +27,6 @@ private: unsigned int count; glm::vec3 bounds; - bool wrapBounds; Field *field; }; diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 6876d732a1..eb6cdf0682 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -8,11 +8,6 @@ #include "Field.h" -#define FIELD_SCALE 0.00050 -#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 - - // A vector-valued field over an array of elements arranged as a 3D lattice int Field::value(float *value, float *pos) @@ -30,7 +25,9 @@ int Field::value(float *value, float *pos) value[2] = field[index].val.z; return 1; } - else return 0; + else { + return 0; + } } Field::Field(float worldSize) @@ -41,7 +38,7 @@ Field::Field(float worldSize) float fx, fy, fz; for (i = 0; i < FIELD_ELEMENTS; i++) { - const float FIELD_INITIAL_MAG = 0.3f; + const float FIELD_INITIAL_MAG = 0.0f; field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; field[i].scalar = 0; // Record center point for this field cell @@ -53,11 +50,6 @@ Field::Field(float worldSize) field[i].center.z = (fz + 0.5f); field[i].center *= _worldSize / 10.f; - // 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); } } @@ -76,8 +68,8 @@ void Field::add(float* add, float *pos) } } -void Field::interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * color, float coupling) { - +void Field::interact(float dt, glm::vec3* pos, glm::vec3* vel, glm::vec3* color, float coupling) { + int index = (int)(pos->x/ _worldSize * 10.0) + (int)(pos->y/_worldSize*10.0)*10 + (int)(pos->z/_worldSize*10.0)*100; @@ -85,17 +77,11 @@ void Field::interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * col // // Vector Coupling with particle velocity // - *vel += field[index].val*dt; // Particle influenced by field + *vel += field[index].val * dt; // Particle influenced by field - glm::vec3 temp = *vel*dt; // Field influenced by particle + glm::vec3 temp = *vel * dt; // Field influenced by particle temp *= coupling; field[index].val += temp; - // - // Scalar coupling: Damp particle as function of local density - // - - // add a fraction of the field color to the particle color - //*color = (*color * (1 - COLOR_DRIFT_RATE)) + (fieldcolors[index].rgb * COLOR_DRIFT_RATE); } } diff --git a/interface/src/Field.h b/interface/src/Field.h index 44d3388206..8198521b4a 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -26,12 +26,7 @@ class Field { 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(float worldSize); int value(float *ret, float *pos); From ab4b09ca3913528fff48601d7a4d2816041b8604 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 16:03:06 -0700 Subject: [PATCH 06/13] More coding standard fixes to particle cloud --- interface/src/Cloud.cpp | 67 +++++++++++++++++----------------- interface/src/Cloud.h | 9 +++-- interface/src/Field.cpp | 80 ++++++++++++++--------------------------- interface/src/Field.h | 4 +-- 4 files changed, 65 insertions(+), 95 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index 7ab2418573..bfa5129d14 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -16,18 +16,17 @@ const int NUM_PARTICLES = 100000; Cloud::Cloud() { // Create and initialize particles - unsigned int i; glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE); - bounds = box; - count = NUM_PARTICLES; - particles = new Particle[count]; - field = new Field(PARTICLE_WORLD_SIZE); + _bounds = box; + _count = NUM_PARTICLES; + _particles = new Particle[_count]; + _field = new Field(PARTICLE_WORLD_SIZE); - for (i = 0; i < count; i++) { - particles[i].position = randVector() * box; + for (int i = 0; i < _count; i++) { + _particles[i].position = randVector() * box; const float INIT_VEL_SCALE = 0.03f; - particles[i].velocity = randVector() * ((float)PARTICLE_WORLD_SIZE * INIT_VEL_SCALE); - particles[i].color = randVector(); + _particles[i].velocity = randVector() * ((float)PARTICLE_WORLD_SIZE * INIT_VEL_SCALE); + _particles[i].color = randVector(); } } @@ -38,53 +37,53 @@ void Cloud::render() { glDisable(GL_TEXTURE_2D); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); - for (unsigned int i = 0; i < count; i++) + 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); + 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(); } void Cloud::simulate (float deltaTime) { unsigned int i; - field->simulate(deltaTime); - for (i = 0; i < count; ++i) { + _field->simulate(deltaTime); + for (i = 0; i < _count; ++i) { // Update position - particles[i].position += particles[i].velocity * deltaTime; + _particles[i].position += _particles[i].velocity * deltaTime; // Decay Velocity (Drag) const float CONSTANT_DAMPING = 0.15f; - particles[i].velocity *= (1.f - CONSTANT_DAMPING * deltaTime); + _particles[i].velocity *= (1.f - CONSTANT_DAMPING * deltaTime); // Interact with Field const float FIELD_COUPLE = 0.005f; - field->interact(deltaTime, - &particles[i].position, - &particles[i].velocity, - &particles[i].color, + _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) + 0.5f; + _particles[i].color = (glm::normalize(_particles[i].velocity) * 0.5f) + 0.5f; // Bounce at bounds - if ((particles[i].position.x > bounds.x) || (particles[i].position.x < 0.f)) { - particles[i].position.x = glm::clamp(particles[i].position.x, 0.f, bounds.x); - particles[i].velocity.x *= -1.f; + if ((_particles[i].position.x > _bounds.x) || (_particles[i].position.x < 0.f)) { + _particles[i].position.x = glm::clamp(_particles[i].position.x, 0.f, _bounds.x); + _particles[i].velocity.x *= -1.f; } - if ((particles[i].position.y > bounds.y) || (particles[i].position.y < 0.f)) { - particles[i].position.y = glm::clamp(particles[i].position.y, 0.f, bounds.y); - particles[i].velocity.y *= -1.f; + if ((_particles[i].position.y > _bounds.y) || (_particles[i].position.y < 0.f)) { + _particles[i].position.y = glm::clamp(_particles[i].position.y, 0.f, _bounds.y); + _particles[i].velocity.y *= -1.f; } - if ((particles[i].position.z > bounds.z) || (particles[i].position.z < 0.f)) { - particles[i].position.z = glm::clamp(particles[i].position.z, 0.f, bounds.z); - particles[i].velocity.z *= -1.f; + if ((_particles[i].position.z > _bounds.z) || (_particles[i].position.z < 0.f)) { + _particles[i].position.z = glm::clamp(_particles[i].position.z, 0.f, _bounds.z); + _particles[i].velocity.z *= -1.f; } } } diff --git a/interface/src/Cloud.h b/interface/src/Cloud.h index 44ff8c54a6..fcf414b62e 100644 --- a/interface/src/Cloud.h +++ b/interface/src/Cloud.h @@ -16,18 +16,17 @@ class Cloud { public: Cloud(); - void simulate(float deltaTime); void render(); private: struct Particle { glm::vec3 position, velocity, color; - } *particles; + }* _particles; - unsigned int count; - glm::vec3 bounds; - Field *field; + unsigned int _count; + glm::vec3 _bounds; + Field* _field; }; #endif diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index eb6cdf0682..93d2cfca0a 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -20,9 +20,9 @@ int Field::value(float *value, float *pos) if ((index >= 0) && (index < FIELD_ELEMENTS)) { - value[0] = field[index].val.x; - value[1] = field[index].val.y; - value[2] = field[index].val.z; + value[0] = _field[index].val.x; + value[1] = _field[index].val.y; + value[2] = _field[index].val.z; return 1; } else { @@ -34,21 +34,20 @@ Field::Field(float worldSize) // Initializes the field to some random values { _worldSize = worldSize; - int i; float fx, fy, fz; - for (i = 0; i < FIELD_ELEMENTS; i++) + for (int i = 0; i < FIELD_ELEMENTS; i++) { const float FIELD_INITIAL_MAG = 0.0f; - field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; - field[i].scalar = 0; + _field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; + _field[i].scalar = 0; // Record center point for this field cell fx = static_cast(i % 10); fy = static_cast(i % 100 / 10); fz = static_cast(i / 100); - field[i].center.x = (fx + 0.5f); - field[i].center.y = (fy + 0.5f); - field[i].center.z = (fz + 0.5f); - field[i].center *= _worldSize / 10.f; + _field[i].center.x = (fx + 0.5f); + _field[i].center.y = (fy + 0.5f); + _field[i].center.z = (fz + 0.5f); + _field[i].center *= _worldSize / 10.f; } } @@ -62,63 +61,38 @@ void Field::add(float* add, float *pos) if ((index >= 0) && (index < FIELD_ELEMENTS)) { - field[index].val.x += add[0]; - field[index].val.y += add[1]; - field[index].val.z += add[2]; + _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) { +void Field::interact(float deltaTime, glm::vec3* pos, glm::vec3* vel, glm::vec3* color, float coupling) { int index = (int)(pos->x/ _worldSize * 10.0) + - (int)(pos->y/_worldSize*10.0)*10 + - (int)(pos->z/_worldSize*10.0)*100; + (int)(pos->y/_worldSize*10.0) * 10 + + (int)(pos->z/_worldSize*10.0) * 100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { // // Vector Coupling with particle velocity // - *vel += field[index].val * dt; // Particle influenced by field + *vel += _field[index].val * deltaTime; // Particle influenced by field - glm::vec3 temp = *vel * dt; // Field influenced by particle + glm::vec3 temp = *vel * deltaTime; // Field influenced by particle temp *= coupling; - field[index].val += temp; + _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); - - 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) { +void Field::simulate(float deltaTime) { glm::vec3 neighbors, add, diff; for (int i = 0; i < FIELD_ELEMENTS; i++) { 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); + _field[i].val *= (1.f - CONSTANT_DAMPING * deltaTime); + _field[i].scalar *= (1.f - CONSTANT_SCALAR_DAMPING * deltaTime); } } @@ -133,10 +107,10 @@ void Field::render() for (i = 0; i < FIELD_ELEMENTS; i++) { glColor3f(0, 1, 0); - glVertex3fv(&field[i].center.x); - glVertex3f(field[i].center.x + field[i].val.x * scale_view, - field[i].center.y + field[i].val.y * scale_view, - field[i].center.z + field[i].val.z * scale_view); + glVertex3fv(&_field[i].center.x); + glVertex3f(_field[i].center.x + _field[i].val.x * scale_view, + _field[i].center.y + _field[i].val.y * scale_view, + _field[i].center.z + _field[i].val.z * scale_view); } glEnd(); @@ -146,7 +120,7 @@ void Field::render() glBegin(GL_POINTS); for (i = 0; i < FIELD_ELEMENTS; i++) { - glVertex3fv(&field[i].center.x); + glVertex3fv(&_field[i].center.x); } glEnd(); } diff --git a/interface/src/Field.h b/interface/src/Field.h index 8198521b4a..0fe3bc0a82 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -25,7 +25,7 @@ class Field { glm::vec3 center; glm::vec3 fld; float scalar; - } field[FIELD_ELEMENTS]; + } _field[FIELD_ELEMENTS]; Field(float worldSize); @@ -34,9 +34,7 @@ class Field { 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); float _worldSize; }; From 5509324ffdaf0bf95cfb7a7581af94fd3e3a97e2 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 17:18:22 -0700 Subject: [PATCH 07/13] Change particles to use vertex arrays, further speedups --- interface/src/Cloud.cpp | 36 ++++++++++++++++-------------------- interface/src/Field.cpp | 18 ++++++++---------- interface/src/Field.h | 7 ++++--- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index bfa5129d14..5174d0c4c5 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -13,14 +13,17 @@ #include "Field.h" const int NUM_PARTICLES = 100000; +const float FIELD_COUPLE = 0.001f; Cloud::Cloud() { - // Create and initialize particles + // Create and initialize particles + + glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE); _bounds = box; _count = NUM_PARTICLES; _particles = new Particle[_count]; - _field = new Field(PARTICLE_WORLD_SIZE); + _field = new Field(PARTICLE_WORLD_SIZE, FIELD_COUPLE); for (int i = 0; i < _count; i++) { _particles[i].position = randVector() * box; @@ -36,17 +39,15 @@ void Cloud::render() { glPointSize(3.0f); glDisable(GL_TEXTURE_2D); glEnable(GL_POINT_SMOOTH); - 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(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 3 * sizeof(glm::vec3), &_particles[0].position); + glColorPointer(3, GL_FLOAT, 3 * sizeof(glm::vec3), &_particles[0].color); + glDrawArrays(GL_POINTS, 0, NUM_PARTICLES); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } void Cloud::simulate (float deltaTime) { @@ -62,13 +63,8 @@ void Cloud::simulate (float deltaTime) { _particles[i].velocity *= (1.f - CONSTANT_DAMPING * deltaTime); // Interact with Field - const float FIELD_COUPLE = 0.005f; - _field->interact(deltaTime, - &_particles[i].position, - &_particles[i].velocity, - &_particles[i].color, - FIELD_COUPLE); - + _field->interact(deltaTime, _particles[i].position, _particles[i].velocity); + // Update color to velocity _particles[i].color = (glm::normalize(_particles[i].velocity) * 0.5f) + 0.5f; diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 93d2cfca0a..ee1ba32253 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -30,10 +30,11 @@ int Field::value(float *value, float *pos) } } -Field::Field(float worldSize) +Field::Field(float worldSize, float coupling) // Initializes the field to some random values { _worldSize = worldSize; + _coupling = coupling; float fx, fy, fz; for (int i = 0; i < FIELD_ELEMENTS; i++) { @@ -67,20 +68,17 @@ void Field::add(float* add, float *pos) } } -void Field::interact(float deltaTime, glm::vec3* pos, glm::vec3* vel, glm::vec3* color, float coupling) { +void Field::interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel) { - int index = (int)(pos->x/ _worldSize * 10.0) + - (int)(pos->y/_worldSize*10.0) * 10 + - (int)(pos->z/_worldSize*10.0) * 100; + int index = (int)(pos.x / _worldSize * 10.0) + + (int)(pos.y / _worldSize*10.0) * 10 + + (int)(pos.z / _worldSize*10.0) * 100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { // // Vector Coupling with particle velocity // - *vel += _field[index].val * deltaTime; // Particle influenced by field - - glm::vec3 temp = *vel * deltaTime; // Field influenced by particle - temp *= coupling; - _field[index].val += temp; + vel += _field[index].val * deltaTime; // Particle influenced by field + _field[index].val += vel * deltaTime * _coupling; } } diff --git a/interface/src/Field.h b/interface/src/Field.h index 0fe3bc0a82..70b10287d9 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -27,15 +27,16 @@ class Field { float scalar; } _field[FIELD_ELEMENTS]; - Field(float worldSize); + Field(float worldSize, float coupling); 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); + void interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel); + void simulate(float deltaTime); private: float _worldSize; + float _coupling; }; #endif From 1d1e1f6d416cea958f46ac4e099e455799e88846 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 17:21:39 -0700 Subject: [PATCH 08/13] spacing --- interface/src/Field.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index ee1ba32253..438e3c5803 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -57,8 +57,8 @@ void Field::add(float* add, float *pos) // At location loc, add vector add to the field values { int index = (int)(pos[0] / _worldSize * 10.0) + - (int)(pos[1] / _worldSize * 10.0)*10 + - (int)(pos[2] / _worldSize * 10.0)*100; + (int)(pos[1] / _worldSize * 10.0) * 10 + + (int)(pos[2] / _worldSize * 10.0) * 100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { From 27a892fa55aa01886792ce919f10e994ae7aff10 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 22:46:34 -0700 Subject: [PATCH 09/13] Removed old head rotation code, menu items, added ability to turn off faceshift head rotation --- interface/src/Application.cpp | 3 +-- interface/src/Menu.cpp | 14 +++++++------- interface/src/Menu.h | 2 +- interface/src/avatar/Head.cpp | 2 -- interface/src/avatar/Head.h | 3 --- interface/src/avatar/MyAvatar.cpp | 16 ++++++++-------- interface/src/avatar/MyAvatar.h | 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7d7b5ff4aa..cf08abde29 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2088,8 +2088,7 @@ void Application::updateAvatar(float deltaTime) { _yawFromTouch = 0.f; // Update my avatar's state from gyros and/or webcam - _myAvatar.updateFromGyrosAndOrWebcam(Menu::getInstance()->isOptionChecked(MenuOption::GyroLook), - _pitchFromTouch); + _myAvatar.updateFromGyrosAndOrWebcam(_pitchFromTouch, Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead)); // Update head mouse from faceshift if active if (_faceshift.isActive()) { diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 23743f3cc3..2970e47416 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -212,7 +212,13 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, - false); + true); + addCheckableActionToQMenuAndActionHash(viewMenu, + MenuOption::TurnWithHead, + 0, + true); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false); + addDisabledActionAndSeparator(viewMenu, "Stats"); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); @@ -315,12 +321,6 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::SimulateLeapHand); addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::TestRaveGlove); - - QMenu* gyroOptionsMenu = developerMenu->addMenu("Gyro Options"); - addCheckableActionToQMenuAndActionHash(gyroOptionsMenu, MenuOption::GyroLook, 0, true); - addCheckableActionToQMenuAndActionHash(gyroOptionsMenu, MenuOption::HeadMouse); - - QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, MenuOption::SkeletonTracking, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index ed7f0adce4..00223af204 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -170,7 +170,6 @@ namespace MenuOption { const QString Gravity = "Use Gravity"; const QString GroundPlane = "Ground Plane"; const QString ParticleCloud = "Particle Cloud"; - const QString GyroLook = "Smooth Gyro Look"; const QString ListenModeNormal = "Listen Mode Normal"; const QString ListenModePoint = "Listen Mode Point"; const QString ListenModeSingleSource = "Listen Mode Single Source"; @@ -182,6 +181,7 @@ namespace MenuOption { const QString NudgeVoxels = "Nudge"; const QString OcclusionCulling = "Occlusion Culling"; const QString OffAxisProjection = "Off-Axis Projection"; + const QString TurnWithHead = "Turn using Head"; const QString Oscilloscope = "Audio Oscilloscope"; const QString Pair = "Pair"; const QString PasteVoxels = "Paste"; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 9d8ba3cb9b..d5a6991d54 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -83,8 +83,6 @@ Head::Head(Avatar* owningAvatar) : _mousePitch(0.f), _cameraYaw(_yaw), _isCameraMoving(false), - _cameraFollowsHead(false), - _cameraFollowHeadRate(0.0f), _face(this), _perlinFace(this), _blendFace(this) diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 7c5491ae39..b84d988026 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -57,7 +57,6 @@ public: void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; } - void setCameraFollowsHead(bool cameraFollowsHead) { _cameraFollowsHead = cameraFollowsHead; } float getMousePitch() const { return _mousePitch; } void setMousePitch(float mousePitch) { _mousePitch = mousePitch; } @@ -133,8 +132,6 @@ private: float _mousePitch; float _cameraYaw; bool _isCameraMoving; - bool _cameraFollowsHead; - float _cameraFollowHeadRate; Face _face; PerlinFace _perlinFace; BlendFace _blendFace; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 54080ae9ff..26734c3bf3 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -357,8 +357,7 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { } // Update avatar head rotation with sensor data -void MyAvatar::updateFromGyrosAndOrWebcam(bool gyroLook, - float pitchFromTouch) { +void MyAvatar::updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHead) { Faceshift* faceshift = Application::getInstance()->getFaceshift(); SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor(); Webcam* webcam = Application::getInstance()->getWebcam(); @@ -368,11 +367,13 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool gyroLook, estimatedPosition = faceshift->getHeadTranslation(); estimatedRotation = safeEulerAngles(faceshift->getHeadRotation()); // Rotate the body if the head is turned quickly - glm::vec3 headAngularVelocity = faceshift->getHeadAngularVelocity(); - const float FACESHIFT_YAW_VIEW_SENSITIVITY = 20.f; - const float FACESHIFT_MIN_YAW_VELOCITY = 1.0f; - if (fabs(headAngularVelocity.y) > FACESHIFT_MIN_YAW_VELOCITY) { - _bodyYawDelta += headAngularVelocity.y * FACESHIFT_YAW_VIEW_SENSITIVITY; + if (turnWithHead) { + glm::vec3 headAngularVelocity = faceshift->getHeadAngularVelocity(); + const float FACESHIFT_YAW_VIEW_SENSITIVITY = 20.f; + const float FACESHIFT_MIN_YAW_VELOCITY = 1.0f; + if (fabs(headAngularVelocity.y) > FACESHIFT_MIN_YAW_VELOCITY) { + _bodyYawDelta += headAngularVelocity.y * FACESHIFT_YAW_VIEW_SENSITIVITY; + } } } else if (gyros->isActive()) { estimatedRotation = gyros->getEstimatedRotation(); @@ -429,7 +430,6 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool gyroLook, _head.setPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY); _head.setYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY); _head.setRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY); - _head.setCameraFollowsHead(gyroLook); // Update torso lean distance based on accelerometer data const float TORSO_LENGTH = _scale * 0.5f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index e6cea94988..12b0193b0c 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -19,7 +19,7 @@ public: void reset(); void simulate(float deltaTime, Transmitter* transmitter); - void updateFromGyrosAndOrWebcam(bool gyroLook, float pitchFromTouch); + void updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHead); void render(bool lookingInMirror, bool renderAvatarBalls); void renderScreenTint(ScreenTintLayer layer, Camera& whichCamera); From 632dd2fa7df95597fb11d057da255e34950b9179 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 23:23:20 -0700 Subject: [PATCH 10/13] code review, added Doxygen style comments --- interface/src/Cloud.cpp | 5 ++++- interface/src/Field.cpp | 32 ++++++++------------------------ interface/src/Field.h | 10 +++++++--- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index 5174d0c4c5..42ab873947 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -14,6 +14,7 @@ const int NUM_PARTICLES = 100000; const float FIELD_COUPLE = 0.001f; +const bool RENDER_FIELD = false; Cloud::Cloud() { // Create and initialize particles @@ -34,7 +35,9 @@ Cloud::Cloud() { } void Cloud::render() { - //field->render(); + if (RENDER_FIELD) { + _field->render(); + } glPointSize(3.0f); glDisable(GL_TEXTURE_2D); diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 438e3c5803..51d73de359 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -5,14 +5,11 @@ // Created by Philip Rosedale on 8/23/12. // Copyright (c) 2012 High Fidelity, Inc. All rights reserved. // +// A vector-valued field over an array of elements arranged as a 3D lattice #include "Field.h" -// 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] / _worldSize * 10.0) + (int)(pos[1] / _worldSize * 10.0) * 10 + @@ -31,30 +28,23 @@ int Field::value(float *value, float *pos) } Field::Field(float worldSize, float coupling) -// Initializes the field to some random values { _worldSize = worldSize; _coupling = coupling; - float fx, fy, fz; + //float fx, fy, fz; for (int i = 0; i < FIELD_ELEMENTS; i++) { const float FIELD_INITIAL_MAG = 0.0f; _field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; - _field[i].scalar = 0; - // Record center point for this field cell - fx = static_cast(i % 10); - fy = static_cast(i % 100 / 10); - fz = static_cast(i / 100); - _field[i].center.x = (fx + 0.5f); - _field[i].center.y = (fy + 0.5f); - _field[i].center.z = (fz + 0.5f); + _field[i].center.x = ((float)(i % 10) + 0.5f); + _field[i].center.y = ((float)(i % 100 / 10) + 0.5f); + _field[i].center.z = ((float)(i / 100) + 0.5f); _field[i].center *= _worldSize / 10.f; } } void Field::add(float* add, float *pos) -// At location loc, add vector add to the field values { int index = (int)(pos[0] / _worldSize * 10.0) + (int)(pos[1] / _worldSize * 10.0) * 10 + @@ -74,11 +64,8 @@ void Field::interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel) { (int)(pos.y / _worldSize*10.0) * 10 + (int)(pos.z / _worldSize*10.0) * 100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { - // - // Vector Coupling with particle velocity - // - vel += _field[index].val * deltaTime; // Particle influenced by field - _field[index].val += vel * deltaTime * _coupling; + vel += _field[index].val * deltaTime; // Particle influenced by field + _field[index].val += vel * deltaTime * _coupling; // Field influenced by particle } } @@ -87,15 +74,12 @@ void Field::simulate(float deltaTime) { for (int i = 0; i < FIELD_ELEMENTS; i++) { - const float CONSTANT_DAMPING = 0.5; - const float CONSTANT_SCALAR_DAMPING = 2.5; + const float CONSTANT_DAMPING = 0.5f; _field[i].val *= (1.f - CONSTANT_DAMPING * deltaTime); - _field[i].scalar *= (1.f - CONSTANT_SCALAR_DAMPING * deltaTime); } } void Field::render() -// Render the field lines { int i; float scale_view = 0.05f * _worldSize; diff --git a/interface/src/Field.h b/interface/src/Field.h index 70b10287d9..a5d4e4c963 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -15,24 +15,28 @@ #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; +/// Field is a lattice of vectors uniformly distributed in 3D with FIELD_ELEMENTS^(1/3) per side class Field { public: struct FieldElement { glm::vec3 val; glm::vec3 center; glm::vec3 fld; - float scalar; } _field[FIELD_ELEMENTS]; Field(float worldSize, float coupling); - + /// The field value at a position in space, given simply as the value of the enclosing cell int value(float *ret, float *pos); + /// Visualize the field as vector lines drawn at each center void render(); + /// Add to the field value cell enclosing a location void add(float* add, float *loc); + /// A particle with a position and velocity interacts with the field given the coupling + /// constant passed when creating the field. void interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel); + /// Field evolves over timestep void simulate(float deltaTime); private: float _worldSize; From d8dcb6aa4445975a2b713ab21475bd422d616a70 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 9 Oct 2013 23:26:44 -0700 Subject: [PATCH 11/13] bracket placement --- interface/src/Cloud.cpp | 3 --- interface/src/Field.cpp | 12 ++++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/interface/src/Cloud.cpp b/interface/src/Cloud.cpp index 42ab873947..ba4c16b8fd 100644 --- a/interface/src/Cloud.cpp +++ b/interface/src/Cloud.cpp @@ -17,9 +17,6 @@ const float FIELD_COUPLE = 0.001f; const bool RENDER_FIELD = false; Cloud::Cloud() { - // Create and initialize particles - - glm::vec3 box = glm::vec3(PARTICLE_WORLD_SIZE); _bounds = box; _count = NUM_PARTICLES; diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index 51d73de359..f8e6179e56 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -9,8 +9,7 @@ #include "Field.h" -int Field::value(float *value, float *pos) -{ +int Field::value(float *value, float *pos) { int index = (int)(pos[0] / _worldSize * 10.0) + (int)(pos[1] / _worldSize * 10.0) * 10 + (int)(pos[2] / _worldSize * 10.0) * 100; @@ -27,8 +26,7 @@ int Field::value(float *value, float *pos) } } -Field::Field(float worldSize, float coupling) -{ +Field::Field(float worldSize, float coupling) { _worldSize = worldSize; _coupling = coupling; //float fx, fy, fz; @@ -44,8 +42,7 @@ Field::Field(float worldSize, float coupling) } } -void Field::add(float* add, float *pos) -{ +void Field::add(float* add, float *pos) { int index = (int)(pos[0] / _worldSize * 10.0) + (int)(pos[1] / _worldSize * 10.0) * 10 + (int)(pos[2] / _worldSize * 10.0) * 100; @@ -79,8 +76,7 @@ void Field::simulate(float deltaTime) { } } -void Field::render() -{ +void Field::render() { int i; float scale_view = 0.05f * _worldSize; From dd09d686fc87f252271aaff15e6da7ce62954ef2 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 10 Oct 2013 09:53:43 -0700 Subject: [PATCH 12/13] indents --- interface/src/Field.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/interface/src/Field.cpp b/interface/src/Field.cpp index f8e6179e56..1f4024653b 100644 --- a/interface/src/Field.cpp +++ b/interface/src/Field.cpp @@ -11,17 +11,15 @@ int Field::value(float *value, float *pos) { int index = (int)(pos[0] / _worldSize * 10.0) + - (int)(pos[1] / _worldSize * 10.0) * 10 + - (int)(pos[2] / _worldSize * 10.0) * 100; + (int)(pos[1] / _worldSize * 10.0) * 10 + + (int)(pos[2] / _worldSize * 10.0) * 100; - if ((index >= 0) && (index < FIELD_ELEMENTS)) - { + 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 { + } else { return 0; } } @@ -30,8 +28,7 @@ Field::Field(float worldSize, float coupling) { _worldSize = worldSize; _coupling = coupling; //float fx, fy, fz; - for (int i = 0; i < FIELD_ELEMENTS; i++) - { + for (int i = 0; i < FIELD_ELEMENTS; i++) { const float FIELD_INITIAL_MAG = 0.0f; _field[i].val = randVector() * FIELD_INITIAL_MAG * _worldSize; _field[i].center.x = ((float)(i % 10) + 0.5f); @@ -44,11 +41,10 @@ Field::Field(float worldSize, float coupling) { void Field::add(float* add, float *pos) { int index = (int)(pos[0] / _worldSize * 10.0) + - (int)(pos[1] / _worldSize * 10.0) * 10 + - (int)(pos[2] / _worldSize * 10.0) * 100; + (int)(pos[1] / _worldSize * 10.0) * 10 + + (int)(pos[2] / _worldSize * 10.0) * 100; - if ((index >= 0) && (index < FIELD_ELEMENTS)) - { + if ((index >= 0) && (index < FIELD_ELEMENTS)) { _field[index].val.x += add[0]; _field[index].val.y += add[1]; _field[index].val.z += add[2]; @@ -58,8 +54,8 @@ void Field::add(float* add, float *pos) { void Field::interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel) { int index = (int)(pos.x / _worldSize * 10.0) + - (int)(pos.y / _worldSize*10.0) * 10 + - (int)(pos.z / _worldSize*10.0) * 100; + (int)(pos.y / _worldSize*10.0) * 10 + + (int)(pos.z / _worldSize*10.0) * 100; if ((index >= 0) && (index < FIELD_ELEMENTS)) { vel += _field[index].val * deltaTime; // Particle influenced by field _field[index].val += vel * deltaTime * _coupling; // Field influenced by particle @@ -69,8 +65,7 @@ void Field::interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel) { void Field::simulate(float deltaTime) { glm::vec3 neighbors, add, diff; - for (int i = 0; i < FIELD_ELEMENTS; i++) - { + for (int i = 0; i < FIELD_ELEMENTS; i++) { const float CONSTANT_DAMPING = 0.5f; _field[i].val *= (1.f - CONSTANT_DAMPING * deltaTime); } @@ -82,8 +77,7 @@ void Field::render() { glDisable(GL_LIGHTING); glBegin(GL_LINES); - for (i = 0; i < FIELD_ELEMENTS; i++) - { + for (i = 0; i < FIELD_ELEMENTS; i++) { glColor3f(0, 1, 0); glVertex3fv(&_field[i].center.x); glVertex3f(_field[i].center.x + _field[i].val.x * scale_view, @@ -96,8 +90,7 @@ void Field::render() { glPointSize(4.0); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); - for (i = 0; i < FIELD_ELEMENTS; i++) - { + for (i = 0; i < FIELD_ELEMENTS; i++) { glVertex3fv(&_field[i].center.x); } glEnd(); From 72273d14692a861b07b8ab757e16b7673346dc84 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 10 Oct 2013 10:14:35 -0700 Subject: [PATCH 13/13] indent --- interface/src/Field.h | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/interface/src/Field.h b/interface/src/Field.h index a5d4e4c963..c85c3d33a4 100644 --- a/interface/src/Field.h +++ b/interface/src/Field.h @@ -19,28 +19,28 @@ const int FIELD_ELEMENTS = 1000; /// Field is a lattice of vectors uniformly distributed in 3D with FIELD_ELEMENTS^(1/3) per side class Field { - public: - struct FieldElement { - glm::vec3 val; - glm::vec3 center; - glm::vec3 fld; - } _field[FIELD_ELEMENTS]; - - Field(float worldSize, float coupling); - /// The field value at a position in space, given simply as the value of the enclosing cell - int value(float *ret, float *pos); - /// Visualize the field as vector lines drawn at each center - void render(); - /// Add to the field value cell enclosing a location - void add(float* add, float *loc); - /// A particle with a position and velocity interacts with the field given the coupling - /// constant passed when creating the field. - void interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel); - /// Field evolves over timestep - void simulate(float deltaTime); - private: - float _worldSize; - float _coupling; +public: + struct FieldElement { + glm::vec3 val; + glm::vec3 center; + glm::vec3 fld; + } _field[FIELD_ELEMENTS]; + + Field(float worldSize, float coupling); + /// The field value at a position in space, given simply as the value of the enclosing cell + int value(float *ret, float *pos); + /// Visualize the field as vector lines drawn at each center + void render(); + /// Add to the field value cell enclosing a location + void add(float* add, float *loc); + /// A particle with a position and velocity interacts with the field given the coupling + /// constant passed when creating the field. + void interact(float deltaTime, const glm::vec3& pos, glm::vec3& vel); + /// Field evolves over timestep + void simulate(float deltaTime); +private: + float _worldSize; + float _coupling; }; #endif