mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-14 00:50:04 +02:00
added gravity, damping, and shouldDie behavior to particles
This commit is contained in:
parent
7a828794be
commit
ba9a113720
4 changed files with 73 additions and 54 deletions
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
**/
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue