• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

webgl scene-Graph

m1au

New member
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.
 
Zuletzt bearbeitet:
Zurück
Oben