summaryrefslogtreecommitdiff
path: root/src/sims/dynamics/Shape.scala
blob: f57bbc688eb33c21eadace21b3b736ea46dd7c16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * 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 <code>axis</code>.
   * @param axis Richtungsvektor der Geraden
   * @return Projektion dieser Form*/
  def project(axis: Vector2D): Projection
  
  /**Ermittelt ob der gebene Punkt <code>point</code> 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 <code>s</code>.*/
  def ^(s: Shape) = new Body(this, s)
  
  /**Erstellt einen Koerper aus dieser Form und den Formen des Koerpers <code>b</code>.*/
  def ^(b: Body) = {
    val shapes = this :: b.shapes
    new Body(shapes: _*)
  }
}

object Shape {
  private var uidCounter = -1
  private def nextUid = {uidCounter += 1; uidCounter}
}