diff --git a/.DS_Store b/.DS_Store index 8a70b493dd..42a5f68581 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/cloud.cpp b/cloud.cpp index 155540bc01..3a73134441 100644 --- a/cloud.cpp +++ b/cloud.cpp @@ -89,6 +89,10 @@ void Cloud::simulate (float deltaTime) { const float FIELD_COUPLE = 0.005; //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); + + // Bounce or Wrap if (wrapBounds) { // wrap around bounds diff --git a/field.cpp b/field.cpp index f450c38525..aa3b496fb7 100644 --- a/field.cpp +++ b/field.cpp @@ -12,6 +12,8 @@ #define COLOR_DRIFT_RATE 0.001f // per-frame drift of particle color towards field element color #define COLOR_MIN 0.3f // 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) @@ -35,11 +37,21 @@ void field_init() // 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.5)*FIELD_SCALE; field[i].val.y = (randFloat() - 0.5)*FIELD_SCALE; field[i].val.z = (randFloat() - 0.5)*FIELD_SCALE; + field[i].scalar = 0; + // Record center point for this field cell + fx = (int)(i % 10); + fy = (int)(i%100 / 10); + fz = (int)(i / 100); + field[i].center.x = fx + 0.5; + field[i].center.y = fy + 0.5; + field[i].center.z = fz + 0.5; + // 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, @@ -68,15 +80,27 @@ void field_interact(float dt, glm::vec3 * pos, glm::vec3 * vel, glm::vec3 * colo (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*dt; - // Add back to field from particle velocity - glm::vec3 temp = *vel*dt; + // + // 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); + //*color = (*color * (1 - COLOR_DRIFT_RATE)) + (fieldcolors[index].rgb * COLOR_DRIFT_RATE); } } @@ -106,9 +130,10 @@ void field_avg_neighbors(int index, glm::vec3 * result) { } void field_simulate(float dt) { - glm::vec3 neighbors, add; - float size; - for (int i = 0; i < FIELD_ELEMENTS; i++) + glm::vec3 neighbors, add, diff; + float size, distance; + int i, j; + for (i = 0; i < FIELD_ELEMENTS; i++) { if (0) { //(randFloat() > 0.01) { field_avg_neighbors(i, &neighbors); @@ -117,9 +142,6 @@ void field_simulate(float dt) { field[i].val.z*field[i].val.z, 0.5); neighbors *= 0.0001; - // not currently in use - // glm::vec3 test = glm::normalize(glm::vec3(0,0,0)); - field[i].val = glm::normalize(field[i].val); field[i].val *= size * 0.99; add = glm::normalize(neighbors); @@ -128,12 +150,27 @@ void field_simulate(float dt) { } else { const float CONSTANT_DAMPING = 0.5; + const float CONSTANT_SCALAR_DAMPING = 2.5; field[i].val *= (1.f - CONSTANT_DAMPING*dt); - //field[i].val.x += (randFloat() - 0.5)*0.01*FIELD_SCALE; - //field[i].val.y += (randFloat() - 0.5)*0.01*FIELD_SCALE; - //field[i].val.z += (randFloat() - 0.5)*0.01*FIELD_SCALE; + 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); + } + } + } } } @@ -145,19 +182,29 @@ void field_render() float scale_view = 0.1; glDisable(GL_LIGHTING); - glColor3f(0, 1, 0); glBegin(GL_LINES); for (i = 0; i < FIELD_ELEMENTS; i++) { - fx = (int)(i % 10); - fy = (int)(i%100 / 10); - fz = (int)(i / 100); + 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.01, fz); + glColor3f(1, 1, 0); + glVertex3f(fx, fy, fz); + glVertex3f(fx + field[i].fld.x*0.0001, + fy + field[i].fld.y*0.0001, + fz + field[i].fld.z*0.0001); + } + } glEnd(); diff --git a/field.h b/field.h index 354a4a8149..6fbdf262db 100644 --- a/field.h +++ b/field.h @@ -24,6 +24,9 @@ const int FIELD_ELEMENTS = 1000; struct { glm::vec3 val; + glm::vec3 center; + glm::vec3 fld; + float scalar; } field[FIELD_ELEMENTS]; // Pre-calculated RGB values for each field element diff --git a/hardware/head_hand/head_hand.pde b/hardware/head_hand/head_hand.pde index 16be76ed04..8618674cc3 100644 --- a/hardware/head_hand/head_hand.pde +++ b/hardware/head_hand/head_hand.pde @@ -9,7 +9,7 @@ Read a set of analog input lines and echo their readings over the serial port wi #define NUM_CHANNELS 6 -#define MSECS_PER_SAMPLE 10 +#define MSECS_PER_SAMPLE 15 #define LED_PIN 12 diff --git a/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate b/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate index 5069cead64..752de4bf00 100644 Binary files a/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate and b/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist index f5c01eb1d0..6b093433a5 100644 --- a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist @@ -8,11 +8,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "field.cpp" - timestampString = "374955033.430214" + timestampString = "375986878.0086" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "98" - endingLineNumber = "98" + startingLineNumber = "122" + endingLineNumber = "122" landmarkName = "field_avg_neighbors(int index, glm::vec3 * result)" landmarkType = "7"> diff --git a/main.cpp b/main.cpp index f366efad3a..68b9244f27 100644 --- a/main.cpp +++ b/main.cpp @@ -93,7 +93,7 @@ ParticleSystem balls(0, Cloud cloud(100000, // Particles box, // Bounding Box - false // Wrap + false // Wrap ); float cubes_position[MAX_CUBES*3];