void PUBoxCollider::preUpdateAffector( float deltaTime ) { PUBaseCollider::preUpdateAffector(deltaTime); // Calculate the affectors' center position in worldspace, set the box and calculate the bounds // Applied scaling in V 1.3.1. populateAlignedBox(_box, getDerivedPosition(), _affectorScale.x * _width, _affectorScale.y * _height, _affectorScale.z * _depth); calculateBounds(); }
//----------------------------------------------------------------------- void BoxCollider::_preProcessParticles(ParticleTechnique* particleTechnique, Real timeElapsed) { // Call parent BaseCollider::_preProcessParticles(particleTechnique, timeElapsed); // Calculate the affectors' center position in worldspace, set the box and calculate the bounds // Applied scaling in V 1.3.1. populateAlignedBox(mBox, getDerivedPosition(), _mAffectorScale.x * mWidth, _mAffectorScale.y * mHeight, _mAffectorScale.z * mDepth); _calculateBounds(); }
//----------------------------------------------------------------------- void BoxColliderExtern::_preProcessParticles(ParticleTechnique* particleTechnique, Real timeElapsed) { if (isAttached()) { // Use the position of the parent node in this case. position = getParentNode()->_getDerivedPosition(); mDerivedPosition = position; populateAlignedBox(mBox, mDerivedPosition, mWidth, mHeight, mDepth); _calculateBounds(); } }
//----------------------------------------------------------------------- void BoxCollider::_affect(ParticleTechnique* particleTechnique, Particle* particle, Real timeElapsed) { mPredictedPosition = particle->position + mVelocityScale * particle->direction; bool collision = false; /** Collision detection is a two-step. First, we determine whether the particle is now colliding. If it is, the particle is re-positioned. However, a timeElapsed value is used, which is not the same as the one that was used at the moment before the particle was colliding. Therefore, we rather want to predict particle collision in front. This probably isn't the fastest solution. The same approach was used for the other colliders. */ switch(mIntersectionType) { case BaseCollider::IT_POINT: { // Validate for a point-box intersection if (mInnerCollision != mBox.intersects(particle->position)) { // Collision detected (re-position the particle) particle->position -= mVelocityScale * particle->direction; collision = true; } else if (mInnerCollision != mBox.intersects(mPredictedPosition)) { // Collision detected collision = true; } } break; case BaseCollider::IT_BOX: { // Validate for a box-box intersection if (particle->particleType != Particle::PT_VISUAL) break; VisualParticle* visualParticle = static_cast<VisualParticle*>(particle); AxisAlignedBox box; populateAlignedBox(box, visualParticle->position, visualParticle->width, visualParticle->height, visualParticle->depth); if (mInnerCollision != box.intersects(mBox)) { // Collision detected (re-position the particle) particle->position -= mVelocityScale * particle->direction; collision = true; } else { AxisAlignedBox box; populateAlignedBox(box, mPredictedPosition, visualParticle->width, visualParticle->height, visualParticle->depth); if (mInnerCollision != box.intersects(mBox)) { // Collision detected collision = true; } } } break; } if (collision) { calculateDirectionAfterCollision(particle); calculateRotationSpeedAfterCollision(particle); particle->addEventFlags(Particle::PEF_COLLIDED); } }
void PUBoxCollider::updatePUAffector( PUParticle3D *particle, float deltaTime ) { //for (auto iter : _particleSystem->getParticles()) { //PUParticle3D *particle = iter; _predictedPosition = particle->position + _velocityScale * particle->direction; bool collision = false; /** Collision detection is a two-step. First, we determine whether the particle is now colliding. If it is, the particle is re-positioned. However, a timeElapsed value is used, which is not the same as the one that was used at the moment before the particle was colliding. Therefore, we rather want to predict particle collision in front. This probably isn't the fastest solution. The same approach was used for the other colliders. */ switch(_intersectionType) { case PUBaseCollider::IT_POINT: { // Validate for a point-box intersection if (_innerCollision != _box.containPoint(particle->position)) { // Collision detected (re-position the particle) particle->position -= _velocityScale * particle->direction; collision = true; } else if (_innerCollision != _box.containPoint(_predictedPosition)) { // Collision detected collision = true; } } break; case PUBaseCollider::IT_BOX: { AABB box; populateAlignedBox(box, particle->position, particle->width, particle->height, particle->depth); if (_innerCollision != box.intersects(_box)) { // Collision detected (re-position the particle) particle->position -= _velocityScale * particle->direction; collision = true; } else { populateAlignedBox(box, _predictedPosition, particle->width, particle->height, particle->depth); if (_innerCollision != box.intersects(_box)) { // Collision detected collision = true; } } } break; } if (collision) { calculateDirectionAfterCollision(particle); calculateRotationSpeedAfterCollision(particle); particle->addEventFlags(PUParticle3D::PEF_COLLIDED); } } }
void PUParticle3DPlaneCollider::updatePUAffector( PUParticle3D *particle, float deltaTime ) { //for (auto iter : _particleSystem->getParticles()) { //PUParticle3D *particle = iter; _predictedPosition = particle->position + _velocityScale * particle->direction; bool collision = false; switch(_intersectionType) { case PUParticle3DBaseCollider::IT_POINT: { // Validate for a point-plane intersection (on the plane or the back side) // First determine whether it is now colliding (some affector made the particle move), else // determine whether it WILL be colliding if (_plane.getDistance(particle->position) <= 0.0f) { // Collision detected (re-position the particle) particle->position -= _velocityScale * particle->direction; collision = true; } else if (_plane.getDistance(_predictedPosition) <= 0.0f) { // Collision detected collision = true; } } break; case PUParticle3DBaseCollider::IT_BOX: { AABB box; populateAlignedBox(box, particle->position, particle->width, particle->height, particle->depth); //FIXME //if (box.intersects(_plane)) //{ // // Collision detected (re-position the particle) // particle->position -= _velocityScale * particle->direction; // collision = true; //} //else //{ // populateAlignedBox(box, // _predictedPosition, // particle->width, // particle->height, // particle->depth); // if (box.intersects(_plane)) // { // // Collision detected // collision = true; // } //} } break; } if (collision) { calculateDirectionAfterCollision(particle, deltaTime); calculateRotationSpeedAfterCollision(particle); particle->addEventFlags(PUParticle3D::PEF_COLLIDED); } } }
void PUParticle3DSphereCollider::updatePUAffector( PUParticle3D *particle, float deltaTime ) { //for (auto iter : _particleSystem->getParticles()) { //PUParticle3D *particle = iter; _predictedPosition = particle->position + _velocityScale * particle->direction; bool collision = false; Vec3 distance = particle->position - _derivedPosition; float distanceLength = distance.length(); float scaledRadius = 0.3333f * (_affectorScale.x + _affectorScale.y + _affectorScale.z) * _radius; // Scaling changed in V 1.3.1 switch(_intersectionType) { case PUParticle3DBaseCollider::IT_POINT: { // Validate for a point-sphere intersection if (_innerCollision == (distanceLength > scaledRadius)) { // Collision detected (re-position the particle) particle->position -= _velocityScale * particle->direction; collision = true; } else { distance = _predictedPosition - _derivedPosition; distanceLength = distance.length(); if (_innerCollision == (distanceLength > scaledRadius)) { // Collision detected collision = true; } } } break; case PUParticle3DBaseCollider::IT_BOX: { //// Validate for a box-sphere intersection //if (particle->particleType != Particle::PT_VISUAL) // break; AABB box; populateAlignedBox(box, particle->position, particle->width, particle->height, particle->depth); //FIXME //if (_innerCollision != box.intersects(_sphere)) //{ // // Collision detected (re-position the particle) // particle->position -= _velocityScale * particle->direction; // collision = true; //} //else //{ // AABB box; // populateAlignedBox(box, // _predictedPosition, // particle->width, // particle->height, // particle->depth); // if (_innerCollision != box.intersects(_sphere)) // { // // Collision detected // collision = true; // } //} } break; } if (collision) { calculateDirectionAfterCollision(particle, distance, distanceLength); calculateRotationSpeedAfterCollision(particle); particle->addEventFlags(PUParticle3D::PEF_COLLIDED); } } }