added gravity, damping, and shouldDie behavior to particles

This commit is contained in:
ZappoMan 2013-12-10 12:53:42 -08:00
parent 7a828794be
commit ba9a113720
4 changed files with 73 additions and 54 deletions

View file

@ -17,19 +17,19 @@
uint32_t Particle::_nextID = 0;
Particle::Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity) {
init(position, radius, color, velocity);
Particle::Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, float damping, glm::vec3 gravity) {
init(position, radius, color, velocity, damping, gravity);
}
Particle::Particle() {
rgbColor noColor = { 0, 0, 0 };
init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0));
init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0), DEFAULT_DAMPING, DEFAULT_GRAVITY);
}
Particle::~Particle() {
}
void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity) {
void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, float damping, glm::vec3 gravity) {
_id = _nextID;
_nextID++;
_lastUpdated = usecTimestampNow();
@ -38,6 +38,8 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3
_radius = radius;
memcpy(_color, color, sizeof(_color));
_velocity = velocity;
_damping = damping;
_gravity = gravity;
}
@ -45,7 +47,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
bool success = packetData->appendValue(getID());
printf("Particle::appendParticleData()... getID()=%d\n", getID());
//printf("Particle::appendParticleData()... getID()=%d\n", getID());
if (success) {
success = packetData->appendValue(getLastUpdated());
@ -62,12 +64,19 @@ printf("Particle::appendParticleData()... getID()=%d\n", getID());
if (success) {
success = packetData->appendValue(getVelocity());
}
if (success) {
success = packetData->appendValue(getGravity());
}
if (success) {
success = packetData->appendValue(getDamping());
}
return success;
}
int Particle::expectedBytes() {
int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(float) +
sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3);
sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) +
sizeof(glm::vec3) + sizeof(float);
return expectedBytes;
}
@ -99,6 +108,14 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
// velocity
memcpy(&_velocity, dataAt, sizeof(_velocity));
dataAt += sizeof(_velocity);
// gravity
memcpy(&_gravity, dataAt, sizeof(_gravity));
dataAt += sizeof(_gravity);
// damping
memcpy(&_damping, dataAt, sizeof(_damping));
dataAt += sizeof(_damping);
bytesRead = expectedBytes();
}
@ -201,54 +218,29 @@ void Particle::update() {
uint64_t now = usecTimestampNow();
uint64_t elapsed = now - _lastUpdated;
uint64_t USECS_PER_SECOND = 1000 * 1000;
uint64_t USECS_PER_FIVE_SECONDS = 5 * USECS_PER_SECOND;
uint64_t USECS_PER_TEN_SECONDS = 10 * USECS_PER_SECOND;
uint64_t USECS_PER_THIRTY_SECONDS = 30 * USECS_PER_SECOND;
uint64_t USECS_PER_MINUTE = 60 * USECS_PER_SECOND;
uint64_t USECS_PER_HOUR = 60 * USECS_PER_MINUTE;
float timeElapsed = (float)((float)elapsed/(float)USECS_PER_SECOND);
//printf("elapsed=%llu timeElapsed=%f\n", elapsed, timeElapsed);
glm::vec3 position = getPosition() * (float)TREE_SCALE;
//printf("OLD position=%f, %f, %f\n", position.x, position.y, position.z);
//printf("velocity=%f, %f, %f\n", getVelocity().x, getVelocity().y, getVelocity().z);
// calculate our default shouldDie state... then allow script to change it if it wants...
float velocityScalar = glm::length(getVelocity());
const float STILL_MOVING = 0.05 / TREE_SCALE;
setShouldDie(velocityScalar < STILL_MOVING);
runScript(); // allow the javascript to alter our state
_position += _velocity * timeElapsed;
float gravity = -9.8f / TREE_SCALE;
glm::vec3 velocity = getVelocity() * (float)TREE_SCALE;
//printf("OLD velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
// handle bounces off the ground...
if (_position.y <= 0) {
_velocity = _velocity * glm::vec3(1,-1,1);
velocity = getVelocity() * (float)TREE_SCALE;
//printf("NEW from ground BOUNCE velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
_position.y = 0;
}
// handle gravity....
_velocity += glm::vec3(0,gravity,0) * timeElapsed;
velocity = getVelocity() * (float)TREE_SCALE;
//printf("NEW from gravity.... velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
_velocity += _gravity * timeElapsed;
// handle air resistance....
glm::vec3 airResistance = _velocity * glm::vec3(-0.25,-0.25,-0.25);
_velocity += airResistance * timeElapsed;
velocity = getVelocity() * (float)TREE_SCALE;
//printf("NEW from air resistance.... velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
position = getPosition() * (float)TREE_SCALE;
//printf("NEW position=%f, %f, %f\n", position.x, position.y, position.z);
runScript(); // test this...
position = getPosition() * (float)TREE_SCALE;
//printf("AFTER SCRIPT NEW position=%f, %f, %f\n", position.x, position.y, position.z);
// handle damping
glm::vec3 dampingResistance = _velocity * _damping;
_velocity -= dampingResistance * timeElapsed;
_lastUpdated = now;
}
@ -286,6 +278,9 @@ void Particle::xColorFromScriptValue(const QScriptValue &object, xColor& color)
void Particle::runScript() {
QString scriptContents(""
//"var myGravity = ((Math.random() * 20)-10) / TREE_SCALE;\n"
//"var myGravityVector = { x: myGravity, y: myGravity, z: myGravity };\n"
//"Particle.setGravity(myGravityVector);\n"
//"print(\"hello world\\n\");\n"
//"var position = Particle.getPosition();\n"
//"print(\"position.x=\" + position.x + \"\\n\");\n"

View file

@ -27,27 +27,32 @@ public:
glm::vec3 velocity;
};
const float DEFAULT_DAMPING = 0.99f;
const glm::vec3 DEFAULT_GRAVITY(0, (-9.8f / TREE_SCALE), 0);
class Particle {
public:
Particle();
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity,
float damping = DEFAULT_DAMPING, glm::vec3 gravity = DEFAULT_GRAVITY);
/// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD edit data buffer
static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes);
virtual ~Particle();
virtual void init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);
virtual void init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, float damping, glm::vec3 gravity);
const glm::vec3& getPosition() const { return _position; }
const rgbColor& getColor() const { return _color; }
xColor getColor() { return { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; }
float getRadius() const { return _radius; }
const glm::vec3& getVelocity() const { return _velocity; }
const glm::vec3& getGravity() const { return _gravity; }
float getDamping() const { return _damping; }
uint64_t getLastUpdated() const { return _lastUpdated; }
uint32_t getID() const { return _id; }
bool getShouldDie() const { return _shouldDie; }
void setPosition(const glm::vec3& value) { _position = value; }
void setVelocity(const glm::vec3& value) { _velocity = value; }
@ -57,6 +62,10 @@ public:
_color[GREEN_INDEX] = value.green;
_color[BLUE_INDEX] = value.blue;
}
void setRadius(float value) { _radius = value; }
void setGravity(const glm::vec3& value) { _gravity = value; }
void setDamping(float value) { _damping = value; }
void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; }
bool appendParticleData(OctreePacketData* packetData) const;
int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
@ -81,6 +90,10 @@ protected:
uint64_t _lastUpdated;
uint32_t _id;
static uint32_t _nextID;
bool _shouldDie;
glm::vec3 _gravity;
float _damping;
};
class ParticleScriptObject : public QObject {
@ -92,10 +105,16 @@ public slots:
glm::vec3 getPosition() const { return _particle->getPosition(); }
glm::vec3 getVelocity() const { return _particle->getVelocity(); }
xColor getColor() const { return _particle->getColor(); }
glm::vec3 getGravity() const { return _particle->getGravity(); }
float getDamping() const { return _particle->getDamping(); }
float getRadius() const { return _particle->getRadius(); }
void setPosition(glm::vec3 value) { return _particle->setPosition(value); }
void setVelocity(glm::vec3 value) { return _particle->setVelocity(value); }
void setGravity(glm::vec3 value) { return _particle->setGravity(value); }
void setDamping(float value) { return _particle->setDamping(value); }
void setColor(xColor value) { return _particle->setColor(value); }
void setRadius(float value) { return _particle->setRadius(value); }
private:
Particle* _particle;

View file

@ -82,16 +82,16 @@ void ParticleTree::update() {
// now add back any of the particles that moved elements....
int movingParticles = args._movingParticles.size();
for (int i = 0; i < movingParticles; i++) {
bool shouldDie = args._movingParticles[i].getShouldDie();
// if the particle is still inside our total bounds, then re-add it
AABox treeBounds = getRoot()->getAABox();
float velocityScalar = glm::length(args._movingParticles[i].getVelocity());
const float STILL_MOVING = 0.0001;
if (velocityScalar > STILL_MOVING && treeBounds.contains(args._movingParticles[i].getPosition())) {
if (!shouldDie && treeBounds.contains(args._movingParticles[i].getPosition())) {
printf("re-storing moved particle...\n");
storeParticle(args._movingParticles[i]);
} else {
printf("out of bounds or !velocityScalar=[%f], not re-storing moved particle...\n",velocityScalar);
printf(">>>>>>>>>>>>>>>>>>>> out of bounds or shouldDie, not re-storing moved particle...\n");
}
}
}

View file

@ -67,28 +67,31 @@ void ParticleTreeElement::update(ParticleTreeUpdateArgs& args) {
for (uint16_t i = 0; i < numberOfParticles; i++) {
_particles[i].update();
// what if this update moves the particle to a new element??
if (!_box.contains(_particles[i].getPosition())) {
// If the particle wants to die, or if it's left our bounding box, then move it
// into the arguments moving particles. These will be added back or deleted completely
if (_particles[i].getShouldDie() || !_box.contains(_particles[i].getPosition())) {
glm::vec3 position = _particles[i].getPosition() * (float)TREE_SCALE;
glm::vec3 boxBRN =_box.getCorner() * (float)TREE_SCALE;
glm::vec3 boxTLF =_box.calcTopFarLeft() * (float)TREE_SCALE;
/**
printf("particle [%f,%f,%f] no longer contained in ParticleTreeElement() box [%f,%f,%f] -> [%f,%f,%f]\n",
position.x, position.y, position.z,
boxBRN.x, boxBRN.y, boxBRN.z,
boxTLF.x, boxTLF.y, boxTLF.z);
**/
args._movingParticles.push_back(_particles[i]);
// erase this particle
_particles.erase(_particles.begin()+i);
printf("removed particle[%d]\n",i);
//printf("removed particle[%d]\n",i);
// reduce our index since we just removed this item
i--;
numberOfParticles--;
printf("numberOfParticles=%d]\n",numberOfParticles);
//printf("numberOfParticles=%d\n",numberOfParticles);
}
}
}
@ -145,8 +148,10 @@ void ParticleTreeElement::storeParticle(const Particle& particle) {
markWithChangedTime();
printf("ParticleTreeElement::storeParticle() element=%p _particles.size()=%ld particle.getPosition()=%f,%f,%f\n",
/***
printf("ParticleTreeElement::storeParticle() element=%p _particles.size()=%ld particle.getPosition()=%f,%f,%f\n",
this, _particles.size(),
particle.getPosition().x, particle.getPosition().y, particle.getPosition().z);
**/
}