Unit VRMLNodes

DescriptionusesClasses, Interfaces, Objects and RecordsFunctions and ProceduresTypesConstantsVariables

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:

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 :

  1. Inline nodes (WWWInline, Inline, InlineLoadControl) ktore w BeforeTraverse laduje swoja scene jako swoje dziecko

  2. 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

  1. 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.

  2. 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

Name Description
record TTraverseStateLastNodes Stala TraverseStateLastNodesClasses okresla jakie node'y beda zapamietywane w TVRMLGraphTraverseState w LastNodes.
record TActiveLight This is used in TVRMLGraphTraverseState to keep track of used light.
Class TDynArray_1  
Class TDynActiveLightArray  
Class TVRMLGraphTraverseState This describes current "state" (current transformation and such) when traversing VRML graph.
record TTraversingInfo  
Class TVRMLNode VRML node.
Class TObjectsList_3  
Class TVRMLNodesList  
Class TVRMLNodeClassesList  
Class TSFNode SFNode VRML field.
Class TMFNode MFNode VRML field.
Class TNodeGeneralShape Shape is the only node that produces some visible results during rendering.
Class TNodeGeneralTexture Common texture node for all VRML versions.
Interface INodeGeneralInline Basic interface that should be implemented by all Inline VRML nodes.
Class TNodeGeneralShape_1 This is descendant of TNodeGeneralShape that is allowed only in VRML <= 1.0.
Class TNodeAsciiText_1  
Class TNodeCone_1  
Class TNodeCube_1  
Class TNodeCylinder_1  
Class TNodeGeneralIndexed_1 wspolny rodzic dla IndexedFaceSet, IndexedTriangleMesh, IndexedLineSet
Class TNodeIndexed_Faces_Or_Triangles_1 wspolny rodzic dla IndexedFaceSet i IndexedTriangleMesh
Class TNodeIndexedFaceSet_1  
Class TNodeIndexedLineSet_1  
Class TNodePointSet_1  
Class TNodeSphere_1  
Class TNodeCoordinate3  
Class TNodeFontStyle_1  
Class TNodeInfo  
Class TNodeLOD_1  
Class TNodeMaterial_1  
Class TNodeMaterialBinding  
Class TNodeNormalBinding  
Class TNodeTexture2  
Class TNodeTexture2Transform  
Class TNodeTextureCoordinate2  
Class TNodeShapeHints  
Class TNodeGeneralTransformation TNodeGeneralTransformation - wspolna klasa dla wszystkich node'ow ktorych jedynym celem jest zmodyfikowac aktualna macierz modelview.
Class TNodeMatrixTransform  
Class TNodeRotation  
Class TNodeScale  
Class TNodeTransform_1  
Class TNodeTranslation  
Class TNodeGeneralViewpoint A common class for both VRML 1.0 camera nodes and VRML 2.0 Viewpoint node.
Class TNodeGeneralVRML1Camera GeneralCamera - wspolna klasa dla wszystkich kamer VRML'a.
Class TNodeOrthographicCamera  
Class TNodePerspectiveCamera  
Class TNodeGeneralLight  
Class TObjectsList_1  
Class TNodeGeneralLightsList  
Class TNodeGeneralDirectionalLight  
Class TNodeDirectionalLight_1  
Class TNodeGeneralPositionalLight  
Class TNodeGeneralPointLight  
Class TNodePointLight_1  
Class TNodeSpotLight_1  
Class TNodeGroup_1  
Class TNodeGroupHidden_1 A Group node that is added when VRML 1.0 file contains more than one root node.
Class TNodeGeneralSeparator A general class that can ce used as a separator, something that pushes and pops all attribs and matrices.
Class TNodeSeparator  
Class TNodeSwitch_1  
Class TNodeTransformSeparator  
Class TNodeWWWAnchor TODO: node anchor dziala jak Separator, wartosci jego pol nie maja nigdzie zadnego znaczenia.
Class TNodeWWWInline gdy chcemy operowac na scenie juz po jej zaladowaniu, bezposrednio lub poprzez metode w rodzaju TVRMLNode.EnumerateNodes, jest istotne gdzie w hierarchii sceny znajduja sie Inlined nodes.
Class TNodeIndexedTriangleMesh_1 IndexedTriangleMesh — from Inventor 1.0.
Class TNodeRotationXYZ RotationXYZ node from Inventor.
Class TNodeGeneralGrouping This is a VRML 2.0 grouping node.
Class TNodeX3DGroupingNode  
Class TNodeAnchor  
Class TNodeAppearance  
Class TNodeAudioClip  
Class TNodeBackground  
Class TNodeBillboard  
Class TNodeBox  
Class TNodeCollision  
Class TNodeColor  
Class TNodeColorInterpolator  
Class TNodeCone_2  
Class TNodeContour2D  
Class TNodeCoordinate  
Class TNodeCoordinateDeformer  
Class TNodeCoordinateInterpolator  
Class TNodeCylinder_2  
Class TNodeCylinderSensor  
Class TNodeDirectionalLight_2  
Class TNodeElevationGrid  
Class TNodeExtrusion  
Class TNodeFog  
Class TNodeFontStyle_2  
Class TNodeGeoCoordinate  
Class TNodeGeoElevationGrid  
Class TNodeGeoLocation  
Class TNodeGeoLOD  
Class TNodeGeoMetadata  
Class TNodeGeoOrigin  
Class TNodeGeoPositionInterpolator  
Class TNodeGeoTouchSensor  
Class TNodeGeoViewpoint  
Class TNodeGroup_2  
Class TNodeGroupHidden_2  
Class TNodeImageTexture  
Class TNodeIndexedFaceSet_2  
Class TNodeIndexedLineSet_2  
Class TNodeInline  
Class TNodeInlineLoadControl  
Class TNodeLOD_2  
Class TNodeMaterial_2  
Class TNodeMovieTexture  
Class TNodeNavigationInfo  
Class TNodeNormal  
Class TNodeNormalInterpolator  
Class TNodeNurbsCurve  
Class TNodeNurbsCurve2D  
Class TNodeNurbsGroup  
Class TNodeNurbsPositionInterpolator  
Class TNodeNurbsSurface  
Class TNodeNurbsTextureSurface  
Class TNodeOrientationInterpolator  
Class TNodePixelTexture  
Class TNodePlaneSensor  
Class TNodePointLight_2  
Class TNodePointSet_2  
Class TNodePolyline2D  
Class TNodePositionInterpolator  
Class TNodeProximitySensor  
Class TNodeScalarInterpolator  
Class TNodeScript  
Class TNodeShape  
Class TNodeSound  
Class TNodeSphere_2  
Class TNodeSphereSensor  
Class TNodeSpotLight_2  
Class TNodeSwitch_2  
Class TNodeText  
Class TNodeTextureCoordinate  
Class TNodeTextureTransform  
Class TNodeTimeSensor  
Class TNodeTouchSensor  
Class TNodeTransform_2  
Class TNodeTrimmedSurface  
Class TNodeViewpoint  
Class TNodeVisibilitySensor  
Class TNodeWorldInfo  
Class TNodeKambiTriangulation  
Class TNodeKambiHeadLight  
Class TNodeText3D  
Class TNodeKambiAppearance  
Class TNodeX3DAppearanceChildNode Copyright 2007 Michalis Kamburelis.
Class TNodeX3DMetadataObject  
Interface INodeX3DUrlObject  
Class TNodeX3DShaderNode  
Interface INodeX3DProgrammableShaderObject  
Class TNodeComposedShader  
Class TNodePackagedShader  
Class TNodeProgramShader TODO: # And any number of: fieldType [in] fieldName fieldType [in,out] fieldName initialValue fieldType [out] fieldName fieldType [] fieldName initialValue
Class TNodeShaderPart  
Class TNodeShaderProgram  
Class TNodeUnknown TNodeUnknown represents a node with an unrecognized type.
Class TVRMLInterfaceDeclaration Interface declaration, used in VRML (exposed) prototypes and scripts.
Class TObjectsList_2  
Class TVRMLInterfaceDeclarationsList  
Class EVRMLPrototypeInstantiateError  
Class TVRMLPrototypeNode VRML node related to a given prototype.
Class TVRMLPrototypeBase  
Class TObjectsList_4  
Class TVRMLPrototypeBasesList  
Class TVRMLPrototype  
Class TVRMLExternalPrototype  
Class TVRMLRoute TVRMLRoute —————————————————————–
Class TObjectsList_5  
Class TVRMLRoutesList  
Class ENodesManagerError TNodesManager ————————————————————
Class ENodeClassRegisterError  
Class TNodesManager  
Class EVRMLUnknownNodeNotAllowed global procedures ———————————————————-

Functions and Procedures

function ParseNode(Lexer: TVRMLLexer; const AllowedNodes: boolean; NilIfUnresolvedUSE: boolean = false): TVRMLNode;
function ParseVRMLFile(Stream: TPeekCharStream; const WWWBasePath: string; ProtoNameBinding: TStringList = nil): TVRMLNode; overload;
function ParseVRMLFileFromString(const VRMLContents: string; const WWWBasePath: string): TVRMLNode; overload;
function ParseVRMLFile(const FileName: string; AllowStdIn: boolean; ProtoNameBinding: TStringList = nil): TVRMLNode; overload;
procedure SaveToVRMLFile(Node: TVRMLNode; Stream: TStream; const PrecedingComment: string; WriteExpandedPrototype: boolean = false); overload;
procedure SaveToVRMLFile(Node: TVRMLNode; const Filename, PrecedingComment: string; WriteExpandedPrototype: boolean = false); overload;
procedure TraverseState_CreateNodes(var StateNodes: TTraverseStateLastNodes);
procedure TraverseState_FreeAndNilNodes(var StateNodes: TTraverseStateLastNodes);
function VRMLNodeDeepCopy(SourceNode: TVRMLNode): TVRMLNode;
procedure VRMLNodesList_FreeWithNonParentedContentsAndNil(var List: TVRMLNodesList);

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

NodesManager: TNodesManager;
Detail_QuadricSlices: Cardinal = 30;
Detail_QuadricStacks: Cardinal = 20;
Detail_RectDivisions: Cardinal = 2;
AllowedChildrenNodes: TVRMLNodeClassesList;
AllowedGeometryNodes: TVRMLNodeClassesList;

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;
 
procedure TraverseState_CreateNodes(var StateNodes: TTraverseStateLastNodes);

Create and assign all State.Nodes.

procedure TraverseState_FreeAndNilNodes(var StateNodes: TTraverseStateLastNodes);

Free and nil all State.Nodes.

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

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;

Used as a callback by TVRMLNode.Traverse.

TBlenderTraversingFunc = procedure ( BlenderObjectNode: TVRMLNode; const BlenderObjectName: string; BlenderMeshNode: TVRMLNode; const BlenderMeshName: string; ShapeNode: TNodeGeneralShape; State: TVRMLGraphTraverseState) of object;

Used as a callback by TVRMLNode.TraverseBlenderObjects.

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 = (...);

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:
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 );

opis patrz TTraverseStateLastNodes

VRMLCameraKindToStr: array[TVRMLCameraKind]of string = ('Orthographic', 'Perspective');
 
JUSTIFICATION_LEFT = 0;

consts for TNodeAsciiText.FdJustification.Value

JUSTIFICATION_CENTER = 1;
 
JUSTIFICATION_RIGHT = 2;
 
BIND_DEFAULT = 0;

consts for TNode(Material|Normal)Binding.FdValue.Value

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;

consts for TNodeShapeHints.FdVertexOrdering.Value

VERTORDER_CLOCKWISE = 1;
 
VERTORDER_COUNTERCLOCKWISE = 2;
 
SHTYPE_UNKNOWN = 0;

consts for TNodeShapeHints.FdShapeType.Value

SHTYPE_SOLID = 1;
 
FACETYPE_UNKNOWN = 0;

consts for TNodeShapeHints.FdFaceType.Value

FACETYPE_CONVEX = 1;
 
FSFAMILY_SERIF = 0;

consts for TNodeFontStyle.FdFamily.Value

FSFAMILY_SANS = 1;
 
FSFAMILY_TYPEWRITER = 2;
 
FSSTYLE_BOLD = 0;

consts for TNodeFontStyle.FdStyleFlags[]

FSSTYLE_ITALIC = 1;
 
CONE_PARTS_SIDES = 0;

consts for TNodeCone.FdParts.Flags[]

CONE_PARTS_BOTTOM = 1;
 
CYLINDER_PARTS_SIDES = 0;

consts for TNodeCylinder.FdParts.Flags[]

CYLINDER_PARTS_TOP = 1;
 
CYLINDER_PARTS_BOTTOM = 2;
 
TEXWRAP_REPEAT = 0;

consts for TNodeTexture2.FdWrapS/WrapT.Value

TEXWRAP_CLAMP = 1;
 
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;
 
AllowedChildrenNodes: TVRMLNodeClassesList;
 
AllowedGeometryNodes: TVRMLNodeClassesList;
 

Generated by PasDoc 0.10.0 on 2008-02-25 00:00:42