/*
* Simple Mechanics Simulator (SiMS)
* copyright (c) 2009 Jakob Odersky
* made available under the MIT License
*/
package sims.dynamics
import sims.geometry._
import sims.collision._
/**
* Eine abstrakte Form.
*/
abstract class Shape{
/**Einzigartige Identifikationsnummer.*/
val uid: Int = Shape.nextUid
/**Kollisionsfaehigkeit.*/
var collidable: Boolean = true
/**Teil der Stosszahl bei einer Kollision zwischen dieser Form und einer anderen.
* Die Stosszahl wird aus dem Produkt der beiden Teile der Formen errechnet.*/
var restitution: Double = 0.7
/**Teil des Reibungskoeffizienten bei einer Kollision zwischen dieser Form und einer anderen.
* Der Reibungskoeffizient wird aus dem Produkt der beiden Teile der Formen errechnet.*/
var friction: Double = 0.707
/**Position des Schwerpunktes in Welt.*/
var pos: Vector2D = Vector2D.Null
/**Rotation. Entspricht Laenge des Rotationsvektors.*/
var rotation: Double = 0
/**Initiale Rotation. (Rotation ohne Koerper)*/
var rotation0 = 0.0
/**Referenzposition in Koerper. Wird zur Rotation von Formen in Koerpern verwendet.*/
var refLocalPos: Vector2D = Vector2D.Null
/**Dichte. (Masse pro Flaeche)*/
val density: Double
/**Volumen. Entspricht eigentlich der Flaeche dieser Form (in 2D) wird aber zum Errechnen der Masse verwendet.*/
val volume: Double
/**Errechnet die Masse dieser Form. Masse ist gleich Volumen mal Dichte.
@return Masse der Form*/
def mass = volume * density
/**Errechnet Traegheitsmoment zum Schwerpunkt dieser Form.
@return Traegheitsmoment zum Schwerpunkt*/
val I: Double
/**Beinhaltender Koerper. Sollte nicht selbst bei Initialisierung definiert werden.*/
var body: Body = _
/**Gibt das umfassende AABB dieser Form zurueck.
@return umfassendes AABB*/
def AABB: AABB
/**Ergibt die Projektion dieser Form auf eine Gerade gegeben durch den
* Richtungsvektor axis
.
* @param axis Richtungsvektor der Geraden
* @return Projektion dieser Form*/
def project(axis: Vector2D): Projection
/**Ermittelt ob der gebene Punkt point
in dieser Form enthalten ist.*/
def contains(point: Vector2D): Boolean
/**Baut einen Koerper aus dieser Form.
@return ein Koerper bestehend aus dieser Form. */
def asBody = new Body(this)
/**Formen mit denen diese Form nicht Kollidiert.*/
val transientShapes: collection.mutable.Set[Shape] = collection.mutable.Set()
/**Erstellt einen Koerper aus dieser Form und der Form s
.*/
def ^(s: Shape) = new Body(this, s)
/**Erstellt einen Koerper aus dieser Form und den Formen des Koerpers b
.*/
def ^(b: Body) = {
val shapes = this :: b.shapes
new Body(shapes: _*)
}
}
object Shape {
private var uidCounter = -1
private def nextUid = {uidCounter += 1; uidCounter}
}