| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954 |
- 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 (usually)
- 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> alpha-file { alpha-filename }
- If this scalar is present, the texture file's alpha channel is
- read in from the named image file (which should contain a
- grayscale image), and the two images are combined into a single
- two- or four-channel image internally. This is useful for loading
- alpha channels along with image file formats like JPEG that don't
- traditionally support alpha channels.
- <Scalar> alpha-file-channel { channel }
- This defines the channel that should be extracted from the file
- named by alpha-file to determine the alpha channel for the
- resulting channel. The default is 0, which means the grayscale
- combination of r, g, b. Otherwise, this should be the 1-based
- channel number, for instance 1, 2, or 3 for r, g, or b,
- respectively, or 4 for the alpha channel of a four-component
- image.
- <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> compression { compression-mode }
- Defines an explicit control over the real-time compression mode
- applied to the texture. The various options are:
- DEFAULT OFF ON
- FXT1 DXT1 DXT2 DXT3 DXT4 DXT5
- This controls the compression of the texture when it is loaded
- into graphics memory, and has nothing to do with on-disk
- compression such as JPEG. If this option is omitted or "DEFAULT",
- then the texture compression is controlled by the
- compressed-textures config variable. If it is "OFF", texture
- compression is explicitly off for this texture regardless of the
- setting of the config variable; if it is "ON", texture compression
- is explicitly on, and a default compression algorithm supported by
- the driver is selected. If any of the other options, it names the
- specific compression algorithm to be used.
- <Scalar> wrap { repeat-definition }
- <Scalar> wrapu { repeat-definition }
- <Scalar> wrapv { repeat-definition }
- <Scalar> wrapw { 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".
- Although less often used, for 3-d textures wrapw may also be
- specified, and it behaves similarly to wrapu and wrapv.
- There are other legal values in addtional to REPEAT and CLAMP.
- The full list is:
- CLAMP
- REPEAT
- MIRROR
- MIRROR_ONCE
- BORDER_COLOR
- <Scalar> borderr { red-value }
- <Scalar> borderg { green-value }
- <Scalar> borderb { blue-value }
- <Scalar> bordera { alpha-value }
- These define the "border color" of the texture, which is
- particularly important when one of the wrap modes, above, is
- BORDER_COLOR.
- <Scalar> type { texture-type }
- This may be one of the following attributes:
- 1D
- 2D
- 3D
- CUBE_MAP
- The default is "2D", which specifies a normal, 2-d texture. If
- any of the other types is specified instead, a texture image of
- the corresponding type is loaded.
- If 3D or CUBE_MAP is specified, then a series of texture images
- must be loaded to make up the complete texture; in this case, the
- texture filename is expected to include a sequence of one or more
- hash mark ("#") characters, which will be filled in with the
- sequence number. The first image in the sequence must be numbered
- 0, and there must be no gaps in the sequence. In this case, a
- separate alpha-file designation is ignored; the alpha channel, if
- present, must be included in the same image with the color
- channel(s).
- <Scalar> read-mipmaps { flag }
- If this flag is nonzero, then pre-generated mipmap levels will be
- loaded along with the texture. In this case, the filename should
- contain a sequence of one or more hash mark ("#") characters,
- which will be filled in with the mipmap level number; the texture
- filename thus determines a series of images, one for each mipmap
- level. The base texture image is mipmap level 0.
- If this flag is specified in conjunction with a 3D or cube map
- texture (as specified above), then the filename should contain two
- hash mark sequences, separated by a character such as an
- underscore, hyphen, or dot. The first sequence will be filled in
- with the mipmap level index, and the second sequence will be
- filled in with the 3D sequence or cube map face.
- <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
- MODULATE_GLOW
- MODULATE_GLOSS
- *NORMAL
- *NORMAL_HEIGHT
- *GLOW
- *GLOSS
- *HEIGHT
- *SELECTOR
- 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. In particular, the types prefixed by an asterisk
- (*) require enabling Panda's automatic ShaderGenerator.
- <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
- LAST_SAVED_RESULT
- 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> saved-result { flag }
-
- If flag is nonzero, then it indicates that this particular texture
- stage will be supplied as the "last_saved_result" source for any
- future texture stages.
- <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:
- EYE_SPHERE_MAP (or SPHERE_MAP)
- WORLD_CUBE_MAP
- EYE_CUBE_MAP (or CUBE_MAP)
- WORLD_NORMAL
- EYE_NORMAL
- WORLD_POSITION
- EYE_POSITION
- POINT_SPRITE
- <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", or one of the combine-sources
- is "constant".
- <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.
- <Scalar> quality-level { quality }
- Sets a hint to the renderer about the desired performance /
- quality tradeoff for this particular texture. This is most useful
- for the tinydisplay software renderer; for normal,
- hardware-accelerated renderers, this may have little or no effect.
- This may be one of:
- DEFAULT
- FASTEST
- NORMAL
- BEST
- "Default" means to use whatever quality level is specified by the
- global texture-quality-level config variable.
- <Transform> { transform-definition }
- This specifies a 2-d or 3-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 may
- define either a 2-d 3x3 matrix or a 3-d 4x4 matrix. (You should
- use the two-dimensional forms if the UV's are two-dimensional, and
- the three-dimensional forms if the UV's are three-dimensional.)
- A two-dimensional transform 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
- }
- A three-dimensional transform may be any sequence of zero or more
- of the following. See the description under <Group>, below, for
- more information.
- <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
- }
- <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 [w] [tangent] [binormal] [morph-list] }
- This gives the texture coordinates of the vertex. This must be
- specified if a texture is to be mapped onto this geometry.
- The texture coordinates are usually two-dimensional, with two
- component values (u v), but they may also be three-dimensional,
- with three component values (u v w). (Arguably, it should be
- called <UVW> instead of <UV> in the three-dimensional case, but
- it's not.)
- 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.
- The UV's also support an optional tangent and binormal. These
- values are based on the vertex normal and the UV coordinates of
- connected vertices, and are used to render normal maps and similar
- lighting effects. They are defined within the <UV> entry because
- there may be a different set of tangents and binormals for each
- different UV coordinate set. If present, they have the expected
- syntax:
- <UV> [name] { u v [w] <Tangent> { x y z } <Binormal> { x y z } }
- <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, but the fractional part is meaningful only
- when antialiasing is in effect. The default is 1.0.
- <Scalar> perspective { boolean-value }
- If this is specified, then the thickness, above, is to interpreted
- as a size in 3-d spatial units, rather than a size in pixels, and
- the point should be scaled according to its distance from the
- viewer normally.
- <Line> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- [component attributes]
- }
- 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 (but not
- "perspective"). Also, since a Line (with more than two vertices) is
- made up of multiple line segments, it may contain a number of
- <Component> entries, to set a different color and/or normal for each
- line segment, as in TriangleStrip, below.
- <TriangleStrip> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- [component attributes]
- }
- A triangle strip is only rarely encountered in an egg file; it is
- normally generated automatically only during load time, when
- connected triangles are automatically meshed for loading, and even
- then it exists only momentarily. Since a triangle strip is a
- rendering optimization only and adds no useful scene information
- over a loose collection of triangles, its usage is contrary to the
- general egg philosophy of representing a scene in the abstract.
- Nevertheless, the syntax exists, primarily to allow inspection of
- the meshing results when needed. You can also add custom
- TriangleStrip entries to force a particular mesh arrangement.
- A triangle strip is defined as a series of connected triangles.
- After the first three vertices, which define the first triangle,
- each new vertex defines one additional triangle, by alternating up
- and down.
- It is possible for the individual triangles of a triangle strip to
- have a separate normal and/or color. If so, a <Component> entry
- should be given for each so-modified triangle:
-
- <Component> index {
- <RGBA> { r g b a [morph-list] }
- <Normal> { x y z [morph-list] }
- }
- Where index ranges from 0 to the number of components defined by the
- triangle strip (less 1). Note that the component attribute list
- must always follow the vertex list.
- <TriangleFan> name {
- [attributes]
- <VertexRef> {
- indices
- <Ref> { pool-name }
- }
- [component attributes]
- }
- A triangle fan is similar to a triangle strip, except all of the
- connected triangles share the same vertex, which is the first
- vertex. See <TriangleStrip>, above.
- 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 [w] }
- A texture-coordinate delta, valid within a <UV> entry (within a
- <Vertex> entry). The offset vector should be 2-valued if the
- enclosing UV is 2-valued, or 3-valued if the enclosing UV is
- 3-valued. The given 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.
- <Scalar> blend { mode }
- Specifies that a special blend mode should be applied geometry at
- this level and below. The available options are none, add,
- subtract, inv-subtract, min, and max. See ColorBlendAttrib.
- <Scalar> blendop-a { mode }
- <Scalar> blendop-b { mode }
- If blend mode, above, is not none, this specifies the A and B
- operands to the blend equation. Common options are zero, one,
- incoming-color, one-minus-incoming-color. See ColorBlendAttrib
- for the complete list of available options. The default is "one".
- <Scalar> blendr { red-value }
- <Scalar> blendg { green-value }
- <Scalar> blendb { blue-value }
- <Scalar> blenda { alpha-value }
- If blend mode, above, is not none, and one of the blend operands
- is constant-color or a related option, this defines the constant
- color that will be used.
- 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.
- <Tag> key { value }
- This attribute defines the indicated tag (as a key/value pair),
- retrievable via NodePath::get_tag() and related interfaces, on
- this node.
- <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.
- sphere
- Equivalent to <Collide> { Sphere descend }. The geometry is
- replaced with the smallest collision sphere that will enclose
- it. Typically you model a sphere in polygons and put this flag
- on it to create a collision sphere of the same size.
- tube
- Equivalent to <Collide> { Tube descend }. As in sphere, above,
- but the geometry is replaced with a collision tube (a capsule).
- Typically you will model a capsule or a cylinder in polygons.
- 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 should always define a 3-d
- transform when it appears within the body of a <Group>, while it
- may define either a 2-d or a 3-d transform when it appears within
- the body of a <Texture>. See <Texture>, above.
- <DefaultPose> { transform-definition }
- This defines an optional default pose transform, which might be a
- different transform from that defined by the <Transform> entry,
- above. This makes sense only for a <Joint>. See the <Joint>
- description, below.
- The default pose transform defines the transform the joint will
- maintain in the absence of any animation being applied. This is
- different from the <Transform> entry, which defines the coordinate
- space the joint must have in order to keep its vertices in their
- (global space) position as given in the egg file. If this is
- different from the <Transform> entry, the joint's vertices will
- *not* be in their egg file position at initial load. If there is
- no <DefaultPose> entry for a particular joint, the implicit
- default-pose transform is the same as the <Transform> entry.
- Normally, the <DefaultPose> entry, if any, is created by the
- egg-optchar -defpose option. Most other software has little
- reason to specify an explicit <DefaultPose>.
- <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.
- <AnimPreload> {
- <Scalar> fps { float-value }
- <Scalar> num-frames { integer-value }
- }
- One or more AnimPreload entries may appear within the <Group> that
- contains a <Dart> entry, indicating an animated character (see
- above). These AnimPreload entries record the minimal preloaded
- animation data required in order to support asynchronous animation
- binding. These entries are typically generated by the egg-optchar
- program with the -preload option, and are used by the Actor code
- when allow-async-bind is True (the default).
- <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 Panda3D 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. 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 referencing group's transform. The
- referenced group must appear preceding this point in the egg file,
- and it will also be a part of the scene in the point at which it
- first appears. The referenced group may be either a <Group> or an
- <Instance> of its own; usually, it is a <Group> nested within an
- earlier <Instance> entry.
- <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 { srpht }
- <Scalar> contents { ijkabcrphxyz }
- <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 "ijkabcrphxyz", 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
- r, p, h - 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
- r, p, h - individual rotate transforms
- t - all translation transforms
- <Xfm$Anim_S$> name {
- <Scalar> fps { 24 }
- <Scalar> order { srpht }
- <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.
- ANIMATION STRUCTURE
- Unanimated models may be defined in egg files without much regard to
- any particular structure, so long as named entries like VertexPools
- and Textures appear before they are referenced.
- However, a certain rigid structural convention must be followed in
- order to properly define an animated skeleton-morph model and its
- associated animation data.
- The structure for an animated model should resemble the following:
- <Group> CHARACTER_NAME {
- <Dart> { 1 }
- <Joint> JOINT_A {
- <Transform> { ... }
- <VertexRef> { ... }
- <Group> { <Polygon> ... }
- <Joint> JOINT_B {
- <Transform> { ... }
- <VertexRef> { ... }
- <Group> { <Polygon> ... }
- }
- <Joint> JOINT_C {
- <Transform> { ... }
- <VertexRef> { ... }
- <Group> { <Polygon> ... }
- }
- ...
- }
- }
- The <Dart> flag is necessary to indicate that this group begins an
- animated model description. Without the <Dart> flag, joints will be
- treated as ordinary groups, and morphs will be ignored.
- In the above, UPPERCASE NAMES represent an arbitrary name that you
- may choose. The name of the enclosing group, CHARACTER_NAME, is
- taken as the name of the animated model. It should generally match
- the bundle name in the associated animation tables.
- Within the <Dart> group, you may define an arbitrary hierarchy of
- <Joint> entries. There may be as many <Joint> entries as you like,
- and they may have any nesting complexity you like. There may be
- either one root <Joint>, or multiple roots. However, you must
- always include at least one <Joint>, even if your animation consists
- entirely of morphs.
- Polygons may be directly attached to joints by enclosing them within
- the <Joint> group, perhaps with additional nesting <Group> entries,
- as illustrated above. This will result in the polygon's vertices
- being hard-assigned to the joint it appears within. Alternatively,
- you declare the polygons elsewhere in the egg file, and use
- <VertexRef> entries within the <Joint> group to associate the
- vertices with the joints. This is the more common approach, since
- it allows for soft-assignment of vertices to multiple joints.
- It is not necessary for every joint to have vertices at all. Every
- joint should include a transform entry, however, which defines the
- initial, resting transform of the joint (but see also <DefaultPose>,
- above). If a transform is omitted, the identity transform is
- assumed.
- Some of the vertex definitions may include morph entries, as
- described in MORPH DESCRIPTION ENTRIES, above. These are meaningful
- only for vertices that are assigned, either implicitly or
- explicitly, to at least one joint.
- You may have multiple versions of a particular animated model--for
- instance, multiple different LOD's, or multiple different clothing
- options. Normally each different version is stored in a different
- egg file, but it is also possible to include multiple versions
- within the same egg file. If the different versions are intended to
- play the same animations, they should all have the same
- CHARACTER_NAME, and their joint hierarchies should exactly match in
- structure and names.
- The structure for an animation table should resemble the following:
- <Table> {
- <Bundle> CHARACTER_NAME {
- <Table> "<skeleton>" {
- <Table> JOINT_A {
- <Xfm$Anim_S$> xform {
- <Char*> order { sphrt }
- <Scalar> fps { 24 }
- <S$Anim> x { 0 0 10 10 20 ... }
- <S$Anim> y { 0 0 0 0 0 ... }
- <S$Anim> z { 20 20 20 20 20 ... }
- }
- <Table> JOINT_B {
- <Xfm$Anim_S$> xform {
- <Char*> order { sphrt }
- <Scalar> fps { 24 }
- <S$Anim> x { ... }
- <S$Anim> y { ... }
- <S$Anim> z { ... }
- }
- }
- <Table> JOINT_C {
- <Xfm$Anim_S$> xform {
- <Char*> order { sphrt }
- <Scalar> fps { 24 }
- <S$Anim> x { ... }
- <S$Anim> y { ... }
- <S$Anim> z { ... }
- }
- }
- }
- }
- <Table> morph {
- <S$Anim> MORPH_A {
- <Scalar> fps { 24 }
- <V> { 0 0 0 0.1 0.2 0.3 1 ... }
- }
- <S$Anim> MORPH_B {
- <Scalar> fps { 24 }
- <V> { ... }
- }
- <S$Anim> MORPH_C {
- <Scalar> fps { 24 }
- <V> { ... }
- }
- }
- }
- }
- The <Bundle> entry begins an animation table description. This
- entry must have at least one child: a <Table> named "<skeleton>"
- (this name is a literal keyword and must be present). The children
- of this <Table> entry should be a hierarchy of additional <Table>
- entries, one for each joint in the model. The joint structure and
- names defined by the <Table> hierarchy should exactly match the
- joint structure and names defined by the <Joint> hierarchy in the
- corresponding model.
- Each <Table> that corresponds to a joint should have one child, an
- <Xfm$Anim_S$> entry named "xform" (this name is a literal keyword
- and must be present). Within this entry, there is a series of up to
- twelve <S$Anim> entries, each with a one-letter name like "x", "y",
- or "z", which define the per-frame x, y, z position of the
- corresponding joint. There is one numeric entry for each frame, and
- all frames represent the same length of time. You can also define
- rotation, scale, and shear. See the full description of
- <Xfm$Anim_S$>, above.
- Within a particular animation bundle, all of the various components
- throughout the various <Tables> should define the same number of
- frames, with the exception that if any of them define exactly one
- frame value, that value is understood to be replicated the
- appropriate number of times to match the number of frames defined by
- other components.
- (Note that you may alternatively define an animation table with an
- <Xfm$Anim> entry, which defines all of the individual components in
- one big matrix instead of individually. See the full description
- above.)
- Each joint defines its frame rate independently, with an "fps"
- scalar. This determines the number of frames per second for the
- frame data within this table. Typically, all joints have the same
- frame rate, but it is possible for different joints to animate at
- different speeds.
- Each joint also defines the order in which its components should be
- composed to determine the complete transform matrix, with an "order"
- scalar. This is described in more detail above.
- If any of the vertices in the model have morphs, the top-level
- <Table> should also include a <Table> named "morph" (this name is
- also a literal keyword). This table in turn contains a list of
- <S$Anim> entries, one for each named morph description. Each table
- contains a list of numeric values, one per frame; as with the joint
- data, there should be the same number of numeric values in all
- tables, with the exception that just one value is understood to mean
- hold that value through the entire animation.
- The "morph" table may be omitted if there are no morphs defined in
- the model.
- There should be a separate <Bundle> definition for each different
- animation. The <Bundle> name should match the CHARACTER_NAME used
- for the model, above. Typically each bundle is stored in a separate
- egg file, but it is also possible to store multiple different
- animation bundles within the same egg file. If you do this, you may
- violate the CHARACTER_NAME rule, and give each bundle a different
- name; this will become the name of the animation in the Actor
- interface.
- Although animations and models are typically stored in separate egg
- files, it is possible to store them together in one large egg file.
- The Actor interface will then make available all of the animations
- it finds within the egg file, by bundle name.
|