Unit VRMLNodes
Description
This unit defines VRML nodes. This is the most important unit for VRML processing, as nodes are the key idea in VRML.
In fact, the whole VRML file is just a VRML node (if necessary, we wrap it inside one "artificial" node, see TNodeHiddenGroup_1 or TNodeHiddenGroup_2), so "processing VRML nodes" means also "processing VRML files". And this unit allows you to read nodes from the stream (with the help of lexer in VRMLLexer unit and parser of VRML fields in VRMLFields unit). We also have here methods to save nodes back to stream.
I przede wszystkim metody do przeszukiwania grafu VRML'a na rozne sposoby — patrz metody Traverse, EnumerateNodes i FindNode. Szczegolnie metoda Traverse jest wazna : pozwala ona zamienic graf VRMl'a na liste par (Node typu TGeneralShapeNode + State : TVRMLGraphTraverseState). Renderowanie takiej listy sprowadza sie teraz do wyrenderowania kazdej takiej pary, czyli kazdego shape'u z odpowiednimi ustawieniami State. To jest cala robota jaka musi wykonac renderer taki jak np. OpenGLRenderer w VRMLOpenGLRenderer (alternatywnie, renderer moze uzywac tez Triangulate).
Oraz kazdy node ma zdefiniowane swoje pola i wiele node'ow maja zaimplementowane pewne ogolne metody do operowania na nich (ladowanie zawartosci w node'ach WWWInline i Texture2, funkcja MatrixTransformation w podklasach GeneralTransformation itp.) Node'y z grupy GeneralShape maja kilka istotnych metod jak [Local]BoudingBox, Vertices/TrianglesCount, Triangulate.
Ten modul naturalnie nie zalezy od OpenGL'a. Tak miedzy nami to kiedys zalezal od OpenGL'a i w ogole bylo tu zaimplementowane mnostwo innych rzeczy, m.in. jadro renderera OpenGL'owego i bylo tu naprawde tloczno. Ale teraz juz jest czysto. I jestesmy kompletnie niezalezni od renderera, co jest wazne bo renderer przez OpenGL'a nie jest juz jedynym mozliwym rendererem - mamy juz VRMLRayTracer.
As for VRML versions handling:
We handle both VRML 1.0 and 2.0. Every correct VRML file should be parsed by this unit.
Also many Inventor 1.0 files should be correctly parsed. We handle Inventor 1.0 mostly like VRML 1.0, also some small things and nodes specific for Inventor 1.0 are implemented here, see [http://vrmlengine.sourceforge.net/kambi_vrml_extensions.php#ext_iv_in_vrml].
TNodeUnknown pozwala omijac parserowi nawet kompletnie nieznane node'y pozbawione pol "fields" i "isA" (z VRML'a 1.0 extensibility features). Dlatego jestesmy w stanie odczytac i wyswietlic satysfakcjonujaca czesc wiekszosci plikow Inventora jakie mialem w /usr/share/inventor/demos/. Super !
Nawet dla VRMLa 1.0 w wielu miejscach uzywam specyfikacji VRMLa 97:
zeby ustalic rzeczy zdefiniowane w niejasny sposob w specyfikacji VRML 1.0
zeby pododawac do VRMLa 1.0 male drobiazgi z VRMLa 97, jak attenuation swiatel
VRMLRayTracer uzywa modelu oswietlenia zdefiniowanego w specyfikacji VRMLa 97
Note that structures in this unit are not focused on either VRML 1.0 or VRML 2.0. On the contrary: we try to handle the sum of VRML 1.0 and 2.0. When reading VRML 1.0, many VRML 2.0 constructs (that not conflict with anything in VRML 1.0) are allowed, and the other way around too.
Internally, we do not convert VRML 1.0-specific constructs to VRML 2.0 constructs (or the other way around). For example, we do not convert VRML 1.0 idea of direct children nodes to VRML 2.0 idea of children nodes embedded in MFNode fields. We just allow both constructs. In fact, you could define here a node that uses both VRML 1.0 children nodes and has some MFNode fields — in other words, a node invalid in terms of VRML 1.0 spec and invalid in terms of VRML 2.0 spec, but valid if you take "sum of features" of both VRML versions.
Sometimes this means more work for us, as some similar ideas have to be implemented in two different ways, and then some common access methods (like SmartChild* methods of TVRMLNode) must be done. But the advantage is that we have a clean implementation, that is suited and perfectly conforming to both VRML 1.0 and 2.0.
Notka do mechanizmu wczytywania grafu VRMLa : jak widac nie robimy dekonstrukcji w czasie odczytywania sceny - co znaczy tyle ze po odczytaniu calego strumienia jestesmy w stanie zapisac z powrotem do innego strumienia cala scene VRMLa, nie tracac zadnej informacji. O ile oczywiscie na renderowanie i w ogole wiekszosc operacji mozna patrzec jako na jakis rodzaj dekonstrukcji to my zawsze zostajemy w posiadaniu calej informacji o scenie. Sa dwa wyjatki :
Inline nodes (WWWInline, Inline, InlineLoadControl) ktore w BeforeTraverse laduje swoja scene jako swoje dziecko
w przypadku scen o wielu root node'ach (ktore sa de facto niepoprawne trzymajac sie sciscle specyfikacji VRMLa 1.0, chociaz sa poprawne w VRMLu 97 i ja je dopuszczam takze w VRMLu 1.0, patrz nizej) jezeli root node'ow w pliku byloby wiele to jako root node tworzymy sobie node Group i w nim umieszczamy wszystkie root nodes.
(Jest to zaimplementowane w ParseVRMLFile. Jest to chyba najbardziej sensowny sposob w jaki mozna to zrobic - w programie bedziemy chcieli przeciez reprezentowac model VRMLa jako jeden obiekt; wiec nalezaloby uzyc TVRMLNodesList, ale wtedy musielibysmy powtorzyc implementacje wielu rzeczy w TVRMLNode takze dla takiej listy; wiec tutaj pomysl: przeciez klasa TNodeGroup jest wlasnie taka prosta lista node'ow.)
We represent this special "additional" Group node as a TNodeGroupHidden_1/2, that is a descendant of TNodeGroup (not the other way around). This way you can entirely forget about this issue and just process the VRML model as you like, and the only downside will be that you will actually work with a different model (with additional Group node) than what was encoded in the file. You can also test for (Node is TNodeGroupHidden_1/2) and recognize this special case.
Takie unikanie dekonstrukcji pozwoli nam
na unikniecie zbytniego przywiazania naszego kodu VRMLa do konkretnych zastosowan. Poniewaz mamy cala informacje o scenie mozemy zrobic wszystko co mozemy zrobic ze scena VRMLa - co nie byloby mozliwe gdybysmy w czasie dekonstrukcji (np. wykonujac juz w czasie odczytu wszystkie transformacje na macierzy i transformujac punkty) tracili jakas czesc informacji.
no i mozemy w ten sposob latwo wykorzystac nasz kod VRMLa do pisania konwerterow innych formatow na VRMLa. Uzywajac modulu Object3dAsVRML i tutejszego SaveToVRMLFile mamy sliczny konwerter 3ds, obj, geo -> VRML.
Specyfikacja VRMLa 1.0 z dodanymi "moimi rozszerzeniami VMRLa" [http://vrmlengine.sourceforge.net/kambi_vrml_extensions.php] stanowia uzasadnienie dla wielu rzeczy ktore robimy w tym module.
Node'y o nazwach *General* to nie sa koncowe klasy node'ow, to tylko klasy posrednie jak GeneralShape, GeneralLight, GeneralCamera, GeneralTraformation itp. Te klasy pozwalaja nam zaimplementowac jakas funkcjonalnosc dla kilku podobnych klas jednoczesnie, te klasy buduja tez ladne drzewko zaleznosci obiektow dzieki czemu np. w EnumerateNodes mozemy jako parametr podac TNodeGeneralLight aby znalezc wszystkie swiatla na scenie.
24 sierpnia 2003: znaczne osiagniecie : wyeliminowalem typ TVRMLNodeKind ktory wyliczal mi wszystkie istniajace klasy node'ow. Dzieki temu typowi moglem latwo robic powiazania w stylu "dana nazwa wezla VRMLa odpowiada jakiej podklasie TVRMLNode ?" : taki typ (razem z kilkoma stalymi) przechowywal mi informacje o wszystkich istniejacych koncowych podklasach TVRMLNode. Wada tego jednak byl fakt ze wszystkie wezly VRMLa musialy byc zdefiniowane w tym jednym module. Nie mozna bylo np. w malfunction zaimplementowac specjalnych node'ow w stylu "MalfunctionLevel { fog TRUE }" do uzytku tylko przez malfunction. To znaczy nie bylo praktycznie sensu definiowac potomkow typu TVRMLNode w innych modulach niz VRMLNodes bo nawet jesli mogles zdefiniowac podklasy TVRMLNode w innych modulach to i tak nie mogles ich uzyc (bo zeby one byly widziane przez mechanizm odwzorowywania "nazwa VRMLa -> podklasa TVRMLNode" musialy byc dodane do odpowiednich stalych w TYM module...). Usunalem ta niedogodnosc eliminujac zupelnie typ TVRMLNodeKind. Teraz nie ma zadnej stalej tablicy przechowujacej jakies informacje na temat "wszystkich dostepnych node'ow" - ekwiwalentem tego jest obiekt NodesManager w ktorym mozna w czasie wykonania programu rejestrowac dowolne stworzone podklasy TVRMLNode (prawdopodobnie najsensowniej jest robic to w sekcji initialization modulu; uzywaj tego podobnie jak Picture.RegisterPictureClass z Graphics z VCLa Borlanda.). Ciagle pozostaje niestety ograniczenie ze wszystkie wezly ktore maja byc uwzgledniane w tablicy TVRMLGraphTraverseState.LastNodes musza byc zadeklarowane w tym module. To powoduje ze ciagle nie mozemy przerzucic implementacji wszystkich specyficznych node'ow do jakiegos osobnego modulu. Ktoregos dnia, gdy ograniczenie to zacznie mi przeszkadzac, zapewne to zaimplementuje (tablica TraverseStateLastNodesClasses bedzie musiala byc wtedy zrobiona jako dynamiczna lista klas TVRMLNodeClass; problemem jest tutaj ze TTraverseStateLastNodes bedzie wtedy takze musialo byc struktura dynamiczna i proste zapytania LastNodes.Coordinate3 bedzie musialo byc zastapione na cos mniej wygodnego i badziej czasochlonnego podczas wykonywania : LastNodes.NodesFind[TNodeCoordinate3].) Aby wykazac ze to rzeczywiscie dziala (i to dziala calkiem fajnie) zapisalem w malfunction w LevelUnit cztery node'y specyficzne dla malfunction : MalfunctionLevelInfo, Malfunction(NotMoving|CircleMoving|Hunting)Enemy. Teraz definicje leveli malfunction nie potrzebuja ZADNYCH specjalnie parsowanych wezlow Info. Zalety: parser+lekser VRMLa od razu robia mi mnostwo checkow i podaja moim node'ow gotowy wynik. Kod parsowania zawartosci wezlow Info byl bardzo prosty, mimo to teraz nie musimy go juz w ogole pisac - wszystko zrzucamy na leksera+parsera VRMLa. Ponadto nasze node'y dzialaja od razu w ramach wezlow VRMLa, a wiec np. nie trzeba sobie wszedzie pisac co sie stanie jesli nie podasz tego pola. W VRMLu jesli nie podasz pola to zostanie uzyta jego wartosc domyslna, wystarczy powiedziec ile ona wynosi. Trzeba przyznac ze do tak prostych zadan jak levele malfunction definiowanie wlasnych wezlow VRMLa zapewnia duza elegancje w kodzie ale nie daje az tak wiele realnych zyskow.
Examples of defining your own VRML node types (without modifying sources of this unit, or any other unit) are in these programs: - bezier_curves (VRMLBezierCurve) - malfunction (LevelUnit)
Co do zapisywania VRMLa : - kazde pole zapisuje 1 lub wiecej calych linii - kazdy node zapisuje najpierw linie [DEF NodeName] NodeKindName { potem swoje pola potem swoje subnode'y potem linie } zmieniajac Indent o IndentIncrement zdefiniowane w VRMLFields - linie sa konczone przez nl - mechanizm DEF/USE pol jest zapisywany dobrze, tzn. jezeli jakies pole jest obecne wiecej niz raz w drzewie VRML'a to jest zapisywane do pliku tylko raz, kazdy nastepny zapis to tylko zapisanie 'USE <NodeName>' - w wiekszosci przypadkow pola o wartosciach domyslnych nie sa zapisywane. W zasadzie zapisywanie pol o wartosciach domyslnych nie byloby bledem, choc mogloby denerwowac userow. Ale my naprawde tego potrzebujemy ze wzgledu na male rozszerzenia VRMLa 1.0 jakie tu zaimplementowalem (patrz wyzej). Jesli chcemy zapisywac poprawne pliki VRMLa to nie mozemy dopuszczac zeby np. eksport pliku 3DS na VRMLa dodawal jakies pole "mirror" do kazdego Materialu. Wiec nie bedziemy zapisywac "mirror" kiedy "mirror" = [0.0] i w ten sposob rozwiazujemy problem. Jednoczesnie, jesli ktos rzeczywiscie stworzyl plik podajac wlasciwosc "mirror" rozna od domyslnej to uwzglednimy wszedzie to pole i zapiszemy je w razie potrzeby z powrotem do pliku VRMLa.
uses
Overview
Classes, Interfaces, Objects and Records
Functions and Procedures
Types
TVRMLNodeClass = class of TVRMLNode; |
TVRMLNodeProc = procedure (node: TVRMLNode) of object; |
PActiveLight = ˆTActiveLight; |
TDynArrayItem_1 = TActiveLight; |
PDynArrayItem_1 = PActiveLight; |
TInfiniteArray_1 = array[0..MaxInt div SizeOf(TDynArrayItem_1)-1]of TDynArrayItem_1; |
PInfiniteArray_1 = ˆTInfiniteArray_1; |
TDynArrayItemIsSmallerFunc_1 = function (const a, b: TDynArrayItem_1): boolean; |
TDynArrayItemIsSmallerFuncByObject_1 = function (const a, b: TDynArrayItem_1): boolean of object; |
TArray_ActiveLight = TInfiniteArray_1; |
PArray_ActiveLight = PInfiniteArray_1; |
PTraversingInfo = ˆTTraversingInfo; |
TTraversingFunc = procedure (Node: TVRMLNode; State: TVRMLGraphTraverseState; ParentInfo: PTraversingInfo) of object; |
TBlenderTraversingFunc = procedure ( BlenderObjectNode: TVRMLNode; const BlenderObjectName: string; BlenderMeshNode: TVRMLNode; const BlenderMeshName: string; ShapeNode: TNodeGeneralShape; State: TVRMLGraphTraverseState) of object; |
TEnumerateChildrenFunction = procedure (Node, Child: TVRMLNode) of object; |
TEnumerateRemoveNodesFunction = procedure (ParentNode, Node: TVRMLNode; var RemoveNode: boolean) of object; |
TNewTriangleProc = procedure (const Tri: TTriangle3Single; State: TVRMLGraphTraverseState; ShapeNode: TNodeGeneralShape; const MatNum, FaceCoordIndexBegin, FaceCoordIndexEnd: integer) of object; |
TObjectsListItem_3 = TVRMLNode; |
TObjectsListIsSmallerFunction_3 = function (const A, B: TObjectsListItem_3): boolean of object; |
TVRMLFontJustify = (...); |
TVRMLFontFamily = (...); |
TVRMLCameraKind = (...); |
TNodeGeneralViewpointClass = class of TNodeGeneralViewpoint; |
TObjectsListItem_1 = TNodeGeneralLight; |
TObjectsListIsSmallerFunction_1 = function (const A, B: TObjectsListItem_1): boolean of object; |
TObjectsListItem_2 = TVRMLInterfaceDeclaration; |
TObjectsListIsSmallerFunction_2 = function (const A, B: TObjectsListItem_2): boolean of object; |
TObjectsListItem_4 = TVRMLPrototypeBase; |
TObjectsListIsSmallerFunction_4 = function (const A, B: TObjectsListItem_4): boolean of object; |
TObjectsListItem_5 = TVRMLRoute; |
TObjectsListIsSmallerFunction_5 = function (const A, B: TObjectsListItem_5): boolean of object; |
Constants
CountTraverseStateLastNodes = 10; |
HighTraverseStateLastNodes = CountTraverseStateLastNodes - 1; |
DefaultMaterial_1AmbientColor: TVector3Single = (0.2, 0.2, 0.2); |
DefaultMaterial_2AmbientIntensity = 0.2; |
DefaultMaterialDiffuseColor: TVector3Single = (0.8, 0.8, 0.8); |
DefaultMaterialSpecularColor: TVector3Single = (0, 0, 0); |
DefaultMaterialEmissiveColor: TVector3Single = (0, 0, 0); |
DefaultMaterialShininess = 0.2; |
DefaultMaterialTransparency = 0.0; |
DefaultMaterialMirror = 0.0; |
DefaultMaterialReflSpecularExp = 1000000; |
DefaultMaterialTransSpecularExp = 1000000; |
TraverseStateLastNodesClasses :
array[0..HighTraverseStateLastNodes] of TVRMLNodeClass =
( TNodeCoordinate3, TNodeShapeHints, TNodeFontStyle_1,
TNodeMaterial_1, TNodeMaterialBinding, TNodeNormal, TNodeNormalBinding,
TNodeTexture2, TNodeTextureCoordinate2,
TNodeKambiTriangulation
); |
VRMLCameraKindToStr: array[TVRMLCameraKind]of string =
('Orthographic', 'Perspective'); |
JUSTIFICATION_LEFT = 0; |
JUSTIFICATION_CENTER = 1; |
JUSTIFICATION_RIGHT = 2; |
BIND_DEFAULT = 0; |
BIND_OVERALL = 1; |
BIND_PER_PART = 2; |
BIND_PER_PART_INDEXED = 3; |
BIND_PER_FACE = 4; |
BIND_PER_FACE_INDEXED = 5; |
BIND_PER_VERTEX = 6; |
BIND_PER_VERTEX_INDEXED = 7; |
VERTORDER_UNKNOWN = 0; |
VERTORDER_CLOCKWISE = 1; |
VERTORDER_COUNTERCLOCKWISE = 2; |
SHTYPE_UNKNOWN = 0; |
SHTYPE_SOLID = 1; |
FACETYPE_UNKNOWN = 0; |
FACETYPE_CONVEX = 1; |
FSFAMILY_SERIF = 0; |
FSFAMILY_SANS = 1; |
FSFAMILY_TYPEWRITER = 2; |
FSSTYLE_BOLD = 0; |
FSSTYLE_ITALIC = 1; |
CONE_PARTS_SIDES = 0; |
CONE_PARTS_BOTTOM = 1; |
CYLINDER_PARTS_SIDES = 0; |
CYLINDER_PARTS_TOP = 1; |
CYLINDER_PARTS_BOTTOM = 2; |
TEXWRAP_REPEAT = 0; |
TEXWRAP_CLAMP = 1; |
DefaultHeightMapScale = 0.01; |
DefaultVRML1CreaseAngle = 0.5; |
DefaultViewpointFieldOfView = Pi / 4; |
MinQuadricSlices: Cardinal = 3; |
MinQuadricStacks: Cardinal = 1; |
MinRectDivisions: Cardinal = 0; |
URNVRML97Nodes = 'urn:web3d:vrml97:node:'; |
URNKambiNodes = 'urn:vrmlengine.sourceforge.net:node:'; |
Variables
Description
Functions and Procedures
function ParseNode(Lexer: TVRMLLexer; const AllowedNodes: boolean; NilIfUnresolvedUSE: boolean = false): TVRMLNode; |
|
Parse VRML node. This parses
[ DEF <nodename> ] <nodetype> { node-content }
or
USE <nodename>
If we will find USE clause but node name will be unknown, the normal behavior (when NilIfUnresolvedUSE = False, default) is to raise EVRMLParserError (just like in case of many other errors). However, this is a particular parsing error, because we can probably pretty safely continue parsing, ignoring this error. So if you pass NilIfUnresolvedUSE = True, this function will do VRMLNonFatalError and simply return Nil.
Exceptions raised
- EVRMLParserError
- On various parsing errors.
- EVRMLUnknownNodeNotAllowed
- On a special parsing error: we got unknown node name, and AllowedNodes was
False.
We have a special error class for this, because in some cases it means that actually the unknown node name could be also unknown field / proto etc. name, so error message for the user should be better.
|
function ParseVRMLFile(Stream: TPeekCharStream; const WWWBasePath: string; ProtoNameBinding: TStringList = nil): TVRMLNode; overload; |
|
Parse whole VRML file, return it's root node.
Note that you must pass here TPeekCharStream class, not just any generic TStream class. But it's not a problem, really, because you can wrap any class inside TPeekCharStream descendant. E.g. do
ParseVRMLFile(TBufferedReadStream.Create(MyStream, false), WWWBasePath)
Note that this function can't handle compressed data (VRML files are sometimes compressed with gzip). You should already pass here a stream with uncompressed text data.
Parameters
- ProtoNameBinding
- If <>
Nil, will be filled with global prototype namespace at the end of parsing the file. Usually not useful.
Exceptions raised
- EVRMLGzipCompressed
- If the Stream starts with gzip file header.
|
function ParseVRMLFileFromString(const VRMLContents: string; const WWWBasePath: string): TVRMLNode; overload; |
|
|
function ParseVRMLFile(const FileName: string; AllowStdIn: boolean; ProtoNameBinding: TStringList = nil): TVRMLNode; overload; |
|
FileName to nazwa istniejacego pliku (wzgledna lub bezwzgledna). Jezeli AllowStdIn to jesli filename = '-' to odczytamy model z StdInStream, w tym przypadku WWWBasePath bedzie ustawione na GetCurrentDir.
This function can handle files compressed with gzip (it just internally filters file contents with TGZFileStream, uncompressing it on the fly).
Parameters
- ProtoNameBinding
- If <>
Nil, will be filled with global prototype namespace at the end of parsing the file. Usually not useful.
|
procedure SaveToVRMLFile(Node: TVRMLNode; Stream: TStream; const PrecedingComment: string; WriteExpandedPrototype: boolean = false); overload; |
|
SaveToVRMLFile writes whole VRML file with given root Node. This includes writing VRML header '#VRML ...'.
Parameters
- PrecedingComment
- If PrecedingComment <> '' then we will write a comment '# '+ PrecedingComment at the beginning. This is for you to optionally put name of the generator program or source filename or time/date of generation etc.
- WriteExpandedPrototype
- See TVRMLSaveToStreamProperties.WriteExpandedPrototype. In pretty much all normal cases (i.e. when you save your VRML node hierarchy into a file for user) you can leave this as
False.
|
procedure SaveToVRMLFile(Node: TVRMLNode; const Filename, PrecedingComment: string; WriteExpandedPrototype: boolean = false); overload; |
|
|
function VRMLNodeDeepCopy(SourceNode: TVRMLNode): TVRMLNode; |
|
Create a new node with exactly the same VRML node hierarchy. Everything in the hierarchy is a new node instance, although the same node classess are present, with the same names, field values etc.
|
procedure VRMLNodesList_FreeWithNonParentedContentsAndNil(var List: TVRMLNodesList); |
|
Free all VRML nodes with no parents on the list, then free and Nil the list itself.
|
Types
TVRMLNodeProc = procedure (node: TVRMLNode) of object; |
|
|
TDynArrayItemIsSmallerFunc_1 = function (const a, b: TDynArrayItem_1): boolean; |
|
|
TDynArrayItemIsSmallerFuncByObject_1 = function (const a, b: TDynArrayItem_1): boolean of object; |
|
|
TEnumerateChildrenFunction = procedure (Node, Child: TVRMLNode) of object; |
|
|
TEnumerateRemoveNodesFunction = procedure (ParentNode, Node: TVRMLNode; var RemoveNode: boolean) of object; |
|
|
TObjectsListIsSmallerFunction_3 = function (const A, B: TObjectsListItem_3): boolean of object; |
|
|
TVRMLFontJustify = (...); |
|
Font justification that can be specified by FontStyle in justify/justification field. First three fields are equal (after casting by Ord) to JUSTIFICATION_* constants.
Values
-
fjBegin:
-
fjMiddle:
-
fjEnd:
|
TVRMLFontFamily = (...); |
|
Font family that can be specified by FontStyle node in family field. First three fields are equal (after casting by Ord) to three values of FSFAMILY_* constants.
Values
-
ffSerif:
-
ffSans:
-
ffTypeWriter:
|
TVRMLCameraKind = (...); |
Values
-
ckOrthographic:
-
ckPerspective:
|
TObjectsListIsSmallerFunction_1 = function (const A, B: TObjectsListItem_1): boolean of object; |
|
|
TObjectsListIsSmallerFunction_2 = function (const A, B: TObjectsListItem_2): boolean of object; |
|
|
TObjectsListIsSmallerFunction_4 = function (const A, B: TObjectsListItem_4): boolean of object; |
|
|
TObjectsListIsSmallerFunction_5 = function (const A, B: TObjectsListItem_5): boolean of object; |
|
|
Constants
CountTraverseStateLastNodes = 10; |
|
|
DefaultMaterial_2AmbientIntensity = 0.2; |
|
|
DefaultMaterialShininess = 0.2; |
|
|
DefaultMaterialTransparency = 0.0; |
|
|
DefaultMaterialMirror = 0.0; |
|
|
DefaultMaterialReflSpecularExp = 1000000; |
|
|
DefaultMaterialTransSpecularExp = 1000000; |
|
|
VRMLCameraKindToStr: array[TVRMLCameraKind]of string =
('Orthographic', 'Perspective'); |
|
|
JUSTIFICATION_LEFT = 0; |
|
consts for TNodeAsciiText.FdJustification.Value
|
JUSTIFICATION_CENTER = 1; |
|
|
BIND_DEFAULT = 0; |
|
consts for TNode(Material|Normal)Binding.FdValue.Value
|
BIND_PER_PART_INDEXED = 3; |
|
|
BIND_PER_FACE_INDEXED = 5; |
|
|
BIND_PER_VERTEX_INDEXED = 7; |
|
|
VERTORDER_UNKNOWN = 0; |
|
consts for TNodeShapeHints.FdVertexOrdering.Value
|
VERTORDER_COUNTERCLOCKWISE = 2; |
|
|
SHTYPE_UNKNOWN = 0; |
|
consts for TNodeShapeHints.FdShapeType.Value
|
FACETYPE_UNKNOWN = 0; |
|
consts for TNodeShapeHints.FdFaceType.Value
|
FSFAMILY_SERIF = 0; |
|
consts for TNodeFontStyle.FdFamily.Value
|
FSSTYLE_BOLD = 0; |
|
consts for TNodeFontStyle.FdStyleFlags[]
|
CONE_PARTS_SIDES = 0; |
|
consts for TNodeCone.FdParts.Flags[]
|
CYLINDER_PARTS_SIDES = 0; |
|
consts for TNodeCylinder.FdParts.Flags[]
|
CYLINDER_PARTS_BOTTOM = 2; |
|
|
DefaultHeightMapScale = 0.01; |
|
|
DefaultVRML1CreaseAngle = 0.5; |
|
|
DefaultViewpointFieldOfView = Pi / 4; |
|
|
MinQuadricSlices: Cardinal = 3; |
|
uzywaj w programie zawsze tych stalych zamiast zakladac ze maja one konkretne wartosci, ale mozesz oczywiscie przyjac zalozenie ze na pewno sa one Cardinalami (sa >=0)
|
MinQuadricStacks: Cardinal = 1; |
|
mimo ze OpenGL akceptuje minimum 2, ale dla 2 wynik jest bez sensu
|
MinRectDivisions: Cardinal = 0; |
|
|
URNVRML97Nodes = 'urn:web3d:vrml97:node:'; |
|
|
URNKambiNodes = 'urn:vrmlengine.sourceforge.net:node:'; |
|
|
Variables
NodesManager: TNodesManager; |
|
tworzony i niszczony w init/fini tego modulu
|
Detail_QuadricSlices: Cardinal = 30; |
|
cylinder, cone, sphere and disk slices/stacks (slices for all objects must be equal to perfectly "match" when objects are connected (e.g. sphere connected with cylinder). Stacks and RectDivisions nie sa do tego zmuszone ale i tak nie ma zadnego sensownego powodu zeby z gory mowic ze dana bryla potrzebuje mniej stacks a inna wiecej).
For the meaning of Detail_Quadric* consts look at definition of glu quadric functions (it is not guaranteed that our code will use this functions but we will always honour this Detail parameters in the same way).
For the meaning of Detail_RectDivisions (used only in Cube for now) look at KambiGLUtils.DrawGLPlane.
For now, you can change these variables only before using anything from this module.
These variables must always honour Min values listed below.
|
Detail_QuadricStacks: Cardinal = 20; |
|
|
Detail_RectDivisions: Cardinal = 2; |
|
|
Generated by PasDoc 0.10.0 on 2008-02-25 00:00:42