//! Base implementation of a physical particle for the sju physics engine /*! * A physical particle is the simplest physical object that can exist, yet it * will respond accordingly to nearly all the effects and objects included in * the physics engine and can be used to simulate more complicated objects * cheaply. */ /* Copyright (C) 2009 Alejandro Valenzuela Roca, * * This file is part of MotorJ, a free framework for videogame creation. * * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ #include "pparticle-class.h" pParticle::pParticle() { cGeometry = CG_PT; cGeometryData = NULL; rotDragFactor = 0; e = 1.0; v3_0(&v); v3_0(&a); v3_0(&rotv); v3_0(&rota); hasCollision = true; hasGravitation = false; hasGravity = true; hasCharge = false; } void pParticle::SetData(float m0, float mInertia0, vector3 & v0, vector3 & rotv0) { mass = m0; mInertia = mInertia0; invmass = 1.0/mass; invMInertia = 1.0/mInertia; vec_copy(v0, &v); vec_copy(rotv0, &rotv); collStatus = COLR_NOCOLLISION; } void pParticle::ApplyEffect(vector3 effect, vector3 &pointOfAction, sjuPETypes effectType, IPhysicalObject* interactionObject) { //printf("Got effect %d:%f,%f,%f\n", effectType, effect.x, effect.y, effect.z); if (effectType == PE_C_IMMOVABLE) { // Collision reaction needs to be delayed until the speed // has been recalculated collisionDetected = true; vec_copy(effect, &f_1); normalize(&f_1); } else if (effectType == PE_ACCEL) { // Acceleration response vec_sum2(effect, &a); } else if (effectType == PE_FRFIELD) { v.x *= 1-effect.x; v.y *= 1-effect.y; v.z *= 1-effect.z; } else if (effectType == PE_ROTACCEL) { vec_sum2(effect, &rota); } else if (effectType == PE_TORQUE) { vec_sum(invMInertia, effect, &rota); } else if (effectType == PE_CONTACT) { vec_copy(effect, &v); } else { //printf("%3.3f: %3.3f, %3.3f, %3.3f\n", invmass, effect.x, effect.y, effect.z); vec_sum(invmass, effect, &a); } } void pParticle::ResetAccels() { v3_0(&a); v3_0(&rota); collisionDetected = false; collStatus = COLR_NOCOLLISION; } void pParticle::Update(float t_elapsed) { vector3 rotD; vector3 rotU; //printf("a: %3.3f,%3.3f,%3.3f\n", a.x, a.y, a.z); //printf("v %3.3f,%3.3f,%3.3f\n", v.x, v.y, v.z); vec_sum(t_elapsed, a, &v); vec_sum(t_elapsed, rota, &rotv); if (collisionDetected) { // Get current velocity's magnitude float speed = normalize(&v); vector3 r; // Now perform reflection vec_refl(v, f_1, &r); // Set reflected v as new v vec_copy(r,&v); // Set speed back mul_scal(e*speed, &v); } // Do the dragFactor scaling mul_scal(1.0-dragFactor, &v); mul_scal(1.0-rotDragFactor, &rotv); vec_sum(t_elapsed, v, &p); if (vec_norm(rotv) > 0.0001) { cross(rotv, dir, &rotD); cross(rotv, up, &rotU); //printf("rE: %f %f %f\n", rotE.x, rotE.y, rotE.z ); vec_sum(t_elapsed, rotD, &dir); vec_sum(t_elapsed, rotU, &up); //vec_sum2(rotE, &dir); normalize(&dir); normalize(&up); } //printf("d: %3.3f, %3.3f, %3.3f\n", dir.x, dir.y, dir.z); //printf("p:" } pParticle::~pParticle() { }