Castle Game EngineIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers |
Unit X3DNodes
Description
Nodes and other important bulding blocks of VRML/X3D (prototypes, routes and so on).
This is the central unit for VRML/X3D processing, as VRML/X3D file is basically just a graph of nodes. We represent whole VRML/X3D file by it's root node. This is what we load, save and process in this unit.
The chapter "Reading, writing, processing VRML scene graph" in the documentation on [http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/chapter.scene_graph.html] is almost completely devoted to documenting the design of this single unit.
Various uses of this unit:
Nodes can be loaded or saved from the stream in a classic or XML encoding. For classic encoding we use a lexer in X3DLexer unit. For XML encoding, we use standard FPC DOM unit. Loading and saving of fields (in both encodings) is inside X3DFields unit.
When reading VRML/X3D files, we generally do not change the VRML/X3D graph. So we're able to save exactly the same VRML/X3D graph back to another file. See also [http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/section.writing_vrml.html#section.vrml_preserving]. This allows writing various VRML/X3D processing tools, that can simply read the file, change whatever they want, and write the file back — knowing that the "untouched" parts of graph are preserved perfectly.
TX3DNode class offers a lot of methods to process VRML/X3D graph. See TX3DNode.Traverse, TX3DNode.EnumerateNodes and TX3DNode.FindNode. TX3DNode.Traverse is especially important, as it walks through VRML/X3D graph just as the specification says (accumulating transformation, visiting only active children of nodes like Switch or LOD), gathering some state (useful especially for VRML 1.0, but also used for various things in later VRML/X3D versions).
When you want to render VRML/X3D graph, you can just traverse the graph and render each geometry node (TAbstractGeometryNode instance) knowing it's state (that will contain transformation and such). Alternatively, simple renderer can also use TAbstractGeometryNode.Triangulate.
TAbstractGeometryNode is an important descendant of TX3DNode, as it defines stuff actually visible in the 3D world. It has useful routines for calculating bounding volumes, triangulating and such.
But note that usually it's more comfortable to load your scene to TCastleScene or TCastleSceneCore and then query the shapes list in TCastleSceneCore.Shapes — this is usually more comfortable, also TCastleSceneCore and TShape cache some results for speed.
This unit doesn't depend on OpenGL, or any other particular rendering method. So it's suitable also for CastleRayTracer, and every other possible renderer that will ever get implemented.
Your own units can define new VRML/X3D nodes, by declaring new classes descending from TX3DNode (or other, more specialized, descendant). You should register your new classes by calling NodesManager.RegisterNodeClasses.
Examples of defining your own VRML/X3D node types (without modifying sources of this unit, or any other unit) are for example in the X3DBezierCurve unit in bezier_curves demo, and LevelUnit in malfunction.
Node class names, and inheritance:
Normal VRML/X3D nodes are defined by classses named like TXxxNode . These nodes can be specified inside the VRML/X3D files. See VRML/X3D specifications, and also our extensions specification, on [http://castle-engine.sourceforge.net/vrml_x3d.php].
There are also abstract node classes. Their definitions are helpful for handling some functionality common to many descendants, and to declare allowed children in SFNode/MFNode fields. Abstract node classes are named like TAbstractXxxNode . Some of the abstract nodes are also defined by X3D specification, and some of them are just our own inventions.
Finally, there are some special-purpose node classes that play important role in our VRML/X3D organization. They are not abstract, but also their exact instances are not created under normal circumstances. These are named like TX3DXxxNode , currently these are only: TX3DNode, TX3DRootNode, TX3DUnknownNode, TX3DPrototypeNode.
All node classes descend from the base TX3DNode class.
Some abstract nodes have also Pascal interfaces, like IAbstractXxxNode. Some ideas of X3D specification (although not many) need multiple inheritance, so interfaces have to be used. They all descend from IX3DNode.
Optional suffix _1 or _2 at the node class name indicates that this is only for a specific VRML/X3D standard version. Suffix _1 indicates nodes specific to VRML 1.0. Suffix _2 indicates nodes specific to VRML 2.0 (aka 97), that are not available in X3D. Latest X3D nodes do not have any suffix (to not clutter the source code that simply wants to use the latest and best version of the standard).
For example, we have TIndexedFaceSetNode_1 for VRML 1.0 and TIndexedFaceSetNode for VRML 2.0 and X3D.
VRML/X3D versions handling:
We handle VRML 1.0, VRML 2.0 (aka VRML 97) and X3D (aka VRML 3.x).
Every correct VRML / X3D file in classic and XML encoding should be parsed by this unit. See [http://castle-engine.sourceforge.net/x3d_implementation_status.php] for much more detailed information about supported features.
Also many Inventor 1.0 files are 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://castle-engine.sourceforge.net/x3d_extensions.php#ext_iv_in_vrml].
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 all VRML and X3D. When reading VRML 1.0, many VRML 2.0 constructs (that do 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/X3D constructs (or the other way around). See [http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/section.vrml_1_2_sum.html] for more in-depth explanation of how, and why, we handle both old-style (Inventor, VRML 1.0) and new-style (VRML 2.0, X3D) syntax.
Files organization: X3D nodes are inside x3d_COMPONET_NAME.inc files. This way X3D specification components provide a natural way to group the vast number of nodes into files. Some remaining nodes that are not part of X3D are in other x3dnodes_xxx.inc files, for example x3dnodes_1.inc contains only VRML 1.0-specific nodes.
Uses
Overview
Classes, Interfaces, Objects and Records
Functions and Procedures
Types
Constants
DefaultMaterial_1AmbientColor: TVector3Single = (0.2, 0.2, 0.2); |
DefaultMaterialAmbientIntensity = 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 [TVRML1StateNode] of TX3DNodeClass =
( TCoordinate3Node_1, TShapeHintsNode_1, TFontStyleNode_1,
TMaterialNode_1, TMaterialBindingNode_1, TNormalNode, TNormalBindingNode_1,
TTexture2Node_1, TTextureCoordinate2Node_1,
TKambiTriangulationNode
); |
LoadX3DClassic_FileFilters =
'All files|*|' +
'*VRML (*.wrl, *.wrl.gz, *.wrz)|*.wrl;*.wrl.gz;*.wrz'; |
LoadX3DXml_FileFilters =
'All files|*|' +
'*X3D XML (*.x3d, *.x3dz, *.x3d.gz)|*.x3d;*.x3dz;*.x3d.gz'; |
ProjectionTypeToStr: array [TProjectionType] 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; |
DefaultNavigationInfoHeadlight = true; |
DefaultRenderedTextureWidth = 128; |
DefaultRenderedTextureHeight = 128; |
DefaultShadowMapScale = 1.1; |
DefaultShadowMapBias = 4.0; |
VRML1Version: TX3DVersion = (Major: 1; Minor: 0); |
VRML2Version: TX3DVersion = (Major: 2; Minor: 0); |
X3DVersion: TX3DVersion = (Major: 3; Minor: 2); |
xeClassic = X3DLexer.xeClassic; |
xeXML = X3DLexer.xeXML; |
MinQuadricSlices: Cardinal = 3; |
MinQuadricStacks: Cardinal = 1; |
MinRectDivisions: Cardinal = 0; |
URNVRML97Nodes = 'urn:web3d:vrml97:node:'; |
URNX3DNodes = 'urn:web3d:x3d:node:'; |
URNKambiNodes = 'urn:castle-engine.sourceforge.net:node:'; |
URNKambiNodes2 = 'urn:vrmlengine.sourceforge.net:node:'; |
URNBitManagementNodes = 'urn:inet:bitmanagement.de:node:'; |
AllAccessTypes = [atInputOnly, atOutputOnly, atInitializeOnly, atInputOutput]; |
RestrictedAccessTypes = [atInputOnly, atOutputOnly, atInitializeOnly]; |
Variables
Description
Functions and Procedures
function LoadX3DClassic(Stream: TPeekCharStream; const BaseUrl: string): TX3DRootNode; overload; |
Load VRML/X3D file in classic encoding from stream. 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
LoadX3DClassic(TBufferedReadStream.Create(MyStream, false), BaseUrl)
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.
Exceptions raised
- EX3DGzipCompressed
- If the Stream starts with gzip file header.
|
function LoadX3DClassicFromString(const VRMLContents: string; const BaseUrl: string): TX3DRootNode; overload; |
|
function LoadX3DClassic(const URL: string; const AllowStdIn: boolean; const Gzipped: boolean = false): TX3DRootNode; overload; |
Load VRML/X3D file in classic encoding, return it's root node.
Automatically handles VRML/X3D files compressed with gzip, uncompressing them on the fly.
URL without any protocol is treated as a filename (absolute or relative to current dir). We can also load network URLs using CastleDownload.
If AllowStdIn then URL = '-' is understood as "standard input" (StdInStream). Base for resolving relative URLs in this case is the current working directory.
If Gzipped then we can be relatively sure that stream is gzipped. Otherwise, it can still be gzipped (.wrl files are sometimes gzipped without extension indicating it).
|
function LoadX3DXml(const URL: string; Gzipped: boolean): TX3DRootNode; |
Read X3D encoded in XML, and convert it to VRML/X3D nodes graph.
Overloaded version that takes Stream as a parameter expects that reading the stream returns the uncompressed content (no longer gzip compressed). This version also takes URL as a parameter, but it is not used to load contents (these are inside Stream), it it only used to resolve relative URLs inside content and for error messages.
|
function LoadX3DXml(Stream: TStream; const URL: string): TX3DRootNode; |
|
function Save3DVersion(Node: TX3DNode): TX3DVersion; |
Which VRML/X3D version should be used to save this 3D model.
|
procedure Save3D(Node: TX3DNode; const Stream: TStream; const Generator, Source: string; Version: TX3DVersion; const Encoding: TX3DEncoding; const ForceConvertingToX3D: boolean = false); overload; |
Write VRML/X3D model to a file. Generates a complete file, with header lines (XML headers, or #VRML / #X3D in classic encoding) and everything.
Overloaded version that takes an URL will automatically compress the file with gzip if an extension indicating gzip compression is present (like .x3dv.gz, or .x3d.gz).
Generator and Source, if not empty, will be used to set appropriate META values of X3D root file node. This way you can indicate inside X3D file the generator (your program) name and source (original 3D model file name). If this is not an X3D root file node, we will record it inside a comment.
When ForceConvertingToX3D or when Encoding <> xeClassic, the node graph will be converted to X3D (if it isn't X3D already). This can be used to convert VRML 2.0 to X3D. For VRML 1.0 or Inventor, this will just save them in X3D (XML or classic) encoding, which is not really usable. We simply don't implement VRML 1.0/Inventor convertion (it's difficult, and not worth the trouble, VRML 1.0/Inventor are really old).
Note that converting to X3D will change the nodes graph, possibly removing some nodes. If you use TCastleSceneCore, you should call TCastleSceneCore.BeforeNodesFree before and TCastleSceneCore.ChangedAll when such convertion occcurs (you can easily test whether it may happen by Save3DWillConvertToX3D). If you use Encoding=xeClassic and ForceConvertingToX3D=false, you're safe: convertion will not happen.
Parameters
- Version
- Which VRML/X3D specification version should be used to encode. It should be calculated by Save3DVersion(Node). You often want to calculate it yourself, before calling Save3D, this way you can propose a sensible saved model extension for user (.wrl for VRML <= 2.0 in classic encoding, .x3dv for X3D in classic encoding).
Note that this parameter is not a mechanism to convert between various VRML/X3D versions. This procedure does not convert VRML/X3D nodes/fields inside. For example, you can't just change Version.Major value from 1 to 3 to convert VRML 1.0 to X3D. It would cause some information to be encoded in X3D style (e.g. generated file will have X3D header and PROFILE information), but the nodes would stil have VRML 1.0 names and fields. Which means that you would not generate correct X3D file.
So this should really be calculated based on model contents, usually by Save3DVersion(Node).
A limited VRML 2.0 convertion is possible by ForceConvertingToX3D = true. In this case, Version will be automatically changed to X3D anyway.
|
procedure Save3D(Node: TX3DNode; const URL, Generator, Source: string; const Version: TX3DVersion; const Encoding: TX3DEncoding; const ForceConvertingToX3D: boolean = false); overload; |
|
procedure Save3D(Node: TX3DNode; const Stream: TStream; const Generator, Source: string; const Encoding: TX3DEncoding; const ForceConvertingToX3D: boolean = false); overload; |
|
procedure Save3D(Node: TX3DNode; const URL, Generator, Source: string; const Encoding: TX3DEncoding; const ForceConvertingToX3D: boolean = false); overload; |
|
function Save3DWillConvertToX3D(Version: TX3DVersion; const Encoding: TX3DEncoding; const ForceConvertingToX3D: boolean): boolean; |
|
procedure X3DNodeList_FreeUnusedAndNil(var List: TX3DNodeList); |
Free all unused VRML/X3D nodes on the list, then free and Nil the list itself.
|
function KeyRange(Key: TSingleList; const Fraction: Single; out T: Single): Integer; |
Find a range within "key" field corresponding to given Fraction. Returns the index of right range delimiter. So for normal ranges (between two values of "key" field) it's always between 1 and FdKey.Count - 1. Result 0 indicates we're before the left limit, and result equal FdKey.Count indicates we're after right limit.
Result is always between 0 and FdKey.Count.
Output T is the value between 0..1 indicating where within the range we are. It's undefined when Result is 0 or Key.Count (indicating we're outside limits).
Call this only when FdKey.Count > 0.
This is useful to interpreting TAbstractInterpolatorNode.KeyRange and such fields.
|
procedure FreeIfUnusedAndNil(var Obj); |
Free TX3DNode if it is unused (see TX3DNode.FreeIfUnused), setting reference to Nil . Analogous to standard FreeAndNil, but checks if node is used first.
|
Types
TX3DNodeProc = procedure (node: TX3DNode) of object; |
|
TVRML1StateNode = (...); |
Values
-
vsCoordinate3:
-
vsShapeHints:
-
vsFontStyle:
-
vsMaterial:
-
vsMaterialBinding:
-
vsNormal:
-
vsNormalBinding:
-
vsTexture2:
-
vsTextureCoordinate2:
-
vsKambiTriangulation:
|
TEnumerateChildrenFunction = procedure (Node, Child: TX3DNode) of object; |
|
TEnumerateReplaceNodesFunction = procedure (ParentNode: TX3DNode; var Node: TX3DNode) of object; |
|
TX3DAccessType = (...); |
Values
-
atInputOnly:
-
atOutputOnly:
-
atInitializeOnly:
-
atInputOutput:
|
TNodeDestructionNotification = procedure (Node: TX3DNode) of object; |
|
TNodeTransformationChange = (...); |
Values
|
TCachedNodeList = specialize TFPGObjectList<TCachedNode>; |
|
TTextureUpdate = (...); |
Possible update modes for generated textures (like TGeneratedCubeMapTextureNode).
Values
-
upNone:
-
upNextFrameOnly:
-
upAlways:
|
TAllowedChildren = (...); |
Values
-
acAll:
-
acClasses:
-
acInterface:
|
TStringLongIntMap = specialize TFPGMap<string, LongInt>; |
|
TCoordRangeHandler = procedure (const RangeNumber: Cardinal; BeginIndex, EndIndex: Integer) of object; |
|
TIndexedPolygonHandler = procedure (const Indexes: array of Cardinal) of object; |
|
TX3DFontFamily = (...); |
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:
|
TX3DFontJustify = (...); |
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:
|
TLightScope = (...); |
Values
-
lsGlobal: Light shines everywhere. VRML/X3D >= 2 calls these lights global.
-
lsLocal: Light shines only within it's VRML/X3D grouping node. VRML/X3D >= 2 calls these lights not global.
-
lsLocalVRML1: Light shines only on the following shapes within it's VRML/X3D grouping node. This is used by VRML 1.0 (and Inventor) light sources.
|
TProjectionType = (...); |
Values
-
ptOrthographic:
-
ptPerspective:
|
TBackgroundSide = (...); |
Values
-
bsBack:
-
bsBottom:
-
bsFront:
-
bsLeft:
-
bsRight:
-
bsTop:
|
TFogTypeOrNone = (...); |
Values
|
TFogType = ftLinear..ftExp; |
|
TScriptType = (...); |
Values
-
stCompiled:
-
stCastleScript:
|
TSceneOctreeProperties = (...); |
Values
-
opRendering:
-
opDynamicCollisions:
-
opVisibleTriangles:
-
opCollidableTriangles:
|
Constants
DefaultMaterialAmbientIntensity = 0.2; |
|
DefaultMaterialShininess = 0.2; |
|
DefaultMaterialTransparency = 0.0; |
|
DefaultMaterialMirror = 0.0; |
|
DefaultMaterialReflSpecularExp = 1000000; |
|
DefaultMaterialTransSpecularExp = 1000000; |
|
LoadX3DClassic_FileFilters =
'All files|*|' +
'*VRML (*.wrl, *.wrl.gz, *.wrz)|*.wrl;*.wrl.gz;*.wrz'; |
File filters if you want to open a file and then pass it to LoadX3DClassic. Suitable for TCastleWindowCustom.FileDialog and such.
|
LoadX3DXml_FileFilters =
'All files|*|' +
'*X3D XML (*.x3d, *.x3dz, *.x3d.gz)|*.x3d;*.x3dz;*.x3d.gz'; |
Global routines for parsing XML X3D encoding.
|
ProjectionTypeToStr: array [TProjectionType] of string =
('Orthographic', 'Perspective'); |
|
JUSTIFICATION_LEFT = 0; |
Constants for TAsciiTextNode.FdJustification.Value.
|
JUSTIFICATION_CENTER = 1; |
|
BIND_DEFAULT = 0; |
Constants for TMaterialBindingNode_1.FdValue.Value and TNormalBindingNode_1.FdValue.Value.
|
BIND_PER_PART_INDEXED = 3; |
|
BIND_PER_FACE_INDEXED = 5; |
|
BIND_PER_VERTEX_INDEXED = 7; |
|
VERTORDER_UNKNOWN = 0; |
Constants for TShapeHintsNode_1.FdVertexOrdering.Value.
|
VERTORDER_COUNTERCLOCKWISE = 2; |
|
SHTYPE_UNKNOWN = 0; |
Constants for TShapeHintsNode_1.FdShapeType.Value.
|
FACETYPE_UNKNOWN = 0; |
Constants for TShapeHintsNode_1.FdFaceType.Value.
|
FSFAMILY_SERIF = 0; |
Constants for TFontStyleNode.FdFamily.Value.
|
FSSTYLE_BOLD = 0; |
Constants for TFontStyleNode.FdStyleFlags.
|
CONE_PARTS_SIDES = 0; |
Constants for TConeNode.FdParts.Flags.
|
CYLINDER_PARTS_SIDES = 0; |
Constants for TCylinderNode.FdParts.Flags.
|
CYLINDER_PARTS_BOTTOM = 2; |
|
TEXWRAP_REPEAT = 0; |
Constants for TTexture2Node_1.FdWrapS.Value and TTexture2Node_1.FdWrapT.Value.
|
DefaultHeightMapScale = 0.01; |
|
DefaultVRML1CreaseAngle = 0.5; |
|
DefaultViewpointFieldOfView = Pi / 4; |
|
DefaultNavigationInfoHeadlight = true; |
|
DefaultRenderedTextureWidth = 128; |
|
DefaultRenderedTextureHeight = 128; |
|
DefaultShadowMapScale = 1.1; |
|
DefaultShadowMapBias = 4.0; |
|
X3DVersion: TX3DVersion = (Major: 3; Minor: 2); |
Latest X3D version supported.
|
xeClassic = X3DLexer.xeClassic; |
|
MinQuadricStacks: Cardinal = 1; |
|
MinRectDivisions: Cardinal = 0; |
|
URNVRML97Nodes = 'urn:web3d:vrml97:node:'; |
URNs used to indicate standard VRML / X3D nodes.
Funny thing, I actually didn't found anywhere a definite official statement that they are using such-and-such URNs.
X3D specification refers to RFC [http://www.ietf.org/rfc/rfc3541.txt?number=3541] which, basically, just says "we like URNs and we'll use them" and nothing more. Same thing for VRML 97 spec [http://www.web3d.org/x3d/specifications/vrml/ISO-IEC-14772-VRML97/part1/extensions.html]. There is no precise answer e.g. what URN should be used to Indicate some standard VRML 97 / X3D node.
I constructed URNs below looking at examples in the RFC, annotated by a funny line "The following examples are not guaranteed to be real. They are presented for pedagogical reasons only."
|
URNX3DNodes = 'urn:web3d:x3d:node:'; |
|
URNKambiNodes = 'urn:castle-engine.sourceforge.net:node:'; |
URN used to indicate VRML / X3D nodes that are Castle Game Engine extensions.
|
URNKambiNodes2 = 'urn:vrmlengine.sourceforge.net:node:'; |
|
AllAccessTypes = [atInputOnly, atOutputOnly, atInitializeOnly, atInputOutput]; |
|
RestrictedAccessTypes = [atInputOnly, atOutputOnly, atInitializeOnly]; |
|
Variables
NodesManager: TNodesManager; |
Nodes manager instance. In normal circumstances, this is the only instance of TNodesManager class ever created. It is created / destroyed in this unit's initialization / finalization.
|
WarnAboutAbsoluteFilenames: boolean = true; |
Should be make a warning (using OnWarning) when loading data from an URI with absolute path. This is quite useful if you want to be able to move/copy the files to some other system/location, as absolute paths prevent it.
|
Detail_QuadricSlices: Cardinal = 30; |
Quadric triangulation settings.
Slices divide the circumference of the circle, like a slices of pizza. Stacks divide the height of the object, like stacks of a cake or tower. The precise meaning of slices and stacks parameters follows exactly the OpenGL Utility (GLU) functions (although our implementation doesn't use GLU).
Note that the cylinder, cone, sphere and disk slices must match, otherwise artifacts will appear when you try to connect a sphere with a cylinder cap. Stacks and RectDivisions do not really have to match, but still it's sensible.
Rectangles (used for Cube sides) are also subdivided, for better Gouraud shading. We use Detail_RectDivisions + 1 columns and rows, so we render (Detail_RectDivisions + 1)ˆ2 quads for each cube side.
For now, you can change these variables only before using anything from this module. If you want to change them inside VRML/X3D file (for example, to affect only part of the scene), use the KambiTriangulation node, see [http://castle-engine.sourceforge.net/x3d_extensions.php#section_ext_kambi_triangulation].
These variables must always honour MinQuadricSlices, MinQuadricStacks, MinRectDivisions limit.
|
Detail_QuadricStacks: Cardinal = 20; |
|
Detail_RectDivisions: Cardinal = 2; |
|
X3DCache: TX3DNodesCache; |
Cache, for all the resources not tied with renderer context.
|
Generated by PasDoc 0.13.0 on 2014-08-30 12:10:46
|