From 61578d1ddb63b57dadb7e5c044e959ce65435ab8 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 26 Apr 2013 09:59:50 -0700 Subject: [PATCH] Added balls class --- interface/src/Balls.cpp | 106 ++++++++++++++++++++++++++++++++++++++++ interface/src/Balls.h | 37 ++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 interface/src/Balls.cpp create mode 100644 interface/src/Balls.h diff --git a/interface/src/Balls.cpp b/interface/src/Balls.cpp new file mode 100644 index 0000000000..82f59c025f --- /dev/null +++ b/interface/src/Balls.cpp @@ -0,0 +1,106 @@ +// +// Balls.cpp +// hifi +// +// Created by Philip on 4/25/13. +// +// A cloud of spring-mass spheres to simulate the avatar body/skin. Each ball +// connects to as many as 4 neighbors, and executes motion according to a damped +// spring, while responding physically to other avatars. +// + +#include "Balls.h" + +Balls::Balls(int numberOfBalls) { + _numberOfBalls = numberOfBalls; + _balls = new Ball[_numberOfBalls]; + for (unsigned int i = 0; i < _numberOfBalls; ++i) { + _balls[i].position = glm::vec3(1.0 + randFloat()*0.5, + 0.5 + randFloat()*0.5, + 1.0 + randFloat()*0.5); + _balls[i].radius = 0.02 + randFloat()*0.06; + for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { + _balls[i].links[j] = rand() % (numberOfBalls + 1); + if (_balls[i].links[j]-1 == i) { _balls[i].links[j] = 0; } + _balls[i].springLength[j] = 0.5; + } + } +} + +const bool RENDER_SPRINGS = true; + +void Balls::render() { + + // Render Balls NOTE: This needs to become something other that GlutSpheres! + glColor3f(0.62,0.74,0.91); + for (unsigned int i = 0; i < _numberOfBalls; ++i) { + glPushMatrix(); + glTranslatef(_balls[i].position.x, _balls[i].position.y, _balls[i].position.z); + glutSolidSphere(_balls[i].radius, 15, 15); + glPopMatrix(); + } + + // Render springs + if (RENDER_SPRINGS) { + glColor3f(0.74,0.91,0.62); + for (unsigned int i = 0; i < _numberOfBalls; ++i) { + glBegin(GL_LINES); + for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { + if(_balls[i].links[j] > 0) { + glVertex3f(_balls[i].position.x, + _balls[i].position.y, + _balls[i].position.z); + glVertex3f(_balls[_balls[i].links[j]-1].position.x, + _balls[_balls[i].links[j]-1].position.y, + _balls[_balls[i].links[j]-1].position.z); + } + } + glEnd(); + } + } + +} + +const float CONSTANT_VELOCITY_DAMPING = 1.0f; +const float NOISE_SCALE = 0.00; +const float SPRING_FORCE = 1.0; +const float SPRING_DAMPING = 1.0; + +void Balls::simulate(float deltaTime) { + for (unsigned int i = 0; i < _numberOfBalls; ++i) { + + // Move particles + _balls[i].position += _balls[i].velocity * deltaTime; + + // Drag: decay velocity + _balls[i].velocity *= (1.f - CONSTANT_VELOCITY_DAMPING*deltaTime); + + // Add noise + _balls[i].velocity += glm::vec3((randFloat() - 0.5) * NOISE_SCALE, + (randFloat() - 0.5) * NOISE_SCALE, + (randFloat() - 0.5) * NOISE_SCALE); + + // Spring Force + + + for (unsigned int j = 0; j < NUMBER_SPRINGS; ++j) { + if(_balls[i].links[j] > 0) { + float separation = glm::distance(_balls[i].position, + _balls[_balls[i].links[j]-1].position); + _balls[i].velocity += glm::normalize(_balls[i].position - + _balls[_balls[i].links[j]-1].position) * + deltaTime * + SPRING_FORCE * + (_balls[i].springLength[j] - separation); + + //_balls[i].velocity *= (1.f - SPRING_DAMPING*deltaTime); + + } + } + + + + + } +} + diff --git a/interface/src/Balls.h b/interface/src/Balls.h new file mode 100644 index 0000000000..653854a0c6 --- /dev/null +++ b/interface/src/Balls.h @@ -0,0 +1,37 @@ +// +// Balls.h +// hifi +// +// Created by Philip on 4/25/13. +// +// + +#ifndef hifi_Balls_h +#define hifi_Balls_h + +#include +#include "Util.h" +#include "world.h" +#include "InterfaceConfig.h" + + +const int NUMBER_SPRINGS = 4; + +class Balls { +public: + Balls(int numberOfBalls); + + void simulate(float deltaTime); + void render(); + +private: + struct Ball { + glm::vec3 position, velocity; + int links[NUMBER_SPRINGS]; + float springLength[NUMBER_SPRINGS]; + float radius; + } *_balls; + int _numberOfBalls; +}; + +#endif