Hallo!
Ich habe mir gestern und heute Gedanken zu webgl und zu einem scene-Graphen gemacht.
Ich habe bereits etwas programmiert. Mir würde eure Meinung dazu interessieren, ob das alles Sinn macht.
Zuallererst das grundlegende Prinzip. Es gibt 2 Arten von Klassen für den scene-Graph:
- innere Knoten: Node
Ausschließlich die inneren Knoten sind für Transformationen zuständig.
- leaf-Knoten
Hierfür gibt es die unterschiedlichsten Varianten: Licht-Knoten, Knoten für vertices, ...
Hier mal ein paar Klassen. A steht für eine abstrakte Klasse. + kennzeichnet eine Klasse, die erbt.
Color
AVector
+ Vector: x, y, z
+ Vertex: x, y, z, w
Matrix
AVisitor
+ Renderer
ASpatial: für alle Elemente des scene-Graphen
+ Node: innere Knoten
+ AGeometry: alle Blätter
++ ADrawGeometry: für alle Blätter mit Vertices
+++ DrawArraysGeometry: für gl.drawArrays ... also nur Vertices
+++ DrawElementsGeometry: für gl.drawElements ... also Vertices und Indizes
++ ALight
+++ DirectionalLight
+++ PointLight
++ Camera
Hier Klassendiagramme zu den Klassen. Alle Eigenschaften sind privat. Privates mit - gekenntzeichnet, öffentliches mit +.
Der scene-Graph implementiert das Visitor-Pattern.
Color
=====
- r
- g
- b
- a
=====
+ constructor(_r: number, _g: number, _b: number, _a: number)
+ getter/setter zu r, g, b und a
+ toString(): string
r, g, b und a müssen zwischen [0, 1] liegen.
abstract
AVector
========
+ construct(_x: number, _y: number, _z: number)
========
- x
- y
- z
========
+ getter/setter zu x, y und z
Vector: AVector
===============
+ construct(_x: number, _y: number , _z: number)
===============
+ length(): number
+ normalize(_self: boolean): Vector
+ dot(_other: Vector): number
+ cross(_other: Vector): Vector
+ add(_other: Vector, _self: boolean): Vector
+ toString(): string
Falls _self true ist, wird nichts zurückgegeben, statt dessen der eigene Vektor überarbeitet.
Vertex: AVector
===============
- w
- normal: Vector(0, 0, 0)
===============
+ constructor(_x: number, _y: number, _z: number, _w: number)
+ homogenize(_self: boolean): Vertex
+ minus(_other: Vertex): Vector
+ addNormal(_normal: Vector)
+ normalizeNormal()
+ asVector(): Vector
+ toString(): string
+ getter/setter zu w
normal wird im Konstruktor mit Vector(0, 0, 0) initialisiert. Für einen Phong-Shader muss je Dreiecksfläche
dessen Normale mittels addNormal übergeben werden. Mit normalizeNormal kann man sie normalisieren.
Hier kommt noch eine Color hinzu. Weiß aber noch nicht, ob ich nur setter/getter dafür machen soll, oder ob
das auch im Konstruktor übergeben werden soll.
Matrix
======
- values
======
+ constructor(_values: array)
+ multiplyVertex(_v: Vertex): Vertex
+ multiplyMatrix(_other: Matrix): Matrix
+ toString(): string
+ getter zu values
abstract
AVisitor
========
========
Renderer: AVisitor
==================
==================
+ visitNode(_node: Node)
+ visitDrawArrayGeometry(_geometry: DrawArraysGeometry)
+ visitDrawElementsGeometry(_geometry: DrawElementsGeometry)
+ visitDirectionalLight(_light: DirectionalLight)
+ visitPointLight(_light: PointLight)
+ visitCamera(_camera: Camera)
Der Renderer kann sich dann alle für ihn nötigen Informationen aus dem scene-Graph rausholen.
abstract
ASpatial
========
========
visitNode(_node: Node)
visitDrawArrayGeometry(_geometry: DrawArraysGeometry)
visitDrawElementsGeometry(_geometry: DrawElementsGeometry)
visitDirectionalLight(_light: DirectionalLight)
visitPointLight(_light: PointLight)
visitCamera(_camera: Camera)
Node: ASpatial
==============
- parent: null
- children: []
- localMatrix: Matrix (Identity-Matrix)
- worldMatrix
==============
+ constructor(_localMatrix: Matrix)
+ add(_child: ASpatial)
+ updateWorldMatrix()
+ accept(_visitor: AVisitor)
+ getter/setter zu parent
+ setter zu localMatrix
+ getter zu worldMatrix
+ getter zu children
Den getter für children brauche ich vielleicht gar nicht. Den für localMatrix vermutlich auch nicht.
abstract
AGeometry: ASpatial
====================
- parent: null
====================
+ getter/setter zu parent
+ getter zu worldMatrix
abstract
ADrawGeometry: AGeometry
========================
========================
+ static checkVertices(_vertices: array): array
+ getter für vertices
checkVertices ist öffentlich, damit es von DrawArraysGeometry und DrawElementsGeometry verwendet werden kann.
DrawArraysGeometry: ADrawGeometry
=================================
- vertices
=================================
+ constructor(_vertices: array)
+ setArrays(_vertices: array)
+ accept(_visitor: AVisitor)
+ getter zu vertices
DrawElementsGeometry: ADrawGeometry
===================================
- vertices
- indices
===================================
+ constructor(_vertices: array, _indices: array)
+ static checkIndices(_indices: array): array
+ setElements(_vertices: array, _indices: array)
+ accept(_visitor: AVisitor)
+ getter/setter zu indices
indices müssen integer >= 0 sein.
abstract
ALight: AGeometry
=================
- color
=================
+ constructor(_color: Color)
+ getter/setter zu color
DirectionalLight: ALight
========================
- direction
========================
+ constructor(_color: Color, _direction: Vector)
+ accept(_visitor: AVisitor)
+ getter/setter zu direction
PointLight: ALight
==================
==================
+ accept(_visitor: AVisitor)
Camera: AGeometry
=================
- p
- at
- up
=================
constructor(_p: Vertex, _at: Vertex, _up: Vector)
+ accept(_visitor: AVisitor)
+ getter zu mvMatrix
mvMatrix ist die model-view-Matrix, die sich aus den 3 Vektoren ergeben.
Aktuell habe ich p, at und up mit var deklariert, aber ich glaube, let würde reichen.
Aktuell arbeit ich nur lokal im Konstruktor damit.
Also ev. führe ich p, at und up dann gar nicht mehr als Eigenschaften.
Vielleicht kommen aber auch noch getter und setter hinzu.
Ich habe mir gestern und heute Gedanken zu webgl und zu einem scene-Graphen gemacht.
Ich habe bereits etwas programmiert. Mir würde eure Meinung dazu interessieren, ob das alles Sinn macht.
Zuallererst das grundlegende Prinzip. Es gibt 2 Arten von Klassen für den scene-Graph:
- innere Knoten: Node
Ausschließlich die inneren Knoten sind für Transformationen zuständig.
- leaf-Knoten
Hierfür gibt es die unterschiedlichsten Varianten: Licht-Knoten, Knoten für vertices, ...
Hier mal ein paar Klassen. A steht für eine abstrakte Klasse. + kennzeichnet eine Klasse, die erbt.
Color
AVector
+ Vector: x, y, z
+ Vertex: x, y, z, w
Matrix
AVisitor
+ Renderer
ASpatial: für alle Elemente des scene-Graphen
+ Node: innere Knoten
+ AGeometry: alle Blätter
++ ADrawGeometry: für alle Blätter mit Vertices
+++ DrawArraysGeometry: für gl.drawArrays ... also nur Vertices
+++ DrawElementsGeometry: für gl.drawElements ... also Vertices und Indizes
++ ALight
+++ DirectionalLight
+++ PointLight
++ Camera
Hier Klassendiagramme zu den Klassen. Alle Eigenschaften sind privat. Privates mit - gekenntzeichnet, öffentliches mit +.
Der scene-Graph implementiert das Visitor-Pattern.
Color
=====
- r
- g
- b
- a
=====
+ constructor(_r: number, _g: number, _b: number, _a: number)
+ getter/setter zu r, g, b und a
+ toString(): string
r, g, b und a müssen zwischen [0, 1] liegen.
abstract
AVector
========
+ construct(_x: number, _y: number, _z: number)
========
- x
- y
- z
========
+ getter/setter zu x, y und z
Vector: AVector
===============
+ construct(_x: number, _y: number , _z: number)
===============
+ length(): number
+ normalize(_self: boolean): Vector
+ dot(_other: Vector): number
+ cross(_other: Vector): Vector
+ add(_other: Vector, _self: boolean): Vector
+ toString(): string
Falls _self true ist, wird nichts zurückgegeben, statt dessen der eigene Vektor überarbeitet.
Vertex: AVector
===============
- w
- normal: Vector(0, 0, 0)
===============
+ constructor(_x: number, _y: number, _z: number, _w: number)
+ homogenize(_self: boolean): Vertex
+ minus(_other: Vertex): Vector
+ addNormal(_normal: Vector)
+ normalizeNormal()
+ asVector(): Vector
+ toString(): string
+ getter/setter zu w
normal wird im Konstruktor mit Vector(0, 0, 0) initialisiert. Für einen Phong-Shader muss je Dreiecksfläche
dessen Normale mittels addNormal übergeben werden. Mit normalizeNormal kann man sie normalisieren.
Hier kommt noch eine Color hinzu. Weiß aber noch nicht, ob ich nur setter/getter dafür machen soll, oder ob
das auch im Konstruktor übergeben werden soll.
Matrix
======
- values
======
+ constructor(_values: array)
+ multiplyVertex(_v: Vertex): Vertex
+ multiplyMatrix(_other: Matrix): Matrix
+ toString(): string
+ getter zu values
abstract
AVisitor
========
========
Renderer: AVisitor
==================
==================
+ visitNode(_node: Node)
+ visitDrawArrayGeometry(_geometry: DrawArraysGeometry)
+ visitDrawElementsGeometry(_geometry: DrawElementsGeometry)
+ visitDirectionalLight(_light: DirectionalLight)
+ visitPointLight(_light: PointLight)
+ visitCamera(_camera: Camera)
Der Renderer kann sich dann alle für ihn nötigen Informationen aus dem scene-Graph rausholen.
abstract
ASpatial
========
========
visitNode(_node: Node)
visitDrawArrayGeometry(_geometry: DrawArraysGeometry)
visitDrawElementsGeometry(_geometry: DrawElementsGeometry)
visitDirectionalLight(_light: DirectionalLight)
visitPointLight(_light: PointLight)
visitCamera(_camera: Camera)
Node: ASpatial
==============
- parent: null
- children: []
- localMatrix: Matrix (Identity-Matrix)
- worldMatrix
==============
+ constructor(_localMatrix: Matrix)
+ add(_child: ASpatial)
+ updateWorldMatrix()
+ accept(_visitor: AVisitor)
+ getter/setter zu parent
+ setter zu localMatrix
+ getter zu worldMatrix
+ getter zu children
Den getter für children brauche ich vielleicht gar nicht. Den für localMatrix vermutlich auch nicht.
abstract
AGeometry: ASpatial
====================
- parent: null
====================
+ getter/setter zu parent
+ getter zu worldMatrix
abstract
ADrawGeometry: AGeometry
========================
========================
+ static checkVertices(_vertices: array): array
+ getter für vertices
checkVertices ist öffentlich, damit es von DrawArraysGeometry und DrawElementsGeometry verwendet werden kann.
DrawArraysGeometry: ADrawGeometry
=================================
- vertices
=================================
+ constructor(_vertices: array)
+ setArrays(_vertices: array)
+ accept(_visitor: AVisitor)
+ getter zu vertices
DrawElementsGeometry: ADrawGeometry
===================================
- vertices
- indices
===================================
+ constructor(_vertices: array, _indices: array)
+ static checkIndices(_indices: array): array
+ setElements(_vertices: array, _indices: array)
+ accept(_visitor: AVisitor)
+ getter/setter zu indices
indices müssen integer >= 0 sein.
abstract
ALight: AGeometry
=================
- color
=================
+ constructor(_color: Color)
+ getter/setter zu color
DirectionalLight: ALight
========================
- direction
========================
+ constructor(_color: Color, _direction: Vector)
+ accept(_visitor: AVisitor)
+ getter/setter zu direction
PointLight: ALight
==================
==================
+ accept(_visitor: AVisitor)
Camera: AGeometry
=================
- p
- at
- up
=================
constructor(_p: Vertex, _at: Vertex, _up: Vector)
+ accept(_visitor: AVisitor)
+ getter zu mvMatrix
mvMatrix ist die model-view-Matrix, die sich aus den 3 Vektoren ergeben.
Aktuell habe ich p, at und up mit var deklariert, aber ich glaube, let würde reichen.
Aktuell arbeit ich nur lokal im Konstruktor damit.
Also ev. führe ich p, at und up dann gar nicht mehr als Eigenschaften.
Vielleicht kommen aber auch noch getter und setter hinzu.
Zuletzt bearbeitet: