File formats, specifications and similar¶
The GraphicsEngine¶
The GraphicsEngine is where it all begins. Thereis only one, global, GraphicsEngine in an application, and its job isto keep all of the pointers to your open windows and buffers, andalso to manage the task of doing the rendering, for all of the openwindows and buffers. Panda normally creates a GraphicsEngine for youat startup, which is available as base.graphicsEngine
.There is usually no reason to create a second GraphicsEngine.
Note also that the following interfaces arestrictly for the advanced user. Normally, if you want
to create a new window or an offscreen buffer forrendering, you would just use the
base.openWindow()
or
window.makeTextureBuffer()
interfaces, which handle all of the details foryou automatically.
However, please continue reading if you want tounderstand in detail how Panda manages
windows and buffers, or if you have special needsthat are not addressed by the above
convenience methods.
GraphicsPipe¶
Each application will also need at least oneGraphicsPipe. The GraphicsPipe encapsulates the particular API usedto do rendering. For instance, there is one GraphicsPipe class forOpenGL rendering, and a different GraphicsPipe for DirectX. Althoughit is possible to create a GraphicsPipe of a specific type directly,normally Panda will create a default GraphicsPipe for you at startup,which is available in base.pipe
.
The GraphicsPipe object isn’t often used directly,except to create the individual GraphicsWindow and GraphicsBufferobjects.
GraphicsWindow and GraphicsBuffer¶
The GraphicsWindow class is the class thatrepresents a single onscreen window for rendering. Panda normallyopens a default window for you at startup, which is available inbase.win
. You can create as manyadditional windows as you like. (Note, however, that some graphicsdrivers incur a performance penalty when multiple windows are opensimultaneously.)
Similarly, GraphicsBuffer is the class thatrepresents a hidden, offscreen buffer for rendering special offscreeneffects, such as render-to-texture. It is common for an applicationto have many offscreen buffers open at once.
Both classes inherit from the base classGraphicsOutput, which contains all of the code common to rendering toa window or offscreen buffer.
GraphicsStateGuardian¶
The GraphicsStateGuardian, or GSG for short,represents the actual graphics context. This class manages the actualnuts-and-bolts of drawing to a window; it manages the loading oftextures and vertex buffers into graphics memory, and has thefunctions for actually drawing triangles to the screen. (During theprocess of rendering the frame, the “graphics state”changes several times; the GSG gets its name from the fact that mostof its time is spent managing this graphics state.)
You would normally never call any methods on theGSG directly; Panda handles all of this for you, via theGraphicsEngine. This is important, because in some modes, the GSG mayoperate almost entirely in a separate thread from all of yourapplication code, and it is important not to interrupt that threadwhile it might be in the middle of drawing.
Each GraphicsOutput object keeps a pointer to theGSG that will be used to render that window or buffer. It is possiblefor each GraphicsOutput to have its own GSG, or it is possible toshare the same GSG between multiple different GraphicsOutputs.Normally, it is preferable to share GSG’s, because this tends to bemore efficient for managing graphics resources.
Consider the following diagram to illustrate therelationship between these classes. This shows a typical applicationwith one window and two offscreen buffers:
| | GraphicsPipe | | | ————-: | :————: | ————– | | / | | | \ | | GraphicsOutput | GraphicsOutput | GraphicsOutput | | | | | | | | | GSG | GSG | GSG |
The GraphicsPipe was used to create each of thethree GraphicsOutputs, of which one is a GraphicsWindow, and theremaining two are GraphicsBuffers. Each GraphicsOutput has a pointerto the GSG that will be used for rendering. Finally, theGraphicsEngine is responsible for managing all of these objects.
In the above illustration, each window and bufferhas its own GSG, which is legal, although it’s usually better toshare the same GSG across all open windows and buffers.
Renderinga frame¶
There is one key interface to rendering each frameof the graphics simulation:
base.graphicsEngine.renderFrame()
This method causes all open GraphicsWindows andGraphicsBuffers to render their contents for
the current frame. In order for Panda3D to renderanything, this method must be called once per frame. Normally, thisis done automatically by the task “igloop”, which iscreated when you start
Panda.
Using a GraphicsEngine to create windows and buffers¶
In order to render in Panda3D, you need aGraphicsStateGuardian , and either a GraphicsWindow
(for rendering into a window) or a GraphicsBuffer(for rendering offscreen). You cannot create or destroy these objectsdirectly; instead, you must use interfaces on the GraphicsEngine tocreate them. Before you can create either of the above, you need tohave a GraphicsPipe, which specifies
the particular graphics API you want to use (e.g.OpenGL or DirectX). The default GraphicsPipe
specified in your Config.prc file has already beencreated at startup, and can be accessed by
base.pipe.
Now that you have a GraphicsPipe and aGraphicsEngine, you can create a
GraphicsStateGuardian object. This objectcorresponds to a single graphics context on the
graphics API, e.g. a single OpenGL context. (Thecontext owns all of the OpenGL or DirectX
objects like display lists, vertex buffers, andtexture objects.) You need to have at least one
GraphicsStateGuardian before you can create aGraphicsWindow:
myGsg=base.graphicsEngine.makeGsg(base.pipe)
Now that you have a GraphicsStateGuardian, you canuse it to create an onscreen
GraphicsWindow or an offscreen GraphicsBuffer:
base.graphicsEngine.makeWindow(gsg, name,sort)
base.graphicsEngine.makeBuffer(gsg, name,sort, xSize, ySize, wantTexture)
gsg is the GraphicsStateGuardian, name Is anarbitrary name you want to assign to the window/
buffer, and sort is an integer that determines theorder in which the windows/buffers will be
rendered. The buffer specific arguments xSize andySize decide the dimensions of the buffer, and
wantTexture should be set to True if you want toretrieve a texture from this buffer later on.
You can also use
graphicsEngine.makeParasite(host,name,sort,xSize,ySize)
where host is a GraphicsOutput object. It createsa buffer but it does not allocate room for itself. Instead it rendersto the framebuffer of host. It effectively has wantTexture set toTrue so you can
retrieve a texture from it later on. See TheGraphicsOutput class and Graphics Buffers and Windows
for more information.
myWindow=base.graphicsEngine.makeWindow(myGsg,”HelloWorld”,0)
myBuffer=base.graphicsEngine.makeBuffer(myGsg,”HiWorld”,0,800,600,True)
myParasite=base.graphicsEngine.makeBuffer(myBuffer,”Ima leech”,0,800,600)
Note: if youwant the buffers to be visible add show-buffers true to yourconfiguration file.
This causes the buffers to be opened as windowsinstead, which is useful while debugging.
Sharinggraphics contexts¶
It is possible to share the sameGraphicsStateGuardian among multiple different
GraphicsWindows and/or GraphicsBuffers; if you dothis, then the graphics context will be used
to render into each window one at a time. This isparticularly useful if the different windows
will be rendering many of the same objects, sincethen the same texture objects and vertex
buffers can be shared between different windows.
It is also possible to use a differentGraphicsStateGuardian for each different window. This
means that if a particular texture is to berendered in each window, it will have to be loaded
into graphics memory twice, once in each context,which may be wasteful. However, there are
times when this may be what you want to do, forinstance if you have multiple graphics cards
and you want to to render to both of themsimultaneously. (Note that the actual support for
simultaneously rendering to multiple graphicscards is currently unfinished in Panda at the
time of this writing, but the API has beendesigned with this future path in mind.)
Closingwindows¶
To close a specific window or buffer you useremoveWindow(window). To close all windows
removeAllWindows()
base.graphicsEngine.removeWindow(myWindow)
base.graphicsEngine.removeAllWindows()
More about GraphicsEngine
Here is some other useful functionality of theGraphicsEngine class.
GetNumWindows() Returns the number of windows andbuffers that this GraphicsEngine
object is managing. IsEmpty() Returns True if thisGraphicsEngine is not managing any windows or buffers. See API foradvanced functionality of GraphicsEngine and GraphicsStateGuardianclass.
ppython¶
ppython.exe is used for startingPanda3D. Basicly it is only duplicated copy of python.exe renamed soyou don’t mix Panda’s python with other python on your PATH
Panda Audio Documenation¶
AudioManagerand AudioSound¶
The AudioManager is a combination of a file cacheand a category
of sounds (e.g. sound effects, battle sounds, ormusic).
The first step is to decide which AudioManager touse and load it.
Once you have an AudioManager (e.g.effectsManager), a call to
get_sound(
(e.g. mySound = effectsManager.getSound(“bang”)).
After getting a sound from an AudioManager, youcan tell the sound
change its volume, loop, start time, play, stop,etc. There is no
need to involve the AudioManager explicitly inthese operations.
Simply delete the sound when you’re done with it. (The AudioSound
knows which AudioManager it is associated with,and will do the right
thing).
The audio system, provides an API for the rest ofPanda; and leaves a
lot of leaway to the low level sound system. Thisis good and bad.
On the good side: it’s easier to understand, andit allows for widely
varrying low level systems. On the bad side: itmay be harder to keep
the behavior consistent accross implementations(please try to keep
them consistent, when adding an implementation).
ExampleUsage¶
PythonExample:
effects=AudioManager.createAudioManager()
music=AudioManager.createAudioManager()
bang=effects.load(“bang”)
background=music.load(“background_music”)
background.play()
bang.play()
C++Example:
AudioManagereffects=AudioManager::create_AudioManager();
AudioManagermusic=AudioManager::create_AudioManager();
bang=effects.get_sound(“bang”);
background=music.get_sound(“background_music”);
background.play();
bang.play();
Codingstyle¶
Almostany programming language gives a considerable amount of freedom
tothe programmer in style conventions. Most programmers eventually
developa personal style and use it as they develop code.
Whenmultiple programmers are working together on one project, this
canlead to multiple competing styles appearing throughout the code.
Thisis not the end of the world, but it does tend to make the code
moredifficult to read and maintain if common style conventions are
notfollowed throughout.
Itis much better if all programmers can agree to use the same style
whenworking together on the same body of work. It makes reading,
understanding,and extending the existing code much easier and faster
foreveryone involved. This is akin to all of the animators on a
featurefilm training themselves to draw in one consistent style
throughoutthe film.
Often,there is no strong reason to prefer one style over another,
exceptthat at the end of the day just one must be chosen.
Thefollowing lays out the conventions that we have agreed to use
withinPanda. Most of these conventions originated from an
amalgamationof the different styles of the first three programmers to
domajor development in Panda. The decisions were often arbitrary,
andsome may object to the particular choices that were made.
Althoughdiscussions about the ideal style for future work are still
welcome,considerable code has already been written using these
existingconventions, and the most important goal of this effort is
consistency. Thus, changing the style at this point would require
changingall of the existing code as well.
Notethat not all existing Panda code follows these conventions. This
isunfortunate, but it in no way constitutes an argument in favor of
abandoningthe conventions. Rather, it means we should make an effort
tobring the older code into compliance as we have the opportunity.
Naturally,these conventions only apply to C and C++ code; a
completelydifferent set of conventions has been established for
Pythoncode for the project, and those conventions will not be
discussedhere.
SPACING:
Notab characters should ever appear in a C++ file; we use only space
charactersto achieve the appropriate indentation. Most editors can
beconfigured to use spaces instead of tabs.
Weuse two-character indentation. That is, each nested level of
indentationis two characters further to the right than the enclosing
level.
Spacesshould generally surround operators, e.g. i + 1 instead of i+1.
Spacesfollow commas in a parameter list, and semicolons in a for
statement. Spaces are not placed immediately within parentheses;
e.g.foo(a, b) rather than foo( a,b ).
Resistwriting lines of code that extend beyond 80 columns; instead,
folda long line when possible. Occasionally a line cannot be easily
foldedand remain readable, so this should be taken as more of a
suggestionthan a fixed rule, but most lines can easily be made to fit
within80 columns.
Commentsshould never extend beyond 80 columns, especially sentence or
paragraphcomments that appear on a line or lines by themselves.
Theseshould generally be wordwrapped within 72 columns. Any smart
editorcan do this easily.
CURLYBRACES:
Ingeneral, the opening curly brace for a block of text trails the
linethat introduces it, and the matching curly brace is on a line by
itself,lined up with the start of the introducing line, e.g.:
for(inti=0;i<10;i++){
...
}
Commandslike if, while, and for should always use curly braces, even
ifthey only enclose one command. That is, do this:
if(foo){
bar();
}
insteadof this:
if(foo)
bar();
NAMING:
Classnames are mixed case with an initial capital, e.g. MyNewClass.
Eachdifferent class (except nested classes, of course) is defined in
itsown header file named the same as the class itself, but with the
firstletter lowercase, e.g. myNewClass.h.
Typedefnames and other type names follow the same convention as class
names:mixed case with an initial capital. These need not be defined
intheir own header file, but usually typedef names will be scoped
withinsome enclosing class.
Localvariable names are lowercase with an underscore delimiting
words:my_value. Class data members, including static data members,
arethe same, but with a leading underscore: _my_data_member. We do
notuse Hungarian notation.
Classmethod names, as well as standalone function names, are
lowercasewith a delimiting underscore, just like local variable
names:my_function().
LANGUAGECONSTRUCTS:
PreferC++ constructs over equivalent C constructs when writing C++
code. For instance, use:
staticconstintbuffer_size=1024;
insteadof:
#defineBUFFER_SIZE1024
Resistusing brand-new C++ features that are not broadly supported by
compilers. One of our goals in Panda is ease of distribution to a
widerange of platforms; this goal is thwarted if only a few compilers
maybe used.
Moreexamples of the agreed coding style may be found in
panda/src/doc/sampleClass.* fileshould be also in appendix of this manual.
COLLISIONFLAGS¶
floor:for things that avatars can stand on
barrier:for things that avatars should collide against that are not floors
camera-collide:for things that the camera should avoid
trigger:for things (usually not barriers or floors) that should trigger an
eventwhen avatars intersect with them
sphere:for things that should have a collision sphere around them
tube:for things that should have a collision tube (cylinder) around them
NOTES
Thebarrier & camera-collide flags are typically used together.
Currently,the camera automatically pulls itself in front of anything
markedwith the camera-collide flag, so that the view of the avatar isn’t
blocked.
Thetrigger flag implies that avatars will not collide with the object;
theycan move freely through it.
Thesphere & tube flags create a collision object that is as small as
possiblewhile completely containing the original flagged geometry.
eggpalettize¶
HOWTO USE EGG_PALETTIZE¶
Theprogram egg-palettize is used when building models to optimize
textureusage on all models before loading them into the show. It is
capableof collecting together several different small texture images
fromdifferent models and assembling them together onto the same image
file,potentially reducing the total number of different texture
imagesthat must be loaded and displayed at runtime from several
thousandto several hundred or fewer.
Italso can be used to group together related textures that will be
renderedat the same time (for instance, textures related to one
neighborhood),and if nothing else, it can resize textures at build
timeso that they may be painted at any arbitrary resolution according
tothe artist’s convenience, and then reduced to a suitable size for
texturememory management (and to meet hardware requirements of having
dimensionsthat are always a power of two).
Itis suggested that textures always be painted at high resolution and
reducedusing egg-palettize, since this allows the show designer the
greatestflexibility; if a decision is later made to increase the
resolutionof a texture, this may be done by changing an option with
egg-palettize,and does not require intervention of the artist.
Thebehavior of egg-palettize is largely controlled through a source
filecalled textures.txa, which is usually found in the src/maps
directorywithin the model tree. For a complete description of the
syntaxof the textures.txa file, invoke the command egg-palettize -H.
GROUPINGEGG FILES¶
Muchof the contents of textures.txa involves assigning egg files to
variousgroups; assigning two egg files to the same group indicates
thatthey are associated in some way, and their texture images may be
copiedtogether into the same palettes.
Thegroups are arbitrary and should be defined at the beginning of the
eggfile with the syntax:
:groupgroupname
Wheregroupname is the name of the group. It is also possible to
assigna directory name to a group. This is optional, but if done, it
indicatesthat all of the textures for this group should be installed
withinthe named subdirectory. The syntax is:
:groupgroupname dir dirname
Wheredirname is the name of the subdirectory. If you are
generatinga phased download, the dirname should be one of phase_1,
phase_2,etc., corresponding to the PHASE variable in the install_egg
rule(see ppremake-models.txt).
Finally,it is possible to relate the different groups to each other
hierachically. Doing this allows egg-palettize to assign textures to
theminimal common subset between egg files that share the textures.
Forinstance, if group beta and group gamma both depend on group
alpha,a texture that is assigned to both groups beta and gamma can
actuallybe placed on group alpha, to maximize sharing and minimize
duplicationof palette space.
Yourelate two groups with the syntax:
:groupgroupname with basegroupname
Onceall the groups are defined, you can assign egg files to the
variousgroups with a syntax like this:
model.egg: groupname
wheremodel.egg is the name of some egg model file built within the
tree. You can explicitly group each egg file in this way, or you can
usewildcards to group several at once, e.g.:
dog*.egg: dogs
Assigningan egg file to a group assigns all of the textures used by
thategg file to that same group. If no other egg files reference the
sametextures, those textures will be placed in one or more palette
imagesnamed after the group. If another egg file in a different
groupalso references the textures, they will be assigned to the
lowestgroup that both groups have in common (see relating the groups
hierarchically,above), or copied into both palette images if the two
groupshaving nothing in common.
CONTROLLINGTEXTURE PARAMETERS¶
Mostof the contents of the textures.txa is usually devoted to scaling
thetexture images appropriately. This is usually done with a line
somethinglike this:
texture.rgb: 64 64
wheretexture.rgb is the name of some texture image, and 64 64 is the
sizein pixels it should be scaled to. It is also possible to specify
thetarget size as a factor of the source size, e.g.:
bigtexture.rgb: 50%
specifiesthat the indicated texture should be scaled to 50% in each
dimension(for a total reduction to 0.5 * 0.5 = 25% of the original
area).
Asabove, you may group together multiple textures on the same line
usingwildcards, e.g.:
wall*.rgb: 25%
Finally,you may include one or more optional keywords on the end of
thetexture scaling line that indicate additional properties to apply
tothe named textures. See egg-palettize -H for a complete list.
Someof the more common keywords are:
mipmap- Enables mipmaps for the texture.
linear- Disables mipmaps for the texture.
omit- Omits the texture from any palettes. The texture will still
bescaled and installed, but it will not be combined with other
textures. Normally you need to do this only when the texture will
beapplied to some geometry at runtime. (Since palettizing a
texturerequires adjusting the UV’s of all the geometry that
referencesit, a texture that is applied to geometry at runtime
cannotbe palettized.)
RUNNINGEGG-PALETTIZE¶
Normally,egg-palettize is run automatically just by typing:
makeinstall
inthe model tree. It automatically reads the textures.txa file and
generatesand installs the appropriate palette image files, as part of
thewhole build process, and requires no further intervention from the
user. See ppremake-models.txt for more information on setting up the
modeltree.
Whenegg-palettize runs in the normal mode, it generates suboptimal
palettes. Sometimes, for instance, a palette image is created with
onlyone small texture in the corner, and the rest of it unused. This
happensbecause egg-palettize is reserving space for future textures,
andis ideal for development; but it is not suitable for shipping a
finishedproduct. When you are ready to repack all of the palettes as
optimallyas possible, run the command:
makeopt-pal
Thiscauses egg-palettize to reorganize all of the palette images to
makethe best usage of texture memory. It will force a regeneration
ofmost of the egg files in the model tree, so it can be a fairly
involvedoperation.
Itis sometimes useful to analyze the results of egg-palettize. You
cantype:
makepi >pi.txt
towrite a detailed report of every egg file, texture image, and
generatedpalette image to the file pi.txt.
Finally,the command:
makepal-stats >stats.txt
willwrite a report to stats.txt of the estimated texture memory usage
forall textures, broken down by group.
WHENTHINGS GO WRONG¶
Thewhole palettizing process is fairly complex; it’s necessary for
egg-palettizeto keep a record of the complete state of all egg files
andall textures ever built in a particular model tree. It generally
doesa good job of figuring out when things change and correctly
regeneratingthe necessary egg files and textures when needed, but
sometimesit gets confused.
Thisis particularly likely to happen when you have reassigned some
eggfiles from one group to another, or redefined the relationship
betweendifferent groups. Sometimes egg-palettize appears to run
correctly,but does not generate correct palettes. Other times
egg-palettizewill fail with an assertion failure, or even a segment
fault(general protection fault) when running egg-palettize, due to
thiskind of confusion. This behavior should not happen, but it does
happenevery once and a while.
Whenthis sort of thing happens, often the best thing to do is to
invokethe command:
makeundo-pal
followedby:
makeinstall
Thisremoves all of the old palettization information, including the
stateinformation cached from previous runs, and rebuilds a new set of
palettesfrom scratch. It is a fairly heavy hammer, and may take some
timeto complete, depending on the size of your model tree, but it
almostalways clears up any problems related to egg-palettize.
THEPHILOSOPHY OF EGG FILES¶
THEPHILOSOPHY OF EGG FILES (vs. bam files)
Eggfiles are used by Panda3D to describe many properties of a scene:
simplegeometry, including special effects and collision surfaces,
charactersincluding skeletons, morphs, and multiple-joint
assignments,and character animation tables.
Eggfiles are designed to be the lingua franca of model manipulation
forPanda tools. A number of utilities are provided that read and
writeegg files, for instance to convert to or from some other
modelingformat, or to apply a transform or optimize vertices. The
eggfile philosophy is to describe objects in an abstract way that
facilitateseasy manipulation; thus, the format doesn’t (usually)
includeinformation such as polygon connectivity or triangle meshes.
Eggfiles are furthermore designed to be human-readable to help a
developerdiagnose (and sometimes repair) problems. Also, the egg
syntaxis always intended to be backward compatible with previous
versions,so that as the egg syntax is extended, old egg files will
continueto remain valid.
Thisis a different philosophy than Panda’s bam file format, which is
abinary representation of a model and/or animation that is designed
tobe loaded quickly and efficiently, and is strictly tied to a
particularversion of Panda. The data in a bam file closely mirrors
theactual Panda structures that are used for rendering. Although an
effortis made to keep bam files backward compatible, occasionally
thisis not possible and we must introduce a new bam file major
version.
Whereegg files are used for model conversion and manipulation of
models,bam files are strictly used for loading models into Panda.
Althoughyou can load an egg file directly, a bam file will be loaded
muchmore quickly.
Eggfiles might be generated by outside sources, and thus it makes
senseto document its syntax here. Bam files, on the other hand,
shouldonly be generated by Panda3D, usually by the program egg2bam.
Theexact specification of the bam file format, if you should need it,
isdocumented within the Panda3D code itself.
GENERALEGG SYNTAX¶
Eggfiles consist of a series of sequential and hierarchically-nested
entries. In general, the syntax of each entry is:
<Entry-type>name{contents}
Wherethe name is optional (and in many cases, ignored anyway) and the
syntaxof the contents is determined by the entry-type. The name (and
stringsin general) may be either quoted with double quotes or
unquoted. Newlines are treated like any other whitespace, and case is
notsignificant. The angle brackets are literally a part of the entry
keyword. (Square brackets and ellipses in this document are used to
indicateoptional pieces, and are not literally part of the syntax.)
Thename field is always syntactically allowed between an entry
keywordand its opening brace, even if it will be ignored. In the
syntaxlines given below, the name is not shown if it will be ignored.
Commentsmay be delimited using either the C++-style // ... or the
C-style/* ... */. C comments do not nest. There is also a
entrytype, of the form:
writeegg files will preserve the text within
theymay not preserve comments delimited by // or /* */. Special
charactersand keywords within a
it’ssafest to quote the entire comment.
LOCALINFORMATION ENTRIES¶
Thesenodes contain information relevant to the current level of
nestingonly.
<Char*>name{value}
Scalarscan appear in various contexts. They are always optional,
andspecify some attribute value relevant to the current context.
Thescalar name is the name of the attribute; different attribute
namesare meaningful in different contexts. The value is either a
numericor a (quoted or unquoted) string value; the interpretation
asa number or as a string depends on the nature of the named
attribute. Because of a syntactic accident with the way the egg
syntaxevolved,
canrepresent either a string or a number. <Char*> is being phased
out;it is suggested that new egg files use only
GLOBALINFORMATION ENTRIES¶
Thesenodes contain information relevant to the file as a whole. They
canbe nested along with geometry nodes, but this nesting is
irrelevantand the only significant placement rule is that they should
appearbefore they are referenced.
Thisentry indicates the coordinate system used in the egg file; the
eggloader will automatically make a conversion if necessary. The
followingstrings 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
isthe same as Z-up-right.)
Byconvention, this entry should only appear at the beginning of the
file,although it is technically allowed anywhere. It is an error
toinclude more than one coordinate system entry in the same file.
Ifit is omitted, Y-up is assumed.
Thisdescribes a texture file that can be referenced later with
eachtexture to be used; a texture may also be referenced directly
bythe geometry via an abbreviated inline
separate
thanthe default texture attributes.
Ifthe filename is a relative path, the current egg file’s directory
issearched first, and then the texture-path and model-path are
searched.
Thefollowing attributes are presently implemented for textures:
Ifthis scalar is present, the texture file’s alpha channel is
readin from the named image file (which should contain a
grayscaleimage), and the two images are combined into a single
two-or four-channel image internally. This is useful for loading
alphachannels along with image file formats like JPEG that don’t
traditionallysupport alpha channels.
Thisdefines the channel that should be extracted from the file
namedby alpha-file to determine the alpha channel for the
resultingchannel. The default is 0, which means the grayscale
combinationof r, g, b. Otherwise, this should be the 1-based
channelnumber, for instance 1, 2, or 3 for r, g, or b,
respectively,or 4 for the alpha channel of a four-component
image.
Thisdefines the load format of the image file. The
format-definitionis one of:
RGBA,RGBM, RGBA12, RGBA8, RGBA4,
RGB,RGB12, RGB8, RGB5, RGB332,
LUMINANCE_ALPHA,
RED,GREEN, BLUE, ALPHA, LUMINANCE
Theformats whose names end in digits specifically request a
particulartexel width. RGB12 and RGBA12 specify 48-bit texels
withor without alpha; RGB8 and RGBA8 specify 32-bit texels, and
RGB5and RGBA4 specify 16-bit texels. RGB332 specifies 8-bit
texels.
Theremaining formats are generic and specify only the semantic
meaningof the channels. The size of the texels is determined by
thewidth of the components in the image file. RGBA is the most
general;RGB is the same, but without any alpha channel. RGBM is
likeRGBA, except that it requests only one bit of alpha, if the
graphicscard can provide that, to leave more room for the RGB
components,which is especially important for older 16-bit
graphicscards (the “M” stands for “mask”, as in acutout).
Thenumber of components of the image file should match the format
specified;if it does not, the egg loader will attempt to provide
theclosest match that does.
Definesan explicit control over the real-time compression mode
appliedto the texture. The various options are:
DEFAULTOFF ON
FXT1DXT1 DXT2 DXT3 DXT4 DXT5
Thiscontrols the compression of the texture when it is loaded
intographics memory, and has nothing to do with on-disk
compressionsuch as JPEG. If this option is omitted or “DEFAULT”,
thenthe texture compression is controlled by the
compressed-texturesconfig variable. If it is “OFF”, texture
compressionis explicitly off for this texture regardless of the
settingof the config variable; if it is “ON”, texture compression
isexplicitly on, and a default compression algorithm supported by
thedriver is selected. If any of the other options, it names the
specificcompression algorithm to be used.
Thisdefines the behavior of the texture image outside of the
normal(u,v) range 0.0 - 1.0. It is “REPEAT” to repeat the
textureto infinity, “CLAMP” not to. The wrapping behavior may be
specifiedindependently for each axis via “wrapu” and “wrapv”,or
itmay be specified for both simultaneously via “wrap”.
Althoughless often used, for 3-d textures wrapw may also be
specified,and it behaves similarly to wrapu and wrapv.
Thereare other legal values in addtional to REPEAT and CLAMP.
Thefull list is:
CLAMP
REPEAT
MIRROR
MIRROR_ONCE
BORDER_COLOR
Thesedefine the “border color” of the texture, which is
particularlyimportant when one of the wrap modes, above, is
BORDER_COLOR.
Thismay be one of the following attributes:
1D
2D
3D
CUBE_MAP
Thedefault is “2D”, which specifies a normal, 2-d texture. If
anyof the other types is specified instead, a texture image of
thecorresponding type is loaded.
If3D or CUBE_MAP is specified, then a series of texture images
mustbe loaded to make up the complete texture; in this case, the
texturefilename is expected to include a sequence of one or more
hashmark (“#”) characters, which will be filled in with the
sequencenumber. The first image in the sequence must be numbered
0,and there must be no gaps in the sequence. In this case, a
separatealpha-file designation is ignored; the alpha channel, if
present,must be included in the same image with the color
channel(s).
Ifthis flag is nonzero, the texture is loaded as a multiview
texture. In this case, the filename must contain a hash mark
(“#”)as in the 3D or CUBE_MAP case, above, and the different
imagesare loaded into the different views of the multiview
textures. If the texture is already a cube map texture, the
samehash sequence is used for both purposes: the first six images
definethe first view, the next six images define the second view,
andso on. If the texture is a 3-D texture, you must also specify
num-views,below, to tell the loader how many images are loaded
forviews, and how many are loaded for levels.
Amultiview texture is most often used to load stereo textures,
wherea different image is presented to each eye viewing the
texture,but other uses are possible, such as for texture
animation.
Thisis used only when loading a 3-D multiview texture. It
specifieshow many different views the texture holds; the z height
ofthe texture is then implicitly determined as (number of images)
/(number of views).
Ifthis flag is nonzero, then pre-generated mipmap levels will be
loadedalong with the texture. In this case, the filename should
containa sequence of one or more hash mark (“#”) characters,
whichwill be filled in with the mipmap level number; the texture
filenamethus determines a series of images, one for each mipmap
level. The base texture image is mipmap level 0.
Ifthis flag is specified in conjunction with a 3D or cube map
texture(as specified above), then the filename should contain two
hashmark sequences, separated by a character such as an
underscore,hyphen, or dot. The first sequence will be filled in
withthe mipmap level index, and the second sequence will be
filledin with the 3D sequence or cube map face.
Thisspecifies 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
Thereare also some additional filter types that are supported for
historicalreasons, but each of those additional types maps to one
ofthe above. New egg files should use only the above filter
types.
Enablesanisotropic filtering for the texture, and specifies the
degreeof filtering. If the degree is 0 or 1, anisotropic
filteringis disabled. The default is disabled.
Thisspecifies the type of texture environment to create; i.e. it
controlsthe way in which textures apply to models.
Environment-typemay be one of:
MODULATE
DECAL
BLEND
REPLACE
ADD
BLEND_COLOR_SCALE
MODULATE_GLOW
MODULATE_GLOSS
*NORMAL
*NORMAL_HEIGHT
*GLOW
*GLOSS
*HEIGHT
*SELECTOR
Thedefault environment type is MODULATE, which means the texture
coloris multiplied with the base polygon (or vertex) color. This
isthe most common texture environment by far. Other environment
typesare more esoteric and are especially useful in the presence
ofmultitexture. In particular, the types prefixed by an asterisk
(*)require enabling Panda’s automatic ShaderGenerator.
Theseoptions replace the envtype and specify the texture combiner
mode,which is usually used for multitexturing. This specifies
howthe texture combines with the base color and/or the other
texturesapplied previously. You must specify both an rgb and an
alphacombine mode. Some combine-modes use one source/operand
pair,and some use all three; most use just two.
combine-modemay be one of:
REPLACE
MODULATE
ADD
ADD-SIGNED
INTERPOLATE
SUBTRACT
DOT3-RGB
DOT3-RGBA
combine-sourcemay be one of:
TEXTURE
CONSTANT
PRIMARY-COLOR
PREVIOUS
CONSTANT_COLOR_SCALE
LAST_SAVED_RESULT
combine-operandmay be one of:
SRC-COLOR
ONE-MINUS-SRC-COLOR
SRC-ALPHA
ONE-MINUS-SRC-ALPHA
Thedefault values if any of these are omitted are:
Ifflag is nonzero, then it indicates that this particular texture
stagewill be supplied as the “last_saved_result” source for any
futuretexture stages.
Thisspecifies that texture coordinates for the primitives that
referencethis texture should be dynamically computed at runtime,
forinstance to apply a reflection map or some other effect. The
validvalues 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
Specifiesthe name of the TextureStage object that is created to
renderthis texture. If this is omitted, a custom TextureStage is
createdfor this texture if it is required (e.g. because some
othermultitexturing parameter has been specified), or the system
defaultTextureStage is used if multitexturing is not required.
Specifiesan integer sort value to rank this texture in priority
amongother textures that are applied to the same geometry. This
isonly used to eliminate low-priority textures in case more
texturesare requested for a particular piece of geometry than the
graphicshardware can render.
Specifiesa four-component color that is applied with the color in
casethe envtype, above, is “blend”, or one of thecombine-sources
is”constant”.
Specifiesthe name of the texture coordinates that are to be
associatedwith this texture. If this is omitted, the default
texturecoordinates are used.
Specifiesan additional scale factor that will scale the r, g, b
(ora) components after the texture has been applied. This is
onlyused when a combine mode is in effect. The only legal values
are1, 2, or 4.
Thisspecifies whether and what type of transparency will be
performed. Alpha-type may be one of:
OFF
ON
BLEND
BLEND_NO_OCCLUDE
MS
MS_MASK
BINARY
DUAL
Ifalpha-type is OFF, it means not to enable transparency, even if
theimage contains an alpha channel or the format is RGBA. If
alpha-typeis ON, it means to enable the default transparency,
evenif the image filename does not contain an alpha channel. If
alpha-typeis any of the other options, it specifies the type of
transparencyto be enabled.
Thisspecifies the bin name order of all polygons with this
textureapplied, in the absence of a bin name specified on the
polygonitself. See the description for bin under polygon
attributes.
Thisspecifies the fixed drawing order of all polygons with this
textureapplied, in the absence of a drawing order specified on
thepolygon itself. See the description for draw-order under
polygonattributes.
Specifiesspecial depth buffer properties of all polygons with this
textureapplied. See the descriptions for the individual
attributesunder polygon attributes.
Setsa hint to the renderer about the desired performance /
qualitytradeoff for this particular texture. This is most useful
forthe tinydisplay software renderer; for normal,
hardware-acceleratedrenderers, this may have little or no effect.
Thismay be one of:
DEFAULT
FASTEST
NORMAL
BEST
“Default”means to use whatever quality level is specified by the
globaltexture-quality-level config variable.
Thisspecifies a 2-d or 3-d transformation that is applied to the
UV’sof a surface to generate the texture coordinates.
Thetransform syntax is similar to that for groups, except it may
defineeither a 2-d 3x3 matrix or a 3-d 4x4 matrix. (You should
usethe two-dimensional forms if the UV’s are two-dimensional, and
thethree-dimensional forms if the UV’s are three-dimensional.)
Atwo-dimensional transform may be any sequence of zero or more of
thefollowing. Transformations are post multiplied in the order
theyare encountered to produce a net transformation matrix.
Rotationsare counterclockwise about the origin in degrees.
Matrices,when specified explicitly, are row-major.
0001 02
1011 12
2021 22
}
Athree-dimensional transform may be any sequence of zero or more
ofthe following. See the description under
moreinformation.
0001 02 03
1011 12 13
2021 22 23
3031 32 33
}
Thisdefines a set of material attributes that may later be
referencedwith
Thefollowing attributes may appear within the material block:
Theseproperties collectively define a “material” that controlsthe
lightingeffects that are applied to a surface; a material is only
ineffect in the presence of lighting.
Thefour 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
materialcolor.
Theshininess property controls the size of the specular highlight,
andthe value ranges from 0 to 128. A larger value creates a
smallerhighlight (creating the appearance of a shinier surface).
Avertex pool is a set of vertices. All geometry is created by
referringto vertices by number in a particular vertex pool. There
maybe one or several vertex pools in an egg file, but all vertices
thatmake up a single polygon must come from the same vertex pool.
Thebody of a
A
Thenumber is the index by which this vertex will be referenced.
Itis optional; if it is omitted, the vertices are implicitly
numberedconsecutively beginning at one. If the number is
supplied,the vertices need not be consecutive.
Normally,vertices are three-dimensional (with coordinates x, y,
andz); however, in certain cases vertices may have fewer or more
dimensions,up to four. This is particularly true of vertices
usedas control vertices of NURBS curves and surfaces. If more
coordinatesare supplied than needed, the extra coordinates are
ignored;if fewer are supplied than needed, the missing
coordinatesare assumed to be 0.
Thevertex’s coordinates are always given in world space,
regardlessof any transforms before the vertex pool or before the
referencinggeometry. If the vertex is referenced by geometry
undera transform, the egg loader will do an inverse transform to
movethe vertex into the proper coordinate space without changing
itsposition in world space. One exception is geometry under an
thespace of the
Inneither case does it make a difference whether the vertex pool
isitself declared under a transform or an
onlydeciding factor is whether the geometry that uses the
vertexpool appears under an
asingle vertex to be interpreted in different coordinate spaces
bydifferent polygons.
Whileeach vertex must at least have a position, it may also have
acolor, normal, pair of UV coordinates, and/or a set of morph
offsets. Furthermore, the color, normal, and UV coordinates may
themselveshave morph offsets. Thus, the [attributes] in the
syntaxline above may be replaced with zero or more of the
followingentries:
Thisspecifies the offset of this vertex for the named morph
target. See the “MORPH DESCRIPTION ENTRIES” header, below.
Thisspecifies the surface normal of the vertex. If omitted, the
vertexwill have no normal. Normals may also be morphed;
morph-listhere is thus an optional list of
similarto the above.
Thisspecifies the four-valued color of the vertex. Each
componentis in the range 0.0 to 1.0. A vertex color, if
specifiedfor all vertices of the polygon, overrides the polygon’s
color. If neither color is given, the default is white
(11 1 1). The morph-list is an optional list of
Thisgives the texture coordinates of the vertex. This must be
specifiedif a texture is to be mapped onto this geometry.
Thetexture coordinates are usually two-dimensional, with two
componentvalues (u v), but they may also be three-dimensional,
withthree component values (u v w). (Arguably, it should be
called
it’snot.)
Asbefore, morph-list is an optional list of
Unlikethe other kinds of attributes, there may be multiple sets
ofUV’s on each vertex, each with a unique name; this provides
supportfor multitexturing. The name may be omitted to specify
thedefault UV’s.
TheUV’s also support an optional tangent and binormal. These
valuesare based on the vertex normal and the UV coordinates of
connectedvertices, and are used to render normal maps and similar
lightingeffects. They are defined within the
theremay be a different set of tangents and binormals for each
differentUV coordinate set. If present, they have the expected
syntax:
Thisspecifies some named per-vertex auxiliary data which is
importedfrom the egg file without further interpretation by
Panda. The auxiliary data is copied to the vertex data under a
columnwith the specified name. Presumably the data will have
meaningto custom code or a custom shader. Like named UV’s, there
maybe multiple Aux entries for a given vertex, each with a
differentname.
Adynamic vertex pool is similar to a vertex pool in most respects,
exceptthat each vertex might be animated by substituting in values
froma
dynamicvertex pool are always given in local coordinates, instead
ofworld coordinates.
Thepresence of a dynamic vertex pool makes sense only within a
charactermodel, and a single dynamic vertex pool may not span
multiplecharacters. Each dynamic vertex pool creates a DynVerts
objectwithin the character by the same name; this name is used
laterwhen matching up the corresponding
Atthe present time, the DynamicVertexPool is not implemented in
Panda3D.
GEOMETRYENTRIES¶
[attributes]
indices
}
}
Apolygon consists of a sequence of vertices from a single vertex
pool. Vertices are identified by pool-name and index number within
thepool; indices is a list of vertex numbers within the given
vertexpool. Vertices are listed in counterclockwise order.
Althoughthe vertices must all come from the same vertex pool, they
mayhave been assigned to arbitrarily many different joints
regardlessof joint connectivity (there is no “straddle-polygon”
limitation). See Joints, below.
Thepolygon syntax is quite verbose, and there isn’t any way to
specifya set of attributes that applies to a group of polygons–the
attributeslist must be repeated for each polygon. This is why egg
filestend to be very large.
Thefollowing attributes may be specified for polygons:
Thisrefers to a named
thegiven texture to the polygon. This requires that all the
polygon’svertices have been assigned texture coordinates.
Thisattribute may be repeated multiple times to specify
multitexture. In this case, each named texture is applied to the
polygon,in the order specified.
Thisis another way to apply a texture to a polygon. The
referringto a
specifytexture attributes given this form.
There’sno advantage to this syntax for texture mapping. It’s
supportedonly because it’s required by some older egg files.
Thisapplies the material properties defined in the earlier
Thisdefines a polygon surface normal. The polygon normal will be
usedunless all vertices also have a normal. If no normal is
defined,none will be supplied. The polygon normal, like the
vertexnormal, may be morphed by specifying a series of
entries.
Thepolygon normal is used only for lighting and environment
mappingcalculations, and is not related to the implicit normal
calculatedfor CollisionPolygons.
Thisdefines the polygon’s color, which will be used unless all
verticesalso have a color. If no color is defined, the default
iswhite (1 1 1 1). The color may be morphed with a series of
Thisdefines 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
disablesbackface culling for this particular polygon and allows
itto be viewed from either side.
Itis sometimes important to control the order in which objects
arerendered, particularly when transparency is in use. In Panda,
thisis achieved via the use of named bins and, within certain
kindsof bins, sometimes an explicit draw-order is also used (see
below).
Inthe normal (state-sorting) mode, Panda renders its geometry by
firstgrouping into one or more named bins, and then rendering the
binsin a specified order. The programmer is free to define any
numberof bins, named whatever he/she desires.
Thisscalar specifies which bin this particular polygon is to be
renderedwithin. If no bin scalar is given, or if the name given
doesnot match any of the known bins, the polygon will be assigned
tothe default bin, which renders all opaque geometry sorted by
state,followed by all transparent geometry sorted back-to-front.
Seealso draw-order, below.
Thisworks in conjunction with bin, above, to further refine the
orderin which this polygon is drawn, relative to other geometry
inthe same bin. If (and only if) the bin type named in the bin
scalaris a CullBinFixed, this draw-order is used to define the
fixedorder that all geometry in the same will be rendered, from
smallernumbers to larger numbers.
Ifthe draw-order scalar is specified but no bin scalar is
specified,the default is a bin named “fixed”, which is a
CullBinFixedobject that always exists by default.
Specifiesa special depth offset to be applied to the polygon.
Thismust be an integer value between 0 and 16 or so. The default
valueis 0; values larger than 0 will cause the polygon to appear
closerto the camera for purposes of evaluating the depth buffer.
Thiscan be a simple way to resolve Z-fighting between coplanar
polygons:with two or more coplanar polygons, the polygon with the
highestdepth-offset value will appear to be visible on top. Note
thatthis effect doesn’t necessarily work well when the polygons
areviewed from a steep angle.
Specifiesthe mode for writing to the depth buffer. This may be
ONor OFF. The default is ON.
Specifiesthe mode for testing against the depth buffer. This may
beON or OFF. The default is ON.
Ifthe visibility of a primitive is set to “hidden”, theprimitive
isnot generated as a normally visible primitive. If the
Config.prcvariable egg-suppress-hidden is set to true, the
primitiveis not converted at all; otherwise, it is converted as a
“stashed”node.
This,like the other rendering flags alpha, draw-order, and bin,
maybe specified at the group level, within the primitive level,
oreven within a texture.
[attributes]
indices
}
}
Apatch is similar to a polygon, but it is a special primitive that
canonly be rendered with the use of a tessellation shader. Each
patchconsists of an arbitrary number of vertices; all patches with
thesame number of vertices are collected together into the same
GeomPatchesobject to be delivered to the shader in a single batch.
Itis then up to the shader to create the correct set of triangles
fromthe patch data.
Allof the attributes that are valid for Polygon, above, may also be
specifiedfor Patch.
[attributes]
indices
}
}
APointLight is a set of single points. One point is drawn for each
vertexlisted in the
bespecified for PointLights, as well as draw-order, plus one
additionalattribute valid only for PointLights and Lines:
Thisspecifies the size of the PointLight (or the width of a
line),in pixels, when it is rendered. This may be a
floating-pointnumber, but the fractional part is meaningful only
whenantialiasing is in effect. The default is 1.0.
Ifthis is specified, then the thickness, above, is to interpreted
asa size in 3-d spatial units, rather than a size in pixels, and
thepoint should be scaled according to its distance from the
viewernormally.
[attributes]
indices
}
[componentattributes]
}
ALine is a connected set of line segments. The listed N vertices
definea series of N-1 line segments, drawn between vertex 0 and
vertex1, 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
theend. 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
madeup of multiple line segments, it may contain a number of
linesegment, as in TriangleStrip, below.
[attributes]
indices
}
[componentattributes]
}
Atriangle strip is only rarely encountered in an egg file; it is
normallygenerated automatically only during load time, when
connectedtriangles are automatically meshed for loading, and even
thenit exists only momentarily. Since a triangle strip is a
renderingoptimization only and adds no useful scene information
overa loose collection of triangles, its usage is contrary to the
generalegg philosophy of representing a scene in the abstract.
Nevertheless,the syntax exists, primarily to allow inspection of
themeshing results when needed. You can also add custom
TriangleStripentries to force a particular mesh arrangement.
Atriangle strip is defined as a series of connected triangles.
Afterthe first three vertices, which define the first triangle,
eachnew vertex defines one additional triangle, by alternating up
anddown.
Itis possible for the individual triangles of a triangle strip to
havea separate normal and/or color. If so, a
shouldbe given for each so-modified triangle:
}
Whereindex ranges from 0 to the number of components defined by the
trianglestrip (less 1). Note that the component attribute list
mustalways follow the vertex list.
[attributes]
indices
}
[componentattributes]
}
Atriangle fan is similar to a triangle strip, except all of the
connectedtriangles share the same vertex, which is the first
vertex. See
PARAMETRICDESCRIPTION ENTRIES¶
Thefollowing entries define parametric curves and surfaces.
Generally,Panda supports these only in the abstract; they’re not
geometryin the true sense but do exist in the scene graph and may
havespecific meaning to the application. However, Panda can create
visiblerepresentations of these parametrics to aid visualization.
Theseentries might also have meaning to external tools outside of an
interactivePanda session, such as egg-qtess, which can be used to
convertNURBS surfaces to polygons at different levels of resolution.
Ingeneral, dynamic attributes such as morphs and joint assignment are
legalfor the control vertices of the following parametrics, but Panda
itselfdoesn’t support them and will always create static curves and
surfaces. External tools like egg-qtess, however, may respect them.
[attributes]
}
ANURBS curve is a general parametric curve. It is often used to
representa motion path, e.g. for a camera or an object.
Theorder is equal to the degree of the polynomial basis plus 1. It
mustbe an integer in the range [1,4].
Thenumber of vertices must be equal to the number of knots minus the
order.
Eachcontrol vertex of a NURBS is defined in homogeneous space with
fourcoordinates x y z w (to convert to 3-space, divide x, y, and z
byw). The last coordinate is always the homogeneous coordinate; if
onlythree coordinates are given, it specifies a curve in two
dimensionsplus a homogeneous coordinate (x y w).
Thefollowing attributes may be defined:
Thisdefines the semanting meaning of this curve, either XYZ, HPR,
orT. If the type is XYZ, the curve will automatically be
transformedbetween Y-up and Z-up if necessary; otherwise, it will
beleft alone.
Ifthis scalar is given and nonzero, Panda will create a visible
representationof the curve when the scene is loaded. The number
representsthe number of line segments to draw to approximate the
curve.
Thisspecifies the color of the overall curve.
NURBScontrol vertices may also be given color and/or morph
attributes,but
vertices.
[attributes]
<U-knots>{u-knot-list}
<V-knots>{v-knot-list}
indices
}
}
ANURBS surface is an extension of a NURBS curve into two parametric
dimensions,u and v. NURBS surfaces may be given the same set of
attributesassigned to polygons, except for normals:
forNURBS. NURBS vertices, similarly, may be colored or morphed,
but
attributesmay also include
below.
Tohave Panda create a visualization of a NURBS surface, the
followingtwo attributes should be defined as well:
Thesedefine the number of subdivisions to make in the U and V
directionsto represent the surface. A uniform subdivision is
alwaysmade, and trim curves are not respected (though they will
bedrawn in if the trim curves themselves also have a subiv
parameter). This is only intended as a cheesy visualization.
Thesame sort of restrictions on order and knots applies to NURBS
surfacesas do to NURBS curves. The order and knot description may
bedifferent in each dimension.
Thesurface must have u-num * v-num vertices, where u-num is the
numberof u-knots minus the u-order, and v-num is the number of
v-knotsminus the v-order. All vertices must come from the same
vertexpool. The nth (zero-based) index number defines control
vertex(u, v) of the surface, where n = (v * u-num) + u. Thus, it
isthe u coordinate which changes faster.
Aswith the NURBS curve, each control vertex is defined in
homogeneousspace with four coordinates x y z w.
ANURBS may also contain curves on its surface. These are one or
morenested
curvesare defined in the two-dimensional parametric space of the
surface. Thus, these curve vertices should have only two dimensions
plusthe homogeneous coordinate: u v w. A curve-on-surface has no
intrinsicmeaning to the surface, unless it is defined within a
Finally,a NURBS may be trimmed by one or more trim curves. These
arespecial curves on the surface which exclude certain areas from
theNURBS surface definition. The inside is specified using two
rules:an odd winding rule that states that the inside consists of
allregions for which an infinite ray from any point in the region
willintersect the trim curve an odd number of times, and a curve
orientationrule that states that the inside consists of the regions
tothe left as the curve is traced.
Eachtrim curve contains one or more loops, and each loop contains
oneor more NURBS curves. The curves of a loop connect in a
head-to-tailfashion and must be explicitly closed.
Thetrim curve syntax is as follows:
}
[
}
[
}
Althoughthe egg syntax supports trim curves, there are at present
noegg processing tools that respect them. For instance, egg-qtess
ignorestrim curves and always tesselates the entire NURBS surface.
MORPHDESCRIPTION ENTRIES¶
Morphsare linear interpolations of attribute values at run time,
accordingto values read from an animation table. In general, vertex
positions,surface normals, texture coordinates, and colors may be
morphed.
Amorph target is defined by giving a net morph offset for a series of
vertexor polygon attributes; this offset is the value that will be
addedto the attribute when the morph target has the value 1.0. At
runtime, the morph target’s value may be animated to any scalar value
(butgenerally between 0.0 and 1.0); the corresponding fraction of the
offsetis added to the attribute each frame.
Thereis no explicit morph target definition; a morph target exists
solelyas the set of all offsets that share the same target name. The
targetname may be any arbitrary string; like any name in an egg file,
itshould be quoted if it contains special characters.
Thefollowing types of morph offsets may be defined, within their
correspondingattribute entries:
Aposition delta, valid within a
Thegiven offset vector, scaled by the morph target’s value, is
addedto the vertex or CV position each frame.
Anormal delta, similar to the position delta, valid within a
vector,scaled by the morph target’s value, is added to the normal
vectoreach frame. The resulting vector may not be automatically
normalizedto unit length.
Atexture-coordinate delta, valid within a
enclosingUV 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.
Acolor delta, valid within an
target’svalue, is added to the color value each frame.
GROUPINGENTRIES¶
A
eggfile. Groups can contain vertex pools and polygons, as well as
othergroups. The egg loader translates
PandaNodesin the scene graph (although the egg loader reserves the
rightto arbitrarily remove nodes that it deems unimportant–see the
entriescan be given specifically within a
attributesof the group:
GROUPBINARY ATTRIBUTES¶
Theseattributes may be either on or off; they are off by default.
Theyare turned on by specifying a non-zero “boolean-value”.
DCSstands for Dynamic Coordinate System. This indicates that
showcode will expect to be able to read the transform set on this
nodeat run time, and may need to modify the transform further.
Thisis a special case of
Thisis another syntax for the
shouldbe one of either “local” or “net”, whichspecifies the kind
ofpreserve_transform flag that will be set on the corresponding
ModelNode. If the string is “local”, it indicates that the local
transformon this node (as well as the net transform) will not be
affectedby any flattening operation and will be preserved through
theentire model loading process. If the string is “net”, then
onlythe net transform will be preserved; the local transform may
beadjusted in the event of a flatten operation.
Thisindicates that the show code might need a pointer to this
particulargroup. 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
alsothe
Thisindicates that this group begins an animated character. A
Characternode, which is the fundamental animatable object of
Panda’shigh-level Actor class, will be created for this group.
Thisflag should always be present within the
topof any hierarchy of
vertices;joints and morphs appearing outside of a hierarchy
identifiedwith a
Thisattribute indicates that the child nodes of this group
representa series of animation frames that should be
consecutivelydisplayed. In the absence of an “fps” scalar for
thegroup (see below), the egg loader creates a SwitchNode, and it
theresponsibility of the show code to perform the switching. If
anfps scalar is defined and is nonzero, the egg loader creates a
SequenceNodeinstead, which automatically cycles through its
children.
GROUPSCALARS¶
Thisspecifies the rate of animation for a SequenceNode (created
whenthe Switch flag is specified, see above). A value of zero
indicatesa SwitchNode should be created instead.
Thisspecifies the bin name for all polygons at or below this node
thatdo not explicitly set their own bin. See the description of
binfor geometry attributes, above.
Thisspecifies the drawing order for all polygons at or below this
nodethat do not explicitly set their own drawing order. See the
descriptionof draw-order for geometry attributes, above.
Specifiesspecial depth buffer properties of all polygons at or
belowthis node that do not override this. See the descriptions
forthe individual attributes under polygon attributes.
Ifthe visibility of a group is set to “hidden”, theprimitives
nestedwithin that group are not generated as a normally visible
primitive. If the Config.prc variable egg-suppress-hidden is set
totrue, the primitives are not converted at all; otherwise, they
areconverted as a “stashed” node.
Ifthis is present and boolean-value is non-zero, it indicates
thatthe geometry below this level is coplanar with the geometry
atthis level, and the geometry below is to be drawn as a decal
ontothe geometry at this level. This means the geometry below
thislevel will be rendered “on top of” this geometry, butwithout
theZ-fighting artifacts one might expect without the use of the
decalflag.
Thiscan optionally be used with the “decal” scalar, above. If
present,it should be applied to a sibling of one or more nodes
withthe “decal” scalar on. It indicates which of the sibling
nodesshould be treated as the base of the decal. In the absence
ofthis scalar, the parent of all decal nodes is used as the decal
base. This scalar is useful when the modeling package is unable
toparent geometry nodes to other geometry nodes.
Setsthe CollideMasks on the collision nodes and geometry nodes
createdat or below this group to the indicated values. These
arebits that indicate which objects can collide with which
otherobjects. Setting “collide-mask” is equivalent to setting
both”from-collide-mask” and “into-collide-mask” tothe same
value.
Thevalue may be an ordinary decimal integer, or a hex number in
theform 0x000, or a binary number in the form 0b000.
Specifiesthat a special blend mode should be applied geometry at
thislevel and below. The available options are none, add,
subtract,inv-subtract, min, and max. See ColorBlendAttrib.
Ifblend mode, above, is not none, this specifies the A and B
operandsto the blend equation. Common options are zero, one,
incoming-color,one-minus-incoming-color. See ColorBlendAttrib
forthe complete list of available options. The default is “one”.
Ifblend mode, above, is not none, and one of the blend operands
isconstant-color or a related option, this defines the constant
colorthat will be used.
Thismakes the first (or only) polygon within this group node into
anoccluder. The polygon must have exactly four vertices. An
occluderpolygon is invisible. When the occluder is activated
withmodel.set_occluder(occluder), objects that are behind the
occluderwill not be drawn. This can be a useful rendering
optimizationfor complex scenes, but should not be overused or
performancecan suffer.
OTHERGROUP ATTRIBUTES¶
Thisentry indicates that all geometry defined at or below this
grouplevel is part of a billboard that will rotate to face the
camera. Type is either “axis” or “point”, describing thetype of
rotation.
Billboardsrotate 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
rotateabout the Z axis. Point-rotation billboards rotate about
theorigin.
Thereis an implicit
meansthat the geometry within a billboard is not specified in
worldcoordinates, but in the local billboard space. Thus, a
vertexdrawn at point 0,0,0 will appear to be at the pivot point
ofthe billboard, not at the origin of the scene.
inout[fade]
}
}
Thesubtree beginning at this node and below represents a single
levelof detail for a particular model. Sibling nodes represent
theadditional levels of detail. The geometry at this node will
bevisible when the point (x, y, z) is closer than “in” units,but
furtherthan “out” units, from the camera. “fade” ispresently
ignored.
Thisattribute defines the indicated tag (as a key/value pair),
retrievablevia NodePath::get_tag() and related interfaces, on
thisnode.
name { type [flags] }¶
Thisentry indicates that geometry defined at this group level is
actuallyan invisible collision surface, and is not true geometry.
Thegeometry is used to define the extents of the collision
surface. If there is no geometry defined at this level, then a
childis searched for with the same collision type specified, and
itsgeometry is used to define the extent of the collision
surface(unless the “descend” flag is given; see below).
Validtypes so far are:
Plane
Thegeometry represents an infinite plane. The first polygon
foundin the group will define the plane.
Polygon
Thegeometry represents a single polygon. The first polygon is
used.
Polyset
Thegeometry represents a complex shape made up of several
polygons. This collision type should not be overused, as it
providesthe least optimization benefit.
Sphere
Thegeometry represents a sphere. The vertices in the group are
averagedtogether to determine the sphere’s center and radius.
Box
Thegeometry represents a box. The smalles axis-alligned box
thatwill fit around the vertices is used.
InvSphere
Thegeometry represents an inverse sphere. This is the same as
Sphere,with the normal inverted, so that the solid part of an
inversesphere is the entire world outside of it. Note that an
inversesphere is in infinitely large solid with a finite hole
cutinto it.
Tube
Thegeometry represents a tube. This is a cylinder-like shape
withhemispherical endcaps; it is sometimes called a capsule or
alozenge in other packages. The smallest tube shape that will
fitaround the vertices is used.
Theflags may be any zero or more of:
event
Throwsthe name of the
surfaceif the
anavatar strikes the solid. This is the default if the
intangible
Ratherthan being a solid collision surface, the defined surface
representsa boundary. The name of the surface will be thrown
asan event when an avatar crosses into the interior, and
name-outwill be thrown when an avater exits.
descend
Insteadof creating only one collision object of the given type,
eachgroup descended from this node that contains geometry will
definea new collision object of the given type. The event
name,if any, will also be inherited from the top node and
sharedamong all the collision objects.
keep
Don’tdiscard the visible geometry after using it to define a
collisionsurface; create both an invisible collision surface
andthe visible geometry.
level
Storesa special effective normal with the collision solid that
pointsup, regardless of the actual shape or orientation of the
solid. This can be used to allow an avatar to stand on a
slopingsurface without having a tendency to slide downward.
{type}¶
Thisis a short form to indicate one of several pre-canned sets of
attributes. Type may be any word, and a Config definition will be
searchedfor by the name “egg-object-type-word”, where “word”is
thetype word. This definition may contain any arbitrary egg
syntaxto be parsed in at this group level.
Anumber of predefined ObjectType definitions are provided:
barrier
Thisis equivalent to
geometrydefined at this root and below defines an invisible
collisionsolid.
trigger
Thisis equivalent to
Thegeometry defined at this root and below defines an invisible
triggersurface.
sphere
Equivalentto
replacedwith the smallest collision sphere that will enclose
it. Typically you model a sphere in polygons and put this flag
onit to create a collision sphere of the same size.
tube
Equivalentto
butthe geometry is replaced with a collision tube (a capsule).
Typicallyyou will model a capsule or a cylinder in polygons.
bubble
Equivalentto
bubbleis placed around the geometry, which is otherwise
unchanged.
ghost
Equivalentto
geometrybeginning at this node and below should never be
collidedwith–characters will pass through it.
backstage
Thishas no equivalent; it is treated as a special case. It
meansthat the geometry at this node and below should not be
translated. This will normally be used on scale references and
othermodeling tools.
Theremay also be additional predefined egg object types not
listedhere; see the *.pp files that are installed into the etc
directoryfor a complete list.
Thisspecifies a matrix transform at this group level. This
definesa local coordinate space for this group and its
descendents. Vertices are still specified in world coordinates
(ina vertex pool), but any geometry assigned to this group will
beinverse transformed to move its vertices to the local space.
Thetransform definition may be any sequence of zero or more of
thefollowing. Transformations are post multiplied in the order
theyare encountered to produce a net transformation matrix.
Rotationsare defined as a counterclockwise angle in degrees about
aparticular axis, either implicit (about the x, y, or z axis), or
arbitrary. Matrices, when specified explicitly, are row-major.
00010203
10111213
20212223
30313233
}
Notethat the
transformwhen it appears within the body of a
maydefine either a 2-d or a 3-d transform when it appears within
thebody of a
Thisdefines an optional default pose transform, which might be a
differenttransform from that defined by the
above. This makes sense only for a
description,below.
Thedefault pose transform defines the transform the joint will
maintainin the absence of any animation being applied. This is
differentfrom the
spacethe joint must have in order to keep its vertices in their
(globalspace) position as given in the egg file. If this is
differentfrom the
notbe in their egg file position at initial load. If there is
no
default-posetransform is the same as the
Normally,the
egg-optchar-defpose option. Most other software has little
reasonto specify an explicit
Thismoves geometry created from the named vertices into the
currentgroup, regardless of the group in which the geometry is
actuallydefined. See the
}
Oneor more AnimPreload entries may appear within the
containsa
above). These AnimPreload entries record the minimal preloaded
animationdata required in order to support asynchronous animation
binding. These entries are typically generated by the egg-optchar
programwith the -preload option, and are used by the Actor code
whenallow-async-bind is True (the default).
An
verticesreferenced by geometry created under the
arenot assumed to be given in world coordinates, but are instead
givenin the local space of the
anytransforms given to the node).
Inother words, geometry under an
localcoordinates. In principle, similar geometry can be created
underseveral different
ina different place in the scene each instance. This doesn’t
necessarilyimply the use of shared geometry in the Panda3D scene
graph,but see the syntax, below.
Thisis particularly useful in conjunction with a
loadexternal file references at places other than the origin.
Aspecial syntax of
geometryin the scene graph. The syntax is:
}
Inthis case, the referenced group name will appear as a duplicate
instancein this part of the tree. Local transforms can be applied
andare relative to the referencing group’s transform. The
referencedgroup must appear preceding this point in the egg file,
andit will also be a part of the scene in the point at which it
firstappears. The referenced group may be either a
earlier
Ajoint is a highly specialized kind of grouping node. A tree of
jointsis used to specify the skeletal structure of an animated
character.
Ajoint may only contain one of three things. It may contain a
(rest)position; it may contain lists of assigned vertices or CV’s;
andit may contain other joints.
Atree of
definition,which is created by applying the
See
Thevertex assignment is crucial. This is how the geometry of a
characteris made to move with the joints. The character’s geometry
isactually defined outside the joint tree, and each vertex must be
assignedto one or more joints within the tree.
Thisis done with zero or more
following:
Thisis syntactically similar to the way vertices are assigned to
polygons. Each
vertexpool (but there may be many
Indicesis a list of vertex numbers from the specied vertex pool, in
anarbitrary order.
Themembership scalar is optional. If specified, it is a value
between0.0 and 1.0 that indicates the fraction of dominance this
jointhas over the vertices. This is used to implement
soft-skinning,so that each vertex may have partial ownership in
severaljoints.
The
Inthis case, it treats the geometry as if it was parented under the
groupin the first place. Non-total membership assignments are
meaningless.


Thank You For Playing Artifacts
Third Trimester
Mana (25)
- 1 Black Lotus
- 1 Mox Emerald
- 1 Mox Jet
- 1 Mox Pearl
- 1 Mox Ruby
- 1 Mox Sapphire
- 1 Sol Ring
- 1 Mana Crypt
- 1 Mana Vault
- 4 Scalding Tarn
- 2 Polluted Delta
- 2 Seat of the Synod
- 3 Volcanic Island
- 2 Underground Sea
- 1 Tolarian Academy
- 1 Library of Alexandria
- 1 Island
Countermagic (9)
- 4 Force of Will
- 3 Mental Misstep
- 1 Misdirection
- 1 Flusterstorm
Card Draw, Card Selection (8)
- 1 Vampiric Tutor
- 1 Intuition
- 1 Brainstorm
- 1 Demonic Tutor
- 1 Time Walk
- 1 Ancestral Recall
- 1 Thirst for Knowledge
- 1 Tinker
Disruption, Removal (1)
- 1 Hurkyl’s Recall
Creatures (7)
- 4 Goblin Welder
- 3 Wurmcoil Engine
Planeswalkers (6)
- 4 Dack Fayden
- 1 Tezzeret the Seeker
- 1 Daretti, Scrap Savant
Combo (4)
- 2 Mindslaver
- 1 Time Vault
- 1 Voltaic Key
Sideboard
- 3 Hurkyl’s Recall
- 4 Ingot Chewer
- 2 Ravenous Trap
- 3 Grafdigger’s Cage
- 1 Toxic Deluge
- 1 Crucible of Worlds
- 1 Mountain


Not only the temperature changes
Besides the change of the icon and the temperature the app and the icon will change colors. Colors let you realize quicker what is happening outside.
You have cold, temperate and hot temperatures. Each one of those for the day and night.
It's not about the numbers, it's about the feeling
The temperature you will see is not the actual temperature but the apparent temperature.
You'll get feedback on the temperature you'll feel outside. Certain conditions like humidity and wind speed can change the way you feel outside so the app takes care of that for you.
Be prepared for change
Sometimes it's a great day outside and suddenly your picnic gets screwed by the rain. Now you can see if there's a chance of rain important enough to get your umbrella.
The app will show you a little umbrella if there's a chance of raining in the next 8 hours so you can prepare.


Is this a real offer @APompliano
I did not want to click on the link as I don't recall signing up to this list.
If it is real, I am DEFINITELY interested and can DEFINITELY be there to talk privacy, z adoption and more!
@CISLosAngeles
https://t.co/MrtQYXA2m5
I'll keep it...
expose me plz
You KNOW I'm gonna talk KMD
CryptoNinjaa15-Mar-19 02:00 PM
Expose you
FishyGuts16-Mar-19 01:51 AM
Anyone here with a Shopify shop want to earn a bounty, a customer and help out a KMD ecosystem coin?
Disclaimer: This guide assumes you already have a Shopify shop running. It also assumes you have read through the PirateOcean wallet setup…
cryptopleb16-Mar-19 07:55 AM
There way to many channel here now what happen
Anyways i finally found what look like general channel and here i will vent.
All this time i think barter dex was best DX choice but i find out just the opposite
This is bad both barter dex and hyper dex, i cant even place order
And central electrum what is this ? i dont want central i want full node
How is order book relay i cant find this is bad development i am very unhappy i found this project
So much document is hidden by KMD team i cant find anything i need
Team dont even explain what happens
I will probably be ban for this but no other way to describe month of frustration
I rather lose coin on central exchange
jorian16-Mar-19 08:03 AM
the dex is undergoing a transformation atm, it's been rewritten and is in alpha testing now
the initial dex released a year ago is basically dormant, so it's better to wait for the new dex (dubbed mm2.0) to come out
everything you need you'll find on docs.komodoplatform.com
granted, that place looks like an explosion, but if you care to look, you'll find what you need
cryptopleb16-Mar-19 08:07 AM
I have gone there
gcharang16-Mar-19 08:07 AM
Even in the old dex both full nodes and electrum mode are possible
cryptopleb16-Mar-19 08:07 AM
Right now i barterdex all over crypto and dont work
Very unhappy
@gcharang it is not though i was here and had frustration


HOME
THEATRES
MOVIES
ABOUT
LOGIN
SIGN UP
Name
THEATRES
MOVIES
ABOUT
LOG IN
×
Email
Password
Log in
Don't have an account yet?
SIGN UP
×
Name
Age
Email
Password
Sign up
Already have an account?
YOUR PROFILE
×
Name
Age
Email
Password
Save Changes
Log out
{% block body %} {% endblock %}


For Docs, License, Tests, and pre-packed downloads, see: https://underscorejs.org
For support and questions, please consult our security policy, the gitter channel or stackoverflow
Underscore is an open-sourced component of DocumentCloud: https://github.com/documentcloud
Many thanks to our contributors: https://github.com/jashkenas/underscore/contributors
You can support the project by donating on Patreon. Enterprise coverage is available as part of the Tidelift Subscription.
This project adheres to a code of conduct. By participating, you are expected to uphold this code.


Coding Styles
In this chapter you’ll find some high-level conventions for coding in TypeScript. If you’re looking for a thorough guide, check out idomatic.js[1] or AirBnB’s ES6 style guide[2].
#Types
- Arrays should be defined like this
type[]
, notArray<type>
. - Create an
interface
rather than using theany
type.
Theany
keyword should only be used if absolutely necessary.
#Naming
const
should use UPPEER_SNAKE_CASE[3]class
names should always be written in PascalCase.[4]interface
names should alawys start with a capital “I” and use PascalCase, e.g.IMarvelCharacter
.


class Encoding
An Encoding instance represents a character encoding usable in Ruby. It is defined as a constant under the Encoding namespace. It has a name and optionally, aliases:
Encoding::ISO_8859_1.name #=> "ISO-8859-1" Encoding::ISO_8859_1.names #=> ["ISO-8859-1", "ISO8859-1"]
Ruby methods dealing with encodings return or accept Encoding instances as arguments (when a method accepts an Encoding instance as an argument, it can be passed an Encoding name or alias instead).
"some string".encoding #=> #<Encoding:UTF-8> string = "some string".encode(Encoding::ISO_8859_1) #=> "some string" string.encoding #=> #<Encoding:ISO-8859-1> "some string".encode "ISO-8859-1" #=> "some string"
Encoding::ASCII_8BIT
is a special encoding that is usually
used for a byte string, not a character string. But as the name insists,
its characters in the range of ASCII are considered as ASCII characters.
This is useful when you use ASCII-8BIT characters with other ASCII
compatible characters.
Changing an encoding¶ ↑
The associated Encoding of a String can be changed in two different ways.
First, it is possible to set the Encoding of a string to a new Encoding without changing the internal byte representation of the string, with String#force_encoding. This is how you can tell Ruby the correct encoding of a string.
string #=> "R\xC3\xA9sum\xC3\xA9" string.encoding #=> #<Encoding:ISO-8859-1> string.force_encoding(Encoding::UTF_8) #=> "R\u00E9sum\u00E9"
Second, it is possible to transcode a string, i.e. translate its internal byte representation to another encoding. Its associated encoding is also set to the other encoding. See String#encode for the various forms of transcoding, and the Encoding::Converter class for additional control over the transcoding process.
string #=> "R\u00E9sum\u00E9" string.encoding #=> #<Encoding:UTF-8> string = string.encode!(Encoding::ISO_8859_1) #=> "R\xE9sum\xE9" string.encoding #=> #<Encoding::ISO-8859-1>
Script encoding¶ ↑
All Ruby script code has an associated Encoding which any String literal created in the source code will be associated to.
The default script encoding is Encoding::UTF-8
after v2.0, but
it can be changed by a magic comment on the first line of the source code
file (or second line, if there is a shebang line on the first). The comment
must contain the word coding
or encoding
,
followed by a colon, space and the Encoding
name or alias:
# encoding: UTF-8 "some string".encoding #=> #<Encoding:UTF-8>
The __ENCODING__
keyword returns the script encoding of the
file which the keyword is written:
# encoding: ISO-8859-1 __ENCODING__ #=> #<Encoding:ISO-8859-1>
ruby -K
will change the default locale encoding, but this is
not recommended. Ruby source files should declare its script encoding by a
magic comment even when they only depend on US-ASCII strings or regular
expressions.
Locale encoding¶ ↑
The default encoding of the environment. Usually derived from locale.
see ::locale_charmap, ::find('locale')
Filesystem encoding¶ ↑
The default encoding of strings from the filesystem of the environment. This is used for strings of file names or paths.
see ::find('filesystem')
External encoding¶ ↑
Each IO object has an external encoding which
indicates the encoding that Ruby will use to read its data. By default Ruby
sets the external encoding of an IO object to the
default external encoding. The default external encoding is set by locale
encoding or the interpreter -E
option. ::default_external
returns the current value of the external encoding.
ENV["LANG"] #=> "UTF-8" Encoding.default_external #=> #<Encoding:UTF-8> $ ruby -E ISO-8859-1 -e "p Encoding.default_external" #<Encoding:ISO-8859-1> $ LANG=C ruby -e 'p Encoding.default_external' #<Encoding:US-ASCII>
The default external encoding may also be set through ::default_external=,
but you should not do this as strings created before and after the change
will have inconsistent encodings. Instead use ruby -E
to
invoke ruby with the correct external encoding.
When you know that the actual encoding of the data of an IO object is not the default external encoding, you can reset its external encoding with IO#set_encoding or set it at IO object creation (see IO.new options).
Internal encoding¶ ↑
To process the data of an IO object which has an encoding different from its external encoding, you can set its internal encoding. Ruby will use this internal encoding to transcode the data when it is read from the IO object.
Conversely, when data is written to the IO object it is transcoded from the internal encoding to the external encoding of the IO object.
The internal encoding of an IO object can be set with IO#set_encoding or at IO object creation (see IO.new options).
The internal encoding is optional and when not set, the Ruby default
internal encoding is used. If not explicitly set this default internal
encoding is nil
meaning that by default, no transcoding
occurs.
The default internal encoding can be set with the interpreter option
-E
. ::default_internal
returns the current internal encoding.
$ ruby -e 'p Encoding.default_internal' nil $ ruby -E ISO-8859-1:UTF-8 -e "p [Encoding.default_external, \ Encoding.default_internal]" [#<Encoding:ISO-8859-1>, #<Encoding:UTF-8>]
The default internal encoding may also be set through ::default_internal=,
but you should not do this as strings created before and after the change
will have inconsistent encodings. Instead use ruby -E
to
invoke ruby with the correct internal encoding.
IO encoding example¶ ↑
In the following example a UTF-8 encoded string “Ru00E9sumu00E9” is transcoded for output to ISO-8859-1 encoding, then read back in and transcoded to UTF-8:
string = "R\u00E9sum\u00E9" open("transcoded.txt", "w:ISO-8859-1") do |io| io.write(string) end puts "raw text:" p File.binread("transcoded.txt") puts open("transcoded.txt", "r:ISO-8859-1:UTF-8") do |io| puts "transcoded text:" p io.read end
While writing the file, the internal encoding is not specified as it is only necessary for reading. While reading the file both the internal and external encoding must be specified to obtain the correct result.
$ ruby t.rb raw text: "R\xE9sum\xE9" transcoded text: "R\u00E9sum\u00E9"
Public Class Methods
Returns the hash of available encoding alias and original encoding name.
Encoding.aliases #=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII", "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
static VALUE rb_enc_aliases(VALUE klass) { VALUE aliases[2]; aliases[0] = rb_hash_new(); aliases[1] = rb_ary_new(); st_foreach(enc_table.names, rb_enc_aliases_enc_i, (st_data_t)aliases); return aliases[0]; }
Checks the compatibility of two objects.
If the objects are both strings they are compatible when they are concatenatable. The encoding of the concatenated string will be returned if they are compatible, nil if they are not.
Encoding.compatible?("\xa1".force_encoding("iso-8859-1"), "b") #=> #<Encoding:ISO-8859-1> Encoding.compatible?( "\xa1".force_encoding("iso-8859-1"), "\xa1\xa1".force_encoding("euc-jp")) #=> nil
If the objects are non-strings their encodings are compatible when they have an encoding and:
-
Either encoding is US-ASCII compatible
-
One of the encodings is a 7-bit encoding
static VALUE enc_compatible_p(VALUE klass, VALUE str1, VALUE str2) { rb_encoding *enc; if (!enc_capable(str1)) return Qnil; if (!enc_capable(str2)) return Qnil; enc = rb_enc_compatible(str1, str2); if (!enc) return Qnil; return rb_enc_from_encoding(enc); }
Returns default external encoding.
The default external encoding is used by default for strings created from the following locations:
-
File data read from disk
While strings created from these locations will have this encoding, the encoding may not be valid. Be sure to check String#valid_encoding?.
File data written to disk will be transcoded to the default external encoding when written.
The default external encoding is initialized by the locale or -E option.
static VALUE get_default_external(VALUE klass) { return rb_enc_default_external(); }
Sets default external encoding. You should not set ::default_external in
ruby code as strings created before changing the value may have a different
encoding from strings created after the value was changed., instead you
should use ruby -E
to invoke ruby with the correct
default_external.
See ::default_external for information on how the default external encoding is used.
static VALUE set_default_external(VALUE klass, VALUE encoding) { rb_warning("setting Encoding.default_external"); rb_enc_set_default_external(encoding); return encoding; }
Returns default internal encoding. Strings will be transcoded to the default internal encoding in the following places if the default internal encoding is not nil:
-
File data read from disk
-
Strings returned from Readline
-
Strings returned from SDBM
-
Values from ENV
-
Values in ARGV including $PROGRAM_NAME
Additionally String#encode and String#encode! use the default internal encoding if no encoding is given.
The locale encoding (__ENCODING__), not ::default_internal, is used as the encoding of created strings.
::default_internal is initialized by the source file's internal_encoding or -E option.
static VALUE get_default_internal(VALUE klass) { return rb_enc_default_internal(); }
Sets default internal encoding or removes default internal encoding when
passed nil. You should not set ::default_internal in
ruby code as strings created before changing the value may have a different
encoding from strings created after the change. Instead you should use
ruby -E
to invoke ruby with the correct default_internal.
See ::default_internal for information on how the default internal encoding is used.
static VALUE set_default_internal(VALUE klass, VALUE encoding) { rb_warning("setting Encoding.default_internal"); rb_enc_set_default_internal(encoding); return encoding; }
Search the encoding with specified name. name should be a string.
Encoding.find("US-ASCII") #=> #<Encoding:US-ASCII>
Names which this method accept are encoding names and aliases including following special aliases
- “external”
-
default external encoding
- “internal”
-
default internal encoding
- “locale”
-
locale encoding
- “filesystem”
-
filesystem encoding
An ArgumentError is raised when no
encoding with name. Only
Encoding.find("internal")
however returns nil when
no encoding named “internal”, in other words, when Ruby has no default
internal encoding.
static VALUE enc_find(VALUE klass, VALUE enc) { int idx; if (is_obj_encoding(enc)) return enc; idx = str_to_encindex(enc); if (idx == UNSPECIFIED_ENCODING) return Qnil; return rb_enc_from_encoding_index(idx); }
Returns the list of loaded encodings.
Encoding.list #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>, #<Encoding:ISO-2022-JP (dummy)>] Encoding.find("US-ASCII") #=> #<Encoding:US-ASCII> Encoding.list #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>, #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
static VALUE enc_list(VALUE klass) { VALUE ary = rb_ary_new2(0); rb_ary_replace(ary, rb_encoding_list); return ary; }
Returns the locale charmap name. It returns nil if no appropriate information.
Debian GNU/Linux LANG=C Encoding.locale_charmap #=> "ANSI_X3.4-1968" LANG=ja_JP.EUC-JP Encoding.locale_charmap #=> "EUC-JP" SunOS 5 LANG=C Encoding.locale_charmap #=> "646" LANG=ja Encoding.locale_charmap #=> "eucJP"
The result is highly platform dependent. So ::find may cause an error. If you need some encoding object even for unknown locale, ::find("locale") can be used.
VALUE rb_locale_charmap(VALUE klass) { return locale_charmap(rb_usascii_str_new_cstr); }
Returns the list of available encoding names.
Encoding.name_list #=> ["US-ASCII", "ASCII-8BIT", "UTF-8", "ISO-8859-1", "Shift_JIS", "EUC-JP", "Windows-31J", "BINARY", "CP932", "eucJP"]
static VALUE rb_enc_name_list(VALUE klass) { VALUE ary = rb_ary_new2(enc_table.names->num_entries); st_foreach(enc_table.names, rb_enc_name_list_i, (st_data_t)ary); return ary; }
Public Instance Methods
Returns whether ASCII-compatible or not.
Encoding::UTF_8.ascii_compatible? #=> true Encoding::UTF_16BE.ascii_compatible? #=> false
static VALUE enc_ascii_compatible_p(VALUE enc) { return rb_enc_asciicompat(must_encoding(enc)) ? Qtrue : Qfalse; }
Returns true for dummy encodings. A dummy encoding is an encoding for which character handling is not properly implemented. It is used for stateful encodings.
Encoding::ISO_2022_JP.dummy? #=> true Encoding::UTF_8.dummy? #=> false
static VALUE enc_dummy_p(VALUE enc) { return ENC_DUMMY_P(must_encoding(enc)) ? Qtrue : Qfalse; }
Returns a string which represents the encoding for programmers.
Encoding::UTF_8.inspect #=> "#<Encoding:UTF-8>" Encoding::ISO_2022_JP.inspect #=> "#<Encoding:ISO-2022-JP (dummy)>"
static VALUE enc_inspect(VALUE self) { rb_encoding *enc; if (!is_data_encoding(self)) { not_encoding(self); } if (!(enc = DATA_PTR(self)) || rb_enc_from_index(rb_enc_to_index(enc)) != enc) { rb_raise(rb_eTypeError, "broken Encoding"); } return rb_enc_sprintf(rb_usascii_encoding(), "#<%"PRIsVALUE":%s%s%s>", rb_obj_class(self), rb_enc_name(enc), (ENC_DUMMY_P(enc) ? " (dummy)" : ""), enc_autoload_p(enc) ? " (autoload)" : ""); }
Returns the name of the encoding.
Encoding::UTF_8.name #=> "UTF-8"
static VALUE enc_name(VALUE self) { return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self))); }
Returns the list of name and aliases of the encoding.
Encoding::WINDOWS_31J.names #=> ["Windows-31J", "CP932", "csWindows31J"]
static VALUE enc_names(VALUE self) { VALUE args[2]; args[0] = (VALUE)rb_to_encoding_index(self); args[1] = rb_ary_new2(0); st_foreach(enc_table.names, enc_names_i, (st_data_t)args); return args[1]; }
Returns a replicated encoding of enc whose name is name. The new encoding should have the same byte structure of enc. If name is used by another encoding, raise ArgumentError.
static VALUE enc_replicate(VALUE encoding, VALUE name) { return rb_enc_from_encoding_index( rb_enc_replicate(StringValueCStr(name), rb_to_encoding(encoding))); }
Returns the name of the encoding.
Encoding::UTF_8.name #=> "UTF-8"
static VALUE enc_name(VALUE self) { return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self))); }