| Description | Hierarchy | Fields | Methods | Properties |
type TNodeGeneralShape = class(TVRMLNode)
Shape is the only node that produces some visible results during rendering. Basically, most if the VRML language is just a method of describing those shapes and many other nodes are defined only to set up additional state for shapes (materials, transformations, lighting).
Some exceptions to this are camera nodes, sensors (WWWAnchor in VRML 1.0), Info, WorldInfo, Background, Fog. These nodes specify some things that can't be embedded in simple Render command for a node. These things describe
user interaction with the world (cameras, sensors)
some information that has no meaning to us and all we can do about it (besides ignoring it) is to show it to the user (Info, WorldInfo)
some information about how to render the world that cannot be just expressed as "modifying the way all subsequent shapes are drawn" (Fog, Background)
This class may have some special functionality and it builds comfortable object inheritance hierarchy. For example, now we can use EnumerateNodes(TNodeGeneralShape).
A few things that make Shape node special :
Only shape nodes may have [Local]BoundingBox.
Only shape nodes define something visible "in usual way" during rendering (Some other nodes in VRML 2.0 are visible but in an unusual way, like Background and Fog. These nodes must be rendered in a special way — they are not affected in any usual way by the current transformation matrix etc.)
Only shape nodes can add triangles to the scene, so the Triangulate method can be defined only for shape nodes.
Shape nodes are never "grouping nodes", in particular there's never a shape node that is (direct or indirect) child of another shape node. So there's no need to be concerned whether shape nodes' children are included in things like [Local]BoundingBox or Triangles/VerticesCount.
Shape nodes don't affect anything in graph traverse state.
![]() |
function BoundingBox(State: TVRMLGraphTraverseState): TBox3d; virtual; |
![]() |
function LocalBoundingBox(State: TVRMLGraphTraverseState): TBox3d; virtual; |
![]() |
function VerticesCount(State: TVRMLGraphTraverseState; OverTriangulate: boolean): Cardinal; virtual; abstract; |
![]() |
function TrianglesCount(State: TVRMLGraphTraverseState; OverTriangulate: boolean): Cardinal; virtual; abstract; |
![]() |
procedure Triangulate(State: TVRMLGraphTraverseState; OverTriangulate: boolean; NewTriangleProc: TNewTriangleProc); |
![]() |
procedure LocalTriangulate(State: TVRMLGraphTraverseState; OverTriangulate: boolean; NewTriangleProc: TNewTriangleProc); virtual; abstract; |
![]() |
function BoundingBox(State: TVRMLGraphTraverseState): TBox3d; virtual; |
|
LocalBoundingBox liczy W tej klasie LocalBoundingBox jest liczone jako Zwracam uwage ze odwrotny pomysl — realizacja Tym niemniej miejscami zamierzam tak liczyc W kazdej podklasie Shape powinienes pokryc przynajmniej jedna z tych metod — jak to napisalem powyzej, jezeli nie pokryjesz | |
![]() |
function LocalBoundingBox(State: TVRMLGraphTraverseState): TBox3d; virtual; |
![]() |
function VerticesCount(State: TVRMLGraphTraverseState; OverTriangulate: boolean): Cardinal; virtual; abstract; |
|
kazda podklasa GeneralShape musi pokrywac i implementowac te metody. Te metody zwracaja ilosc trojkatow jaka definiuje [Local]Triangulate (z takimi samymi parametrami State i OverTriangulate) dla tego node'a i ilosc roznych vertexow jakie sa uzywane w tych trojkatach (chociaz nie wykonuje w tym celu zadnych porownan miedzy zdefiniowanymi punktami w node'ach i definiujac nieporzadnie node'y (np. podajac dwa razy ten sam punkt w Coordinate3) mozesz latwo to oszukac). (acha, dla PointSet naturalnie nie ma zadnych trojkatow ale State chwilowo nie jest nigdzie uzywany w TrianglesCount, ale jestem gotowy gdyby w przyszlosci jakis node tego potrzebowal (bo w sumie nie byloby w tym nic wyjatkowego, tzn. nie byloby to nic co w modelu VRMLu jaki tu zaimplementowalem musialbym gdziekolwiek traktowac jako jakis wyjatek) Uwaga — gdy przychodzi do TrianglesCount moze sie okazac ze Triangulate zwrocilo inna ilosc trojkatow gdy niektore face byly non-convex (bo w tym przypadku TriangulateFace ma prawo pousuwac trojkaty zdegenerowane do punktu). Generalnie nie polegaj na TrianglesCount jako na dokladnej wartosci — raczej jako na przyblizeniu ktore zazwyczaj bedzie bardzo bardzo dokladne. | |
![]() |
function TrianglesCount(State: TVRMLGraphTraverseState; OverTriangulate: boolean): Cardinal; virtual; abstract; |
![]() |
procedure Triangulate(State: TVRMLGraphTraverseState; OverTriangulate: boolean; NewTriangleProc: TNewTriangleProc); |
|
LocalTriangulate robi to samo ale nie uwzglednia State.Transform. W podklasach trzeba zdefiniowac tylko LocalTriangulate. Jezeli OverTriangulate = false to [Local] Jezeli OverTriangulate = true to [Local] | |
![]() |
procedure LocalTriangulate(State: TVRMLGraphTraverseState; OverTriangulate: boolean; NewTriangleProc: TNewTriangleProc); virtual; abstract; |