| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448 |
- THE PHILOSOPHY OF EGG FILES (vs. bam files)
- Egg files are used by Panda3D to describe many properties of a scene:
- simple geometry, including special effects and collision surfaces,
- characters including skeletons, morphs, and multiple-joint
- assignments, and character animation tables.
- Egg files are designed to be the lingua franca of model manipulation
- for Panda tools. A number of utilities are provided that read and
- write egg files, for instance to convert to or from some other
- modeling format, or to apply a transform or optimize vertices. The
- egg file philosophy is to describe objects in an abstract way that
- facilitates easy manipulation; thus, the format doesn't include
- information such as polygon connectivity or triangle meshes. Egg
- files are furthermore designed to be human-readable to help a
- developer diagnose (and sometimes repair) problems. Also, the egg
- syntax is always intended to be backward compatible with previous
- versions, so that as the egg syntax is extended, old egg files will
- continue to remain valid.
- This is a different philosophy than Panda's bam file format, which is
- a binary representation of a model and/or animation that is designed
- to be loaded quickly and efficiently, and is strictly tied to a
- particular version of Panda. The data in a bam file closely mirrors
- the actual Panda structures that are used for rendering. Although an
- effort is made to keep bam files backward compatible, occasionally
- this is not possible and we must introduce a new bam file major
- version.
- Where egg files are used for model conversion and manipulation of
- models, bam files are strictly used for loading models into Panda.
- Although you can load an egg file directly, a bam file will be loaded
- much more quickly.
- Egg files might be generated by outside sources, and thus it makes
- sense to document its syntax here. Bam files, on the other hand,
- should only be generated by Panda3D, usually by the program egg2bam.
- The exact specification of the bam file format, if you should need it,
- is documented within the Panda3D code itself.
- GENERAL EGG SYNTAX
- Egg files consist of a series of sequential and hierarchically-nested
- entries. In general, the syntax of each entry is:
- <Entry-type> name { contents }
- Where the name is optional (and in many cases, ignored anyway) and the
- syntax of the contents is determined by the entry-type. The name (and
- strings in general) may be either quoted with double quotes or
- unquoted. Newlines are treated like any other whitespace, and case is
- not significant. The angle brackets are literally a part of the entry
- keyword. (Square brackets and ellipses in this document are used to
- indicate optional pieces, and are not literally part of the syntax.)
- The name field is always syntactically allowed between an entry
- keyword and its opening brace, even if it will be ignored. In the
- syntax lines given below, the name is not shown if it will be ignored.
- Comments may be delimited using either the C++-style // ... or the
- C-style /* ... */. C comments do not nest. There is also a <Comment>
- entry type, of the form:
- <Comment> { text }
- <Comment> entries are slightly different, in that tools which read and
- write egg files will preserve the text within <Comment> entries, but
- they may not preserve comments delimited by // or /* */. Special
- characters and keywords within a <Comment> entry should be quoted;
- it's safest to quote the entire comment.
- LOCAL INFORMATION ENTRIES
- These nodes contain information relevant to the current level of
- nesting only.
- <Scalar> name { value }
- <Char*> name { value }
- Scalars can appear in various contexts. They are always optional,
- and specify some attribute value relevant to the current context.
- The scalar name is the name of the attribute; different attribute
- names are meaningful in different contexts. The value is either a
- numeric or a (quoted or unquoted) string value; the interpretation
- as a number or as a string depends on the nature of the named
- attribute. Because of a syntactic accident with the way the egg
- syntax evolved, <Scalar> and <Char*> are lexically the same and both
- can represent either a string or a number. <Char*> is being phased
- out; it is suggested that new egg files use only <Scalar>.
- GLOBAL INFORMATION ENTRIES
- These nodes contain information relevant to the file as a whole. They
- can be nested along with geometry nodes, but this nesting is
- irrelevant and the only significant placement rule is that they should
- appear before they are referenced.
- <CoordinateSystem> { string }
- This entry indicates the coordinate system used in the egg file; the
- egg loader will automatically make a conversion if necessary. The
- following strings are valid: Y-up, Z-up, Y-up-right, Z-up-right,
- Y-up-left, or Z-up-left. (Y-up is the same as Y-up-right, and Z-up
- is the same as Z-up-right.)
- By convention, this entry should only appear at the beginning of the
- file, although it is technically allowed anywhere. It is an error
- to include more than one coordinate system entry in the same file.
- If it is omitted, Y-up is assumed.
- <Texture> name { filename [scalars] }
- This describes a texture file that can be referenced later with
- <TRef> { name }. It is not necessary to make a <Texture> entry for
- each texture to be used; a texture may also be referenced directly
- by the geometry via an abbreviated inline <Texture> entry, but a
- separate <Texture> entry is the only way to specify anything other
- than the default texture attributes.
- If the filename is a relative path, the current egg file's directory
- is searched first, and then the texture-path and model-path are
- searched.
- The following attributes are presently implemented for textures:
- <Scalar> format { format-definition }
- This defines the load format of the image file. The
- format-definition is one of:
- RGBA, RGBM, RGBA12, RGBA8, RGBA4,
- RGB, RGB12, RGB8, RGB5, RGB332,
- LUMINANCE_ALPHA,
- RED, GREEN, BLUE, ALPHA, LUMINANCE
- The formats whose names end in digits specifically request a
- particular texel width. RGB12 and RGBA12 specify 48-bit texels
- with or without alpha; RGB8 and RGBA8 specify 32-bit texels, and
- RGB5 and RGBA4 specify 16-bit texels. RGB332 specifies 8-bit
- texels.
- The remaining formats are generic and specify only the semantic
- meaning of the channels. The size of the texels is determined by
- the width of the components in the image file. RGBA is the most
- general; RGB is the same, but without any alpha channel. RGBM is
- like RGBA, except that it requests only one bit of alpha, if the
- graphics card can provide that, to leave more room for the RGB
- components, which is especially important for older 16-bit
- graphics cards (the "M" stands for "mask", as in a cutout).
- The number of components of the image file should match the format
- specified; if it does not, the egg loader will attempt to provide
- the closest match that does.
- <Scalar> wrap { repeat-definition }
- <Scalar> wrapu { repeat-definition }
- <Scalar> wrapv { repeat-definition }
- This defines the behavior of the texture image outside of the
- normal (u,v) range 0.0 - 1.0. It is "REPEAT" to repeat the
- texture to infinity, "CLAMP" not to. The wrapping behavior may be
- specified independently for each axis via "wrapu" and "wrapv", or
- it may be specified for both simultaneously via "wrap".
- <Scalar> minfilter { filter-type }
- <Scalar> magfilter { filter-type }
- <Scalar> magfilteralpha { filter-type }
- <Scalar> magfiltercolor { filter-type }
- This specifies the type of filter applied when minimizing or
- maximizing. Filter-type may be one of:
- NEAREST
- LINEAR
- NEAREST_MIPMAP_NEAREST
- LINEAR_MIPMAP_NEAREST
- NEAREST_MIPMAP_LINEAR
- LINEAR_MIPMAP_LINEAR
- There are also some additional filter types that are supported for
- historical reasons, but each of those additional types maps to one
- of the above. New egg files should use only the above filter
- types.
- <Scalar> envtype { environment-type }
- This specifies the type of texture environment to create; i.e. it
- controls the way in which textures apply to models.
- Environment-type may be one of:
- MODULATE
- DECAL
- BLEND
- REPLACE
- ADD
- BLEND_COLOR_SCALE
- The default environment type is MODULATE, which means the texture
- color is multiplied with the base polygon (or vertex) color. This
- is the most common texture environment by far. Other environment
- types are more esoteric and are especially useful in the presence
- of multitexture. See howto.use_multitexture.txt for more on these.
- <Scalar> combine-rgb { combine-mode }
- <Scalar> combine-alpha { combine-mode }
- <Scalar> combine-rgb-source0 { combine-source }
- <Scalar> combine-rgb-operand0 { combine-operand }
- <Scalar> combine-rgb-source1 { combine-source }
- <Scalar> combine-rgb-operand1 { combine-operand }
- <Scalar> combine-rgb-source2 { combine-source }
- <Scalar> combine-rgb-operand2 { combine-operand }
- <Scalar> combine-alpha-source0 { combine-source }
- <Scalar> combine-alpha-operand0 { combine-operand }
- <Scalar> combine-alpha-source1 { combine-source }
- <Scalar> combine-alpha-operand1 { combine-operand }
- <Scalar> combine-alpha-source2 { combine-source }
- <Scalar> combine-alpha-operand2 { combine-operand }
- These options replace the envtype and specify the texture combiner
- mode, which is usually used for multitexturing. This specifies
- how the texture combines with the base color and/or the other
- textures applied previously. You must specify both an rgb and an
- alpha combine mode. Some combine-modes use one source/operand
- pair, and some use all three; most use just two.
- combine-mode may be one of:
- REPLACE
- MODULATE
- ADD
- ADD-SIGNED
- INTERPOLATE
- SUBTRACT
- DOT3-RGB
- DOT3-RGBA
- combine-source may be one of:
- TEXTURE
- CONSTANT
- PRIMARY-COLOR
- PREVIOUS
- CONSTANT_COLOR_SCALE
- combine-operand may be one of:
- SRC-COLOR
- ONE-MINUS-SRC-COLOR
- SRC-ALPHA
- ONE-MINUS-SRC-ALPHA
- The default values if any of these are omitted are:
- <Scalar> combine-rgb { modulate }
- <Scalar> combine-alpha { modulate }
- <Scalar> combine-rgb-source0 { previous }
- <Scalar> combine-rgb-operand0 { src-color }
- <Scalar> combine-rgb-source1 { texture }
- <Scalar> combine-rgb-operand1 { src-color }
- <Scalar> combine-rgb-source2 { constant }
- <Scalar> combine-rgb-operand2 { src-alpha }
- <Scalar> combine-alpha-source0 { previous }
- <Scalar> combine-alpha-operand0 { src-alpha }
- <Scalar> combine-alpha-source1 { texture }
- <Scalar> combine-alpha-operand1 { src-alpha }
- <Scalar> combine-alpha-source2 { constant }
- <Scalar> combine-alpha-operand2 { src-alpha }
- <Scalar> tex-gen { mode }
- This specifies that texture coordinates for the primitives that
- reference this texture should be dynamically computed at runtime,
- for instance to apply a reflection map or some other effect. The
- valid values for mode are:
- SPHERE_MAP
- CUBE_MAP
- WORLD_POSITION
- OBJECT_POSITION
- EYE_POSITION
- <Scalar> stage-name { name }
- Specifies the name of the TextureStage object that is created to
- render this texture. If this is omitted, a custom TextureStage is
- created for this texture if it is required (e.g. because some
- other multitexturing parameter has been specified), or the system
- default TextureStage is used if multitexturing is not required.
- <Scalar> priority { priority-value }
- Specifies an integer sort value to rank this texture in priority
- among other textures that are applied to the same geometry. This
- is only used to eliminate low-priority textures in case more
- textures are requested for a particular piece of geometry than the
- graphics hardware can render.
- <Scalar> blendr { red-value }
- <Scalar> blendg { green-value }
- <Scalar> blendb { blue-value }
- <Scalar> blenda { alpha-value }
- Specifies a four-component color that is applied with the color in
- case the envtype, above, is "blend".
- <Scalar> uv-name { name }
- Specifies the name of the texture coordinates that are to be
- associated with this texture. If this is omitted, the default
- texture coordinates are used.
- <Scalar> rgb-scale { scale }
- <Scalar> alpha-scale { scale }
- Specifies an additional scale factor that will scale the r, g, b
- (or a) components after the texture has been applied. This is
- only used when a combine mode is in effect. The only legal values
- are 1, 2, or 4.
- <Scalar> alpha { alpha-type }
- This specifies whether and what type of transparency will be
- performed. Alpha-type may be one of:
- OFF
- ON
- BLEND
- BLEND_NO_OCCLUDE
- MS
- MS_MASK
- If alpha-type is OFF, it means not to enable transparency, even if
- the image contains an alpha channel or the format is RGBA. If
- alpha-type is ON, it means to enable the default transparency,
- even if the image filename does not contain an alpha channel. If
- alpha-type is any of the other options, it specifies the type of
- transparency to be enabled.
- <Scalar> bin { bin-name }
- This specifies the bin name order of all polygons with this
- texture applied, in the absence of a bin name specified on the
- polygon itself. See the description for bin under polygon
- attributes.
- <Scalar> draw_order { number }
- This specifies the fixed drawing order of all polygons with this
- texture applied, in the absence of a drawing order specified on
- the polygon itself. See the description for draw_order under
- polygon attributes.
- <Transform> { transform-definition }
- This specifies a 2-d transformation that is applied to the UV's of
- a surface to generate the texture coordinates.
- The transform syntax is similar to that for groups, except it
- defines a 2-d 3x3 matrix. The definition may be any sequence of
- zero or more of the following. Transformations are post
- multiplied in the order they are encountered to produce a net
- transformation matrix. Rotations are counterclockwise about the
- origin in degrees. Matrices, when specified explicitly, are
- row-major.
- <Translate> { x y }
- <Rotate> { degrees }
- <Scale> { x y }
- <Scale> { s }
- <Matrix3> {
- 00 01 02
- 10 11 12
- 20 21 22
- }
- The transform definition might also include the following scalar:
- <Scalar> animated { 1 }
- If this is set, it indicates the matrix may be animated by a
- matrix channel, like a joint. At present, this flag is not used;
- eventually, it may be used to define an arbitrary texture
- coordinate animation.
- <Material> name { [scalars] }
- This defines a set of material attributes that may later be
- referenced with <MRef> { name }.
- The following attributes may appear within the material block:
- <Scalar> diffr { number }
- <Scalar> diffg { number }
- <Scalar> diffb { number }
- <Scalar> diffa { number }
- <Scalar> ambr { number }
- <Scalar> ambg { number }
- <Scalar> ambb { number }
- <Scalar> amba { number }
- <Scalar> emitr { number }
- <Scalar> emitg { number }
- <Scalar> emitb { number }
- <Scalar> emita { number }
- <Scalar> specr { number }
- <Scalar> specg { number }
- <Scalar> specb { number }
- <Scalar> speca { number }
- <Scalar> shininess { number }
- <Scalar> local { flag }
- These properties collectively define a "material" that controls the
- lighting effects that are applied to a surface; a material is only
- in effect in the presence of lighting.
- The four color groups, diff*, amb*, emit*, and spec* specify the
- diffuse, ambient, emission, and specular components of the lighting
- equation, respectively. Any of them may be omitted; the omitted
- component(s) take their color from the native color of the
- primitive, otherwise the primitive color is replaced with the
- material color.
- The shininess property controls the size of the specular highlight,
- and the value ranges from 0 to 128. A larger value creates a
- smaller highlight (creating the appearance of a shinier surface).
- <VertexPool> name { vertices }
- A vertex pool is a set of vertices. All geometry is created by
- referring to vertices by number in a particular vertex pool. There
- may be one or several vertex pools in an egg file, but all vertices
- that make up a single polygon must come from the same vertex pool.
- The body of a <VertexPool> entry is simply a list of one or more
- <Vertex> entries, as follows:
- <Vertex> number { x [y [z [w]]] [attributes] }
- A <Vertex> entry is only valid within a vertex pool definition.
- The number is the index by which this vertex will be referenced.
- It is optional; if it is omitted, the vertices are implicitly
- numbered consecutively beginning at one. If the number is
- supplied, the vertices need not be consecutive.
- Normally, vertices are three-dimensional (with coordinates x, y,
- and z); however, in certain cases vertices may have fewer or more
- dimensions, up to four. This is particularly true of vertices
- used as control vertices of NURBS curves and surfaces. If more
- coordinates are supplied than needed, the extra coordinates are
- ignored; if fewer are supplied than needed, the missing
- coordinates are assumed to be 0.
- The vertex's coordinates are always given in world space,
- regardless of any transforms before the vertex pool or before the
- referencing geometry. If the vertex is referenced by geometry
- under a transform, the egg loader will do an inverse transform to
- move the vertex into the proper coordinate space without changing
- its position in world space. One exception is geometry under an
- <Instance> node; in this case the vertex coordinates are given in
- the space of the <Instance> node. (Another exception is a
- <DynamicVertexPool>; see below.)
- In neither case does it make a difference whether the vertex pool
- is itself declared under a transform or an <Instance> node. The
- only deciding factor is whether the geometry that *uses* the
- vertex pool appears under an <Instance> node. It is possible for
- a single vertex to be interpreted in different coordinate spaces
- by different polygons.
- While each vertex must at least have a position, it may also have
- a color, normal, pair of UV coordinates, and/or a set of morph
- offsets. Furthermore, the color, normal, and UV coordinates may
- themselves have morph offsets. Thus, the [attributes] in the
- syntax line above may be replaced with zero or more of the
- following entries:
- <Dxyz> target { x y z }
- This specifies the offset of this vertex for the named morph
- target. See the "MORPH DESCRIPTION ENTRIES" header, below.
- <Normal> { x y z [morph-list] }
- This specifies the surface normal of the vertex. If omitted, the
- vertex will have no normal. Normals may also be morphed;
- morph-list here is thus an optional list of <DNormal> entries,
- similar to the above.
- <RGBA> { r g b a [morph-list] }
- This specifies the four-valued color of the vertex. Each
- component is in the range 0.0 to 1.0. A vertex color, if
- specified for all vertices of the polygon, overrides the polygon's
- color. If neither color is given, the default is white
- (1 1 1 1). The morph-list is an optional list of <DRGBA> entries.
- <UV> [name] { u v [morph-list] }
- This gives the texture coordinates of the vertex. This must be
- specified if a texture is to be mapped onto this geometry. As
- before, morph-list is an optional list of <DUV> entries.
- Unlike the other kinds of attributes, there may be multiple sets
- of UV's on each vertex, each with a unique name; this provides
- support for multitexturing. The name may be omitted to specify
- the default UV's.
- <DynamicVertexPool> name { vertices }
- A dynamic vertex pool is similar to a vertex pool in most respects,
- except that each vertex might be animated by substituting in values
- from a <VertexAnim> table. Also, the vertices defined within a
- dynamic vertex pool are always given in local coordinates, instead
- of world coordinates.
- The presence of a dynamic vertex pool makes sense only within a
- character model, and a single dynamic vertex pool may not span
- multiple characters. Each dynamic vertex pool creates a DynVerts
- object within the character by the same name; this name is used
- later when matching up the corresponding <VertexAnim>.
- At the present time, the DynamicVertexPool is not implemented in
- Panda3D.
-
- GEOMETRY ENTRIES
- <Polygon> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- }
- A polygon consists of a sequence of vertices from a single vertex
- pool. Vertices are identified by pool-name and index number within
- the pool; indices is a list of vertex numbers within the given
- vertex pool. Vertices are listed in counterclockwise order.
- Although the vertices must all come from the same vertex pool, they
- may have been assigned to arbitrarily many different joints
- regardless of joint connectivity (there is no "straddle-polygon"
- limitation). See Joints, below.
- The polygon syntax is quite verbose, and there isn't any way to
- specify a set of attributes that applies to a group of polygons--the
- attributes list must be repeated for each polygon. This is why egg
- files tend to be very large.
- The following attributes may be specified for polygons:
- <TRef> { texture-name }
- This refers to a named <Texture> entry given earlier. It applies
- the given texture to the polygon. This requires that all the
- polygon's vertices have been assigned texture coordinates.
- This attribute may be repeated multiple times to specify
- multitexture. In this case, each named texture is applied to the
- polygon, in the order specified.
- <Texture> { filename }
- This is another way to apply a texture to a polygon. The
- <Texture> entry is defined "inline" to the polygon, instead of
- referring to a <Texture> entry given earlier. There is no way to
- specify texture attributes given this form.
- There's no advantage to this syntax for texture mapping. It's
- supported only because it's required by some older egg files.
- <MRef> { material-name }
- This applies the material properties defined in the earlier
- <Material> entry to the polygon.
- <Normal> { x y z [morph-list] }
- This defines a polygon surface normal. The polygon normal will be
- used unless all vertices also have a normal. If no normal is
- defined, none will be supplied. The polygon normal, like the
- vertex normal, may be morphed by specifying a series of <DNormal>
- entries.
- The polygon normal is used only for lighting and environment
- mapping calculations, and is not related to the implicit normal
- calculated for CollisionPolygons.
- <RGBA> { r g b a [morph-list] }
- This defines the polygon's color, which will be used unless all
- vertices also have a color. If no color is defined, the default
- is white (1 1 1 1). The color may be morphed with a series of
- <DRGBA> entries.
- <BFace> { boolean-value }
- This defines whether the polygon will be rendered double-sided
- (i.e. its back face will be visible). By default, this option is
- disabled, and polygons are one-sided; specifying a nonzero value
- disables backface culling for this particular polygon and allows
- it to be viewed from either side.
-
- <Scalar> bin { bin-name }
- It is sometimes important to control the order in which objects
- are rendered, particularly when transparency is in use. In Panda,
- this is achieved via the use of named bins and, within certain
- kinds of bins, sometimes an explicit draw_order is also used (see
- below).
- In the normal (state-sorting) mode, Panda renders its geometry by
- first grouping into one or more named bins, and then rendering the
- bins in a specified order. The programmer is free to define any
- number of bins, named whatever he/she desires.
- This scalar specifies which bin this particular polygon is to be
- rendered within. If no bin scalar is given, or if the name given
- does not match any of the known bins, the polygon will be assigned
- to the default bin, which renders all opaque geometry sorted by
- state, followed by all transparent geometry sorted back-to-front.
- See also draw_order, below.
- <Scalar> draw_order { number }
- This works in conjunction with bin, above, to further refine the
- order in which this polygon is drawn, relative to other geometry
- in the same bin. If (and only if) the bin type named in the bin
- scalar is a CullBinFixed, this draw_order is used to define the
- fixed order that all geometry in the same will be rendered, from
- smaller numbers to larger numbers.
- If the draw_order scalar is specified but no bin scalar is
- specified, the default is a bin named "fixed", which is a
- CullBinFixed object that always exists by default.
- <Scalar> visibility { hidden | normal }
- If the visibility of a primitive is set to "hidden", the primitive
- is not generated as a normally visible primitive. If the
- Config.prc variable egg-suppress-hidden is set to true, the
- primitive is not converted at all; otherwise, it is converted as a
- "stashed" node.
- This, like the other rendering flags alpha, draw_order, and bin,
- may be specified at the group level, within the primitive level,
- or even within a texture.
- <PointLight> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- }
- A PointLight is a set of single points. One point is drawn for each
- vertex listed in the <VertexRef>. Normals, textures, and colors may
- be specified for PointLights, as well as draw_order, plus one
- additional attribute valid only for PointLights and Lines:
- <Scalar> thick { number }
- This specifies the size of the PointLight (or the width of a
- line), in pixels, when it is rendered. This may be a
- floating-point number, which is meaningful only when antialiasing
- is in effect. The default is 1.0.
- <Line> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- }
- A Line is a connected set of line segments. The listed N vertices
- define a series of N-1 line segments, drawn between vertex 0 and
- vertex 1, vertex 1 and vertex 2, etc. The line is not implicitly
- closed; if you wish to represent a loop, you must repeat vertex 0 at
- the end. As with a PointLight, normals, textures, colors,
- draw_order, and the "thick" attribute are all valid.
- PARAMETRIC DESCRIPTION ENTRIES
- The following entries define parametric curves and surfaces.
- Generally, Panda supports these only in the abstract; they're not
- geometry in the true sense but do exist in the scene graph and may
- have specific meaning to the application. However, Panda can create
- visible representations of these parametrics to aid visualization.
- These entries might also have meaning to external tools outside of an
- interactive Panda session, such as egg-qtess, which can be used to
- convert NURBS surfaces to polygons at different levels of resolution.
- In general, dynamic attributes such as morphs and joint assignment are
- legal for the control vertices of the following parametrics, but Panda
- itself doesn't support them and will always create static curves and
- surfaces. External tools like egg-qtess, however, may respect them.
- <NURBSCurve> {
- [attributes]
- <Order> { order }
- <Knots> { knot-list }
- <VertexRef> { indices <Ref> { pool-name } }
- }
- A NURBS curve is a general parametric curve. It is often used to
- represent a motion path, e.g. for a camera or an object.
- The order is equal to the degree of the polynomial basis plus 1. It
- must be an integer in the range [1,4].
- The number of vertices must be equal to the number of knots minus the
- order.
- Each control vertex of a NURBS is defined in homogeneous space with
- four coordinates x y z w (to convert to 3-space, divide x, y, and z
- by w). The last coordinate is always the homogeneous coordinate; if
- only three coordinates are given, it specifies a curve in two
- dimensions plus a homogeneous coordinate (x y w).
- The following attributes may be defined:
- <Scalar> type { curve-type }
- This defines the semanting meaning of this curve, either XYZ, HPR,
- or T. If the type is XYZ, the curve will automatically be
- transformed between Y-up and Z-up if necessary; otherwise, it will
- be left alone.
- <Scalar> subdiv { num-segments }
- If this scalar is given and nonzero, Panda will create a visible
- representation of the curve when the scene is loaded. The number
- represents the number of line segments to draw to approximate the
- curve.
- <RGBA> { r g b a [morph-list] }
- This specifies the color of the overall curve.
- NURBS control vertices may also be given color and/or morph
- attributes, but <Normal> and <UV> entries do not apply to NURBS
- vertices.
- <NURBSSurface> name {
- [attributes]
- <Order> { u-order v-order }
- <U-knots> { u-knot-list }
- <V-knots> { v-knot-list }
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- }
- A NURBS surface is an extension of a NURBS curve into two parametric
- dimensions, u and v. NURBS surfaces may be given the same set of
- attributes assigned to polygons, except for normals: <TRef>,
- <Texture>, <MRef>, <RGBA>, and draw_order are all valid attributes
- for NURBS. NURBS vertices, similarly, may be colored or morphed,
- but <Normal> and <UV> entries do not apply to NURBS vertices. The
- attributes may also include <NURBSCurve> and <Trim> entries; see
- below.
- To have Panda create a visualization of a NURBS surface, the
- following two attributes should be defined as well:
- <Scalar> U-subdiv { u-num-segments }
- <Scalar> V-subdiv { v-num-segments }
- These define the number of subdivisions to make in the U and V
- directions to represent the surface. A uniform subdivision is
- always made, and trim curves are not respected (though they will
- be drawn in if the trim curves themselves also have a subiv
- parameter). This is only intended as a cheesy visualization.
- The same sort of restrictions on order and knots applies to NURBS
- surfaces as do to NURBS curves. The order and knot description may
- be different in each dimension.
- The surface must have u-num * v-num vertices, where u-num is the
- number of u-knots minus the u-order, and v-num is the number of
- v-knots minus the v-order. All vertices must come from the same
- vertex pool. The nth (zero-based) index number defines control
- vertex (u, v) of the surface, where n = (v * u-num) + u. Thus, it
- is the u coordinate which changes faster.
- As with the NURBS curve, each control vertex is defined in
- homogeneous space with four coordinates x y z w.
- A NURBS may also contain curves on its surface. These are one or
- more nested <NURBSCurve> entries included with the attributes; these
- curves are defined in the two-dimensional parametric space of the
- surface. Thus, these curve vertices should have only two dimensions
- plus the homogeneous coordinate: u v w. A curve-on-surface has no
- intrinsic meaning to the surface, unless it is defined within a
- <Trim> entry, below.
- Finally, a NURBS may be trimmed by one or more trim curves. These
- are special curves on the surface which exclude certain areas from
- the NURBS surface definition. The inside is specified using two
- rules: an odd winding rule that states that the inside consists of
- all regions for which an infinite ray from any point in the region
- will intersect the trim curve an odd number of times, and a curve
- orientation rule that states that the inside consists of the regions
- to the left as the curve is traced.
- Each trim curve contains one or more loops, and each loop contains
- one or more NURBS curves. The curves of a loop connect in a
- head-to-tail fashion and must be explicitly closed.
- The trim curve syntax is as follows:
- <Trim> {
- <Loop> {
- <NURBSCurve> {
- <Order> { order }
- <Knots> { knot-list }
- <VertexRef> { indices <Ref> { pool-name } }
- }
- [ <NURBSCurve> { ... } ... ]
- }
- [ <Loop> { ... } ... ]
- }
- Although the egg syntax supports trim curves, there are at present
- no egg processing tools that respect them. For instance, egg-qtess
- ignores trim curves and always tesselates the entire NURBS surface.
- MORPH DESCRIPTION ENTRIES
- Morphs are linear interpolations of attribute values at run time,
- according to values read from an animation table. In general, vertex
- positions, surface normals, texture coordinates, and colors may be
- morphed.
- A morph target is defined by giving a net morph offset for a series of
- vertex or polygon attributes; this offset is the value that will be
- added to the attribute when the morph target has the value 1.0. At
- run time, the morph target's value may be animated to any scalar value
- (but generally between 0.0 and 1.0); the corresponding fraction of the
- offset is added to the attribute each frame.
- There is no explicit morph target definition; a morph target exists
- solely as the set of all offsets that share the same target name. The
- target name may be any arbitrary string; like any name in an egg file,
- it should be quoted if it contains special characters.
- The following types of morph offsets may be defined, within their
- corresponding attribute entries:
- <Dxyz> target { x y z }
- A position delta, valid within a <Vertex> entry or a <CV> entry.
- The given offset vector, scaled by the morph target's value, is
- added to the vertex or CV position each frame.
- <DNormal> target { x y z }
- A normal delta, similar to the position delta, valid within a
- <Normal> entry (for vertex or polygon normals). The given offset
- vector, scaled by the morph target's value, is added to the normal
- vector each frame. The resulting vector may not be automatically
- normalized to unit length.
- <DUV> target { u v }
- A texture-coordinate delta, valid within a <UV> entry (within a
- <Vertex> entry). The given 2-valued offset vector, scaled by the
- morph target's value, is added to the vertex's texture coordinates
- each frame.
- <DRGBA> target { r g b a }
- A color delta, valid within an <RGBA> entry (for vertex or polygon
- colors). The given 4-valued offset vector, scaled by the morph
- target's value, is added to the color value each frame.
- GROUPING ENTRIES
- <Group> name { group-body }
- A <Group> node is the primary means of providing structure to the
- egg file. Groups can contain vertex pools and polygons, as well as
- other groups. The egg loader translates <Group> nodes directly into
- PandaNodes in the scene graph (although the egg loader reserves the
- right to arbitrarily remove nodes that it deems unimportant--see the
- <Model> flag, below to avoid this). In addition, the following
- entries can be given specifically within a <Group> node to specify
- attributes of the group:
- GROUP BINARY ATTRIBUTES
-
- These attributes may be either on or off; they are off by default.
- They are turned on by specifying a non-zero "boolean-value".
- <DCS> { boolean-value }
- DCS stands for Dynamic Coordinate System. This indicates that
- show code will expect to be able to read the transform set on this
- node at run time, and may need to modify the transform further.
- This is a special case of <Model>, below.
- <DCS> { dcs-type }
- This is another syntax for the <DCS> flag. The dcs-type string
- should be one of either "local" or "net", which specifies the kind
- of preserve_transform flag that will be set on the corresponding
- ModelNode. If the string is "local", it indicates that the local
- transform on this node (as well as the net transform) will not be
- affected by any flattening operation and will be preserved through
- the entire model loading process. If the string is "net", then
- only the net transform will be preserved; the local transform may
- be adjusted in the event of a flatten operation.
- <Model> { boolean-value }
- This indicates that the show code might need a pointer to this
- particular group. This creates a ModelNode at the corresponding
- level, which is guaranteed not to be removed by any flatten
- operation. However, its transform might still be changed, but see
- also the <DCS> flag, above.
- <Dart> { boolean-value }
- This indicates that this group begins an animated character. A
- Character node, which is the fundamental animatable object of
- Panda's high-level Actor class, will be created for this group.
- This flag should always be present within the <Group> entry at the
- top of any hierarchy of <Joint>'s and/or geometry with morphed
- vertices; joints and morphs appearing outside of a hierarchy
- identified with a <Dart> flag are undefined.
- <Switch> { boolean-value }
- This attribute indicates that the child nodes of this group
- represent a series of animation frames that should be
- consecutively displayed. In the absence of an "fps" scalar for
- the group (see below), the egg loader creates a SwitchNode, and it
- the responsibility of the show code to perform the switching. If
- an fps scalar is defined and is nonzero, the egg loader creates a
- SequenceNode instead, which automatically cycles through its
- children.
- GROUP SCALARS
- <Scalar> fps { frame-rate }
- This specifies the rate of animation for a SequenceNode (created
- when the Switch flag is specified, see above). A value of zero
- indicates a SwitchNode should be created instead.
- <Scalar> bin { bin-name }
- This specifies the bin name for all polygons at or below this node
- that do not explicitly set their own bin. See the description of
- bin for geometry attributes, above.
- <Scalar> draw_order { number }
- This specifies the drawing order for all polygons at or below this
- node that do not explicitly set their own drawing order. See the
- description of draw_order for geometry attributes, above.
- <Scalar> visibility { hidden | normal }
- If the visibility of a group is set to "hidden", the primitives
- nested within that group are not generated as a normally visible
- primitive. If the Config.prc variable egg-suppress-hidden is set
- to true, the primitives are not converted at all; otherwise, they
- are converted as a "stashed" node.
- <Scalar> decal { boolean-value }
- If this is present and boolean-value is non-zero, it indicates
- that the geometry *below* this level is coplanar with the geometry
- *at* this level, and the geometry below is to be drawn as a decal
- onto the geometry at this level. This means the geometry below
- this level will be rendered "on top of" this geometry, but without
- the Z-fighting artifacts one might expect without the use of the
- decal flag.
- <Scalar> decalbase { boolean-value }
- This can optionally be used with the "decal" scalar, above. If
- present, it should be applied to a sibling of one or more nodes
- with the "decal" scalar on. It indicates which of the sibling
- nodes should be treated as the base of the decal. In the absence
- of this scalar, the parent of all decal nodes is used as the decal
- base. This scalar is useful when the modeling package is unable
- to parent geometry nodes to other geometry nodes.
- <Scalar> collide-mask { value }
- <Scalar> from-collide-mask { value }
- <Scalar> into-collide-mask { value }
- Sets the CollideMasks on the collision nodes and geometry nodes
- created at or below this group to the indicated values. These
- are bits that indicate which objects can collide with which
- other objects. Setting "collide-mask" is equivalent to setting
- both "from-collide-mask" and "into-collide-mask" to the same
- value.
- The value may be an ordinary decimal integer, or a hex number in
- the form 0x000, or a binary number in the form 0b000.
- OTHER GROUP ATTRIBUTES
- <Billboard> { type }
- This entry indicates that all geometry defined at or below this
- group level is part of a billboard that will rotate to face the
- camera. Type is either "axis" or "point", describing the type of
- rotation.
- Billboards rotate about their local axis. In the case of a Y-up
- file, the billboards rotate about the Y axis; in a Z-up file, they
- rotate about the Z axis. Point-rotation billboards rotate about
- the origin.
- There is an implicit <Instance> around billboard geometry. This
- means that the geometry within a billboard is not specified in
- world coordinates, but in the local billboard space. Thus, a
- vertex drawn at point 0,0,0 will appear to be at the pivot point
- of the billboard, not at the origin of the scene.
- <SwitchCondition> {
- <Distance> {
- in out [fade] <Vertex> { x y z }
- }
- }
- The subtree beginning at this node and below represents a single
- level of detail for a particular model. Sibling nodes represent
- the additional levels of detail. The geometry at this node will
- be visible when the point (x, y, z) is closer than "in" units, but
- further than "out" units, from the camera. "fade" is presently
- ignored.
- <Collide> name { type [flags] }
- This entry indicates that geometry defined at this group level is
- actually an invisible collision surface, and is not true geometry.
- The geometry is used to define the extents of the collision
- surface. If there is no geometry defined at this level, then a
- child is searched for with the same collision type specified, and
- its geometry is used to define the extent of the collision
- surface (unless the "descend" flag is given; see below).
- Valid types so far are:
- Plane
-
- The geometry represents an infinite plane. The first polygon
- found in the group will define the plane.
- Polygon
- The geometry represents a single polygon. The first polygon is
- used.
- Polyset
- The geometry represents a complex shape made up of several
- polygons. This collision type should not be overused, as it
- provides the least optimization benefit.
- Sphere
- The geometry represents a sphere. The vertices in the group are
- averaged together to determine the sphere's center and radius.
- InvSphere
- The geometry represents an inverse sphere. This is the same as
- Sphere, with the normal inverted, so that the solid part of an
- inverse sphere is the entire world outside of it. Note that an
- inverse sphere is in infinitely large solid with a finite hole
- cut into it.
- Tube
- The geometry represents a tube. This is a cylinder-like shape
- with hemispherical endcaps; it is sometimes called a capsule or
- a lozenge in other packages. The smallest tube shape that will
- fit around the vertices is used.
- The flags may be any zero or more of:
- event
- Throws the name of the <Collide> entry, or the name of the
- surface if the <Collide> entry has no name, as an event whenever
- an avatar strikes the solid. This is the default if the
- <Collide> entry has a name.
- intangible
- Rather than being a solid collision surface, the defined surface
- represents a boundary. The name of the surface will be thrown
- as an event when an avatar crosses into the interior, and
- name-out will be thrown when an avater exits.
- descend
- Instead of creating only one collision object of the given type,
- each group descended from this node that contains geometry will
- define a new collision object of the given type. The event
- name, if any, will also be inherited from the top node and
- shared among all the collision objects.
- keep
-
- Don't discard the visible geometry after using it to define a
- collision surface; create both an invisible collision surface
- and the visible geometry.
- level
- Stores a special effective normal with the collision solid that
- points up, regardless of the actual shape or orientation of the
- solid. This can be used to allow an avatar to stand on a
- sloping surface without having a tendency to slide downward.
- <ObjectType> { type }
- This is a short form to indicate one of several pre-canned sets of
- attributes. Type may be any word, and a Config definition will be
- searched for by the name "egg-object-type-word", where "word" is
- the type word. This definition may contain any arbitrary egg
- syntax to be parsed in at this group level.
- A number of predefined ObjectType definitions are provided:
- barrier
- This is equivalent to <Collide> { Polyset descend }. The
- geometry defined at this root and below defines an invisible
- collision solid.
- trigger
- This is equivalent to <Collide> { Polyset descend intangible }.
- The geometry defined at this root and below defines an invisible
- trigger surface.
- bubble
- Equivalent to <Collide> { Sphere keep descend }. A collision
- bubble is placed around the geometry, which is otherwise
- unchanged.
- ghost
- Equivalent to <Scalar> collide-mask { 0 }. It means that the
- geometry beginning at this node and below should never be
- collided with--characters will pass through it.
- backstage
- This has no equivalent; it is treated as a special case. It
- means that the geometry at this node and below should not be
- translated. This will normally be used on scale references and
- other modeling tools.
- There may also be additional predefined egg object types not
- listed here; see the *.pp files that are installed into the etc
- directory for a complete list.
- <Transform> { transform-definition }
- This specifies a matrix transform at this group level. This
- defines a local coordinate space for this group and its
- descendents. Vertices are still specified in world coordinates
- (in a vertex pool), but any geometry assigned to this group will
- be inverse transformed to move its vertices to the local space.
- The transform definition may be any sequence of zero or more of
- the following. Transformations are post multiplied in the order
- they are encountered to produce a net transformation matrix.
- Rotations are defined as a counterclockwise angle in degrees about
- a particular axis, either implicit (about the x, y, or z axis), or
- arbitrary. Matrices, when specified explicitly, are row-major.
- <Translate> { x y z }
- <RotX> { degrees }
- <RotY> { degrees }
- <RotZ> { degrees }
- <Rotate> { degrees x y z }
- <Scale> { x y z }
- <Scale> { s }
- <Matrix4> {
- 00 01 02 03
- 10 11 12 13
- 20 21 22 23
- 30 31 32 33
- }
- Note that the <Transform> block defines a 3-d transform when it
- appears within the context of a node, while it defines a 2-d
- transform (and has correspondingly different entries) when it
- appears within the context of a texture.
- <VertexRef> { indices <Ref> { pool-name } }
- This moves geometry created from the named vertices into the
- current group, regardless of the group in which the geometry is
- actually defined. See the <Joint> description, below.
- <Instance> name { group-body }
- An <Instance> node is exactly like a <Group> node, except that
- vertices referenced by geometry created under the <Instance> node
- are not assumed to be given in world coordinates, but are instead
- given in the local space of the <Instance> node itself (including
- any transforms given to the node).
- In other words, geometry under an <Instance> node is defined in
- local coordinates. In principle, similar geometry can be created
- under several different <Instance> nodes, and thus can be positioned
- in a different place in the scene each instance. This doesn't
- necessarily imply the use of shared geometry in the Performer scene
- graph, but see the <Ref> syntax, below.
- This is particularly useful in conjunction with a <File> entry, to
- load external file references at places other than the origin.
- A special syntax of <Instance> entries does actually create shared
- geometry in the scene graph. However, please note that this special
- syntax is not supported by Panda3D at this time. It is documented
- here against the day that it will be supported.
- The syntax is:
- <Instance> name {
- <Ref> { group-name }
- [ <Ref> { group-name } ... ]
- }
- In this case, the referenced group name will appear as a duplicate
- instance in this part of the tree. Local transforms can be applied
- and are relative to the reference group's transform.
- <Joint> name { [transform] [ref-list] [joint-list] }
- A joint is a highly specialized kind of grouping node. A tree of
- joints is used to specify the skeletal structure of an animated
- character.
- A joint may only contain one of three things. It may contain a
- <Transform> entry, as above, which defines the joint's unanimated
- (rest) position; it may contain lists of assigned vertices or CV's;
- and it may contain other joints.
- A tree of <Joint> nodes only makes sense within a character
- definition, which is created by applying the <DART> flag to a group.
- See <DART>, above.
- The vertex assignment is crucial. This is how the geometry of a
- character is made to move with the joints. The character's geometry
- is actually defined outside the joint tree, and each vertex must be
- assigned to one or more joints within the tree.
- This is done with zero or more <VertexRef> entries per joint, as the
- following:
- <VertexRef> { indices [<Scalar> membership { m }] <Ref> { pool-name } }
- This is syntactically similar to the way vertices are assigned to
- polygons. Each <VertexRef> entry can assign vertices from only one
- vertex pool (but there may be many <VertexRef> entries per joint).
- Indices is a list of vertex numbers from the specied vertex pool, in
- an arbitrary order.
- The membership scalar is optional. If specified, it is a value
- between 0.0 and 1.0 that indicates the fraction of dominance this
- joint has over the vertices. This is used to implement
- soft-skinning, so that each vertex may have partial ownership in
- several joints.
- The <VertexRef> entry may also be given to ordinary <Group> nodes.
- In this case, it treats the geometry as if it was parented under the
- group in the first place. Non-total membership assignments are
- meaningless.
- <Bundle> name { table-list }
- <Table> name { table-body }
- A table is a set of animated values for joints. A tree of tables
- with the same structure as the corresponding tree of joints must be
- defined for each character to be animated. Such a tree is placed
- under a <Bundle> node, which provides a handle within Panda to the
- tree as a whole.
- Bundles may only contain tables; tables may contain more tables,
- bundles, or any one of the following (<Scalar> entries are optional,
- and default as shown):
- <S$Anim> name {
- <Scalar> fps { 24 }
- <V> { values }
- }
- This is a table of scalar values, one per frame. This may be
- applied to a morph slider, for instance.
- <Xfm$Anim> name {
- <Scalar> fps { 24 }
- <Scalar> order { sphrt }
- <Scalar> contents { ijkabcphrxyz }
- <V> { values }
- }
- This is a table of matrix transforms, one per frame, such as may
- be applied to a joint. The "contents" string consists of a subset
- of the letters "ijkabcphrxyz", where each letter corresponds to a
- column of the table; <V> is a list of numbers of length(contents)
- * num_frames. Each letter of the contents string corresponds to a
- type of transformation:
- i, j, k - scale in x, y, z directions, respectively
- a, b, c - shear in xy, xz, and yz planes, respectively
- p, h, r - rotate by pitch, heading, roll
- x, y, z - translate in x, y, z directions
- The net transformation matrix specified by each row of the table
- is defined as the net effect of each of the individual columns'
- transform, according to the corresponding letter in the contents
- string. The order the transforms are applied is defined by the
- order string:
- s - all scale and shear transforms
- p, h, r - individual rotate transforms
- t - all translation transforms
- <Xfm$Anim_S$> name {
- <Scalar> fps { 24 }
- <Scalar> order { sphrt }
- <S$Anim> i { ... }
- <S$Anim> j { ... }
- ...
- }
- This is a variant on the <Xfm$Anim> entry, where each column of
- the table is entered as a separate <S$Anim> table. This syntax
- reflects an attempt to simplify the description by not requiring
- repetition of values for columns that did not change value during
- an animation sequence.
- <VertexAnim> name {
- <Scalar> width { table-width }
- <Scalar> fps { 24 }
- <V> { values }
- }
- This is a table of vertex positions, normals, texture coordinates,
- or colors. These values will be subsituted at runtime for the
- corresponding values in a <DynamicVertexPool>. The name of the
- table should be "coords", "norms", "texCoords", or "colors",
- according to the type of values defined. The number table-width
- is the number of floats in each row of the table. In the case of
- a coords or norms table, this must be 3 times the number of
- vertices in the corresponding dynamic vertex pool. (For texCoords
- and colors, this number must be 2 times and 4 times, respectively.)
- MISCELLANEOUS
- <File> { filename }
- This includes a copy of the referenced egg file at the current
- point. This is usually placed under an <Instance> node, so that the
- current transform will apply to the geometry in the external file.
- The extension ".egg" is implied if it is omitted.
- As with texture filenames, the filename may be a relative path, in
- which case the current egg file's directory is searched first, and
- then the model-path is searched.
|