📄 wparticle.as
字号:
/**
* WOW-Engine AS3 3D Physics Engine, http://www.wow-engine.com
* Copyright (c) 2007-2008 Seraf ( Jerome Birembaut ) http://seraf.mediabox.fr
*
* Based on APE by Alec Cove , http://www.cove.org/ape/
* & Sandy3D by Thomas Pfeiffer, http://www.flashsandy.org/
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
package fr.seraf.wow.primitive {
import fr.seraf.wow.core.WOWEngine;
import fr.seraf.wow.core.collision.WCollision;
import fr.seraf.wow.core.data.WInterval;
import fr.seraf.wow.core.data.WVector;
import fr.seraf.wow.math.WVectorMath;
/**
* The abstract base class for all particles.
*
* <p>
* You should not instantiate this class directly -- instead use one of the subclasses.
* </p>
*/
public class WParticle {
// public properties are not hidden from asdoc?
/** @private */
public var curr:WVector;
/** @private */
public var prev:WVector;
/** @private */
public var isColliding:Boolean;
/** @private */
public var interval:WInterval;
public var name:String;
private var forces:WVector;
private var temp:WVector;
private var _kfr:Number;
private var _mass:Number;
private var _invMass:Number;
private var _fixed:Boolean;
private var _friction:Number;
private var _collidable:Boolean;
private var collision:WCollision;
private var _WOWEngine:WOWEngine;
public static const MIN_MASS:Number = 0.0001;
/**
* @private
*/
public function WParticle (
x:Number=0,
y:Number=0,
z:Number=0,
isFixed:Boolean=true,
mass:Number=1,
elasticity:Number=0.3,
friction:Number=0) {
interval = new WInterval(0,0);
curr = new WVector(x, y,z);
prev = new WVector(x, y,z);
temp = new WVector(0,0,0);
fixed = isFixed;
forces = new WVector(0,0,0);
collision = new WCollision(new WVector(0,0,0), new WVector(0,0,0));
isColliding = false;
this.mass = mass;
this.elasticity = elasticity;
this.friction = friction;
collidable = true;
}
public function get engine():WOWEngine {
return _WOWEngine;
}
public function set engine(e:WOWEngine):void {
_WOWEngine=e
}
/**
* The mass of the particle. Valid values are greater than zero. By default, all particles
* have a mass of 1.
*
* <p>
* The mass property has no relation to the size of the particle. However it can be
* easily simulated when creating particles. A simple example would be to set the
* mass and the size of a particle to same value when you instantiate it.
* </p>
* @throws flash.errors.Error flash.errors.Error if the mass is set less than zero.
*/
public function get mass():Number {
return _mass;
}
/**
* @private
*/
public function set mass(m:Number):void {
_mass = Math.max(m,MIN_MASS);
_invMass = 1 / _mass;
}
/**
* The elasticity of the particle. Standard values are between 0 and 1.
* The higher the value, the greater the elasticity.
*
* <p>
* During collisions the elasticity values are combined. If one particle's
* elasticity is set to 0.4 and the other is set to 0.4 then the collision will
* be have a total elasticity of 0.8. The result will be the same if one particle
* has an elasticity of 0 and the other 0.8.
* </p>
*
* <p>
* Setting the elasticity to greater than 1 (of a single particle, or in a combined
* collision) will cause particles to bounce with energy greater than naturally
* possible. Setting the elasticity to a value less than zero is allowed but may cause
* unexpected results.
* </p>
*/
public function get elasticity():Number {
return _kfr;
}
/**
* @private
*/
public function set elasticity(k:Number):void {
_kfr = k;
}
/**
* The surface friction of the particle. Values must be in the range of 0 to 1.
*
* <p>
* 0 is no friction (slippery), 1 is full friction (sticky).
* </p>
*
* <p>
* During collisions, the friction values are summed, but are clamped between 1 and 0.
* For example, If two particles have 0.7 as their surface friction, then the resulting
* friction between the two particles will be 1 (full friction).
* </p>
*
* <p>
* Note: In the current release, only dynamic friction is calculated. Static friction
* is planned for a later release.
* </p>
*
* @throws flash.errors.Error flash.errors.Error if the friction is set less than zero or greater than 1
*/
public function get friction():Number {
return _friction;
}
/**
* @private
*/
public function set friction(f:Number):void {
_friction = Math.max(Math.min(f,1),0);
}
/**
* The fixed state of the particle. If the particle is fixed, it does not move
* in response to forces or collisions. Fixed particles are good for surfaces.
*/
public function get fixed():Boolean {
return _fixed;
}
/**
* @private
*/
public function set fixed(f:Boolean):void {
_fixed = f;
}
/**
* The position of the particle. Getting the position of the particle is useful
* for drawing it or testing it for some custom purpose.
*
* <p>
* When you get the <code>position</code> of a particle you are given a copy of the current
* location. Because of this you cannot change the position of a particle by
* altering the <code>x</code> and <code>y</code> components of the Vector you have retrieved from the position property.
* You have to do something instead like: <code> position = new Vector(100,100)</code>, or
* you can use the <code>px</code> and <code>py</code> properties instead.
* </p>
*
* <p>
* You can alter the position of a particle three ways: change its position, set
* its velocity, or apply a force to it. Setting the position of a non-fixed particle
* is not the same as setting its fixed property to true. A particle held in place by
* its position will behave as if it's attached there by a 0 length sprint constraint.
* </p>
*/
public function get position():WVector {
return WVectorMath.clone(curr);
}
/**
* @private
*/
public function set position(p:WVector):void {
curr=WVectorMath.clone(p);
prev=WVectorMath.clone(p);
}
/**
* The x position of this particle
*/
public function get px():Number {
return curr.x;
}
/**
* @private
*/
public function set px(x:Number):void {
curr.x = x;
prev.x = x;
}
/**
* The y position of this particle
*/
public function get py():Number {
return curr.y;
}
/**
* @private
*/
public function set py(y:Number):void {
curr.y = y;
prev.y = y;
}
/**
* The y position of this particle
*/
public function get pz():Number {
return curr.z;
}
/**
* @private
*/
public function set pz(z:Number):void {
curr.z = z;
prev.z = z;
}
/**
* The velocity of the particle. If you need to change the motion of a particle,
* you should either use this property, or one of the addForce methods. Generally,
* the addForce methods are best for slowly altering the motion. The velocity property
* is good for instantaneously setting the velocity, e.g., for projectiles.
*
*/
public function get velocity():WVector {
return WVectorMath.sub(curr,prev);
}
/**
* @private
*/
public function set velocity(v:WVector):void {
prev =WVectorMath.sub(curr,v);
}
/**
* Determines if the particle can collide with other particles or constraints.
* The default state is true.
*/
public function get collidable():Boolean {
return _collidable;
}
/**
* @private
*/
public function set collidable(b:Boolean):void {
_collidable = b;
}
// NEED REMOVE FORCES METHODS
/**
* Adds a force to the particle. The mass of the particle is taken into
* account when using this method, so it is useful for adding forces
* that simulate effects like wind. Particles with larger masses will
* not be affected as greatly as those with smaller masses. Note that the
* size (not to be confused with mass) of the particle has no effect
* on its physical behavior.
*
* @param f A Vector represeting the force added.
*/
public function addForce(f:WVector):void {
var f:WVector=WVectorMath.scale(f,invMass)
forces=WVectorMath.addVector(forces,f);
//forces.plusEquals(f.multEquals(invMass));
}
/**
* Adds a 'massless' force to the particle. The mass of the particle is
* not taken into account when using this method, so it is useful for
* adding forces that simulate effects like gravity. Particles with
* larger masses will be affected the same as those with smaller masses.
*
* @param f A Vector represeting the force added.
*/
public function addMasslessForce(f:WVector):void {
//forces.plusEquals(f);
forces=WVectorMath.addVector(forces,f);
}
/**
* @private
*/
public function update(dt2:Number):void {
if (fixed) return;
// global forces
addForce(engine.force);
addMasslessForce(engine.masslessForce);
// integrate
//temp.copy(curr);
temp=WVectorMath.clone(curr);
forces=WVectorMath.scale(forces,dt2)
var nv:WVector =WVectorMath.addVector(velocity,forces);
//var nv:Vector = velocity.plus(forces.multEquals(dt2));
//nv.multEquals(0.98);
nv=WVectorMath.scale(nv,0.98)
nv=WVectorMath.scale(nv,engine.damping)
curr=WVectorMath.addVector(curr,nv);
//curr.plusEquals(nv.multEquals(WOWEngine.damping));
prev=WVectorMath.clone(temp);
//prev.copy(temp);
// clear the forces
forces=new WVector(0,0,0);
}
/**
* @private
*/
public function getComponents(collisionNormal:WVector):WCollision {
var vel:WVector =velocity;
var vdotn:Number = WVectorMath.dot(collisionNormal,vel);
//var vdotn:Number = collisionNormal.dot(vel);
collision.vn = WVectorMath.scale(collisionNormal,vdotn);
//collision.vn = collisionNormal.mult(vdotn);
collision.vt = WVectorMath.sub(vel,collision.vn);
//collision.vt = vel.minus(collision.vn);
return collision;
}
/**
* @private
*/
public function resolveCollision(mtd:WVector, vel:WVector, n:WVector, d:Number, o:Number):void {
curr=WVectorMath.addVector(curr,mtd);
//curr.plusEquals(mtd);
switch (engine.collisionResponseMode) {
case engine.STANDARD:
velocity = vel;
break;
case engine.SELECTIVE:
if (! isColliding) velocity = vel;
isColliding = true;
break;
case engine.SIMPLE:
break;
}
}
/**
* @private
*/
public function get invMass():Number {
return _invMass;
}
/**
* @private
*/
public function getProjection(axis:WVector):WInterval {
return null;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -