mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-27 07:03:36 -04:00
Merge branch 'release/1.10.x'
This commit is contained in:
commit
78fb565f2b
@ -2769,7 +2769,7 @@ def SetupVisualStudioEnviron():
|
||||
elif not win_kit.endswith('\\'):
|
||||
win_kit += '\\'
|
||||
|
||||
for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763, 18362:
|
||||
for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763, 18362, 19041:
|
||||
version = "10.0.{0}.0".format(vnum)
|
||||
if os.path.isfile(win_kit + "Include\\" + version + "\\ucrt\\assert.h"):
|
||||
print("Using Universal CRT %s" % (version))
|
||||
|
@ -3,7 +3,7 @@ THE PHILOSOPHY OF EGG FILES (vs. bam files)
|
||||
Egg files are used by Panda3D to describe many properties of a scene:
|
||||
simple geometry, including special effects and collision surfaces,
|
||||
characters including skeletons, morphs, and multiple-joint
|
||||
assignments, and character animation tables.
|
||||
assignments, and character animation tables.
|
||||
|
||||
Egg files are designed to be the lingua franca of model manipulation
|
||||
for Panda tools. A number of utilities are provided that read and
|
||||
@ -168,8 +168,9 @@ appear before they are referenced.
|
||||
The remaining formats are generic and specify only the semantic
|
||||
meaning of the channels. The size of the texels is determined by
|
||||
the width of the components in the image file. RGBA is the most
|
||||
general; RGB is the same, but without any alpha channel. RGBM is
|
||||
like RGBA, except that it requests only one bit of alpha, if the
|
||||
general; RGB is the same, but without any alpha channel.
|
||||
|
||||
RGBM is like RGBA, except that it requests only one bit of alpha, if the
|
||||
graphics card can provide that, to leave more room for the RGB
|
||||
components, which is especially important for older 16-bit
|
||||
graphics cards (the "M" stands for "mask", as in a cutout).
|
||||
@ -211,7 +212,7 @@ appear before they are referenced.
|
||||
Although less often used, for 3-d textures wrapw may also be
|
||||
specified, and it behaves similarly to wrapu and wrapv.
|
||||
|
||||
There are other legal values in addtional to REPEAT and CLAMP.
|
||||
There are other legal values in additional to REPEAT and CLAMP.
|
||||
The full list is:
|
||||
|
||||
CLAMP
|
||||
@ -278,7 +279,7 @@ appear before they are referenced.
|
||||
/ (number of views).
|
||||
|
||||
<Scalar> read-mipmaps { flag }
|
||||
|
||||
|
||||
If this flag is nonzero, then pre-generated mipmap levels will be
|
||||
loaded along with the texture. In this case, the filename should
|
||||
contain a sequence of one or more hash mark ("#") characters,
|
||||
@ -413,7 +414,7 @@ appear before they are referenced.
|
||||
<Scalar> combine-alpha-operand2 { src-alpha }
|
||||
|
||||
<Scalar> saved-result { flag }
|
||||
|
||||
|
||||
If flag is nonzero, then it indicates that this particular texture
|
||||
stage will be supplied as the "last_saved_result" source for any
|
||||
future texture stages.
|
||||
@ -704,7 +705,7 @@ appear before they are referenced.
|
||||
<UV> [name] { u v [w] [tangent] [binormal] [morph-list] }
|
||||
|
||||
This gives the texture coordinates of the vertex. This must be
|
||||
specified if a texture is to be mapped onto this geometry.
|
||||
specified if a texture is to be mapped onto this geometry.
|
||||
|
||||
The texture coordinates are usually two-dimensional, with two
|
||||
component values (u v), but they may also be three-dimensional,
|
||||
@ -739,7 +740,7 @@ appear before they are referenced.
|
||||
meaning to custom code or a custom shader. Like named UV's, there
|
||||
may be multiple Aux entries for a given vertex, each with a
|
||||
different name.
|
||||
|
||||
|
||||
|
||||
|
||||
<DynamicVertexPool> name { vertices }
|
||||
@ -758,18 +759,18 @@ appear before they are referenced.
|
||||
|
||||
At the present time, the DynamicVertexPool is not implemented in
|
||||
Panda3D.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GEOMETRY ENTRIES
|
||||
|
||||
<Polygon> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
<Polygon> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
}
|
||||
|
||||
A polygon consists of a sequence of vertices from a single vertex
|
||||
@ -822,7 +823,7 @@ GEOMETRY ENTRIES
|
||||
used unless all vertices also have a normal. If no normal is
|
||||
defined, none will be supplied. The polygon normal, like the
|
||||
vertex normal, may be morphed by specifying a series of <DNormal>
|
||||
entries.
|
||||
entries.
|
||||
|
||||
The polygon normal is used only for lighting and environment
|
||||
mapping calculations, and is not related to the implicit normal
|
||||
@ -844,7 +845,7 @@ GEOMETRY ENTRIES
|
||||
disabled, and polygons are one-sided; specifying a nonzero value
|
||||
disables backface culling for this particular polygon and allows
|
||||
it to be viewed from either side.
|
||||
|
||||
|
||||
|
||||
<Scalar> bin { bin-name }
|
||||
|
||||
@ -916,12 +917,12 @@ GEOMETRY ENTRIES
|
||||
or even within a texture.
|
||||
|
||||
|
||||
<Patch> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
<Patch> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
}
|
||||
|
||||
A patch is similar to a polygon, but it is a special primitive that
|
||||
@ -936,12 +937,12 @@ GEOMETRY ENTRIES
|
||||
specified for Patch.
|
||||
|
||||
|
||||
<PointLight> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
<PointLight> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
}
|
||||
|
||||
A PointLight is a set of single points. One point is drawn for each
|
||||
@ -964,12 +965,12 @@ GEOMETRY ENTRIES
|
||||
viewer normally.
|
||||
|
||||
|
||||
<Line> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
<Line> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
[component attributes]
|
||||
}
|
||||
|
||||
@ -985,11 +986,11 @@ GEOMETRY ENTRIES
|
||||
line segment, as in TriangleStrip, below.
|
||||
|
||||
|
||||
<TriangleStrip> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
<TriangleStrip> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
[component attributes]
|
||||
}
|
||||
@ -1013,7 +1014,7 @@ GEOMETRY ENTRIES
|
||||
It is possible for the individual triangles of a triangle strip to
|
||||
have a separate normal and/or color. If so, a <Component> entry
|
||||
should be given for each so-modified triangle:
|
||||
|
||||
|
||||
<Component> index {
|
||||
<RGBA> { r g b a [morph-list] }
|
||||
<Normal> { x y z [morph-list] }
|
||||
@ -1024,11 +1025,11 @@ GEOMETRY ENTRIES
|
||||
must always follow the vertex list.
|
||||
|
||||
|
||||
<TriangleFan> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
<TriangleFan> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
[component attributes]
|
||||
}
|
||||
@ -1057,7 +1058,7 @@ itself doesn't support them and will always create static curves and
|
||||
surfaces. External tools like egg-qtess, however, may respect them.
|
||||
|
||||
<NURBSCurve> {
|
||||
[attributes]
|
||||
[attributes]
|
||||
|
||||
<Order> { order }
|
||||
<Knots> { knot-list }
|
||||
@ -1083,7 +1084,7 @@ surfaces. External tools like egg-qtess, however, may respect them.
|
||||
|
||||
<Scalar> type { curve-type }
|
||||
|
||||
This defines the semanting meaning of this curve, either XYZ, HPR,
|
||||
This defines the semantic meaning of this curve, either XYZ, HPR,
|
||||
or T. If the type is XYZ, the curve will automatically be
|
||||
transformed between Y-up and Z-up if necessary; otherwise, it will
|
||||
be left alone.
|
||||
@ -1107,16 +1108,16 @@ surfaces. External tools like egg-qtess, however, may respect them.
|
||||
|
||||
|
||||
<NURBSSurface> name {
|
||||
[attributes]
|
||||
[attributes]
|
||||
|
||||
<Order> { u-order v-order }
|
||||
<U-knots> { u-knot-list }
|
||||
<V-knots> { v-knot-list }
|
||||
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
}
|
||||
|
||||
A NURBS surface is an extension of a NURBS curve into two parametric
|
||||
@ -1137,7 +1138,7 @@ surfaces. External tools like egg-qtess, however, may respect them.
|
||||
These define the number of subdivisions to make in the U and V
|
||||
directions to represent the surface. A uniform subdivision is
|
||||
always made, and trim curves are not respected (though they will
|
||||
be drawn in if the trim curves themselves also have a subiv
|
||||
be drawn in if the trim curves themselves also have a subdiv
|
||||
parameter). This is only intended as a cheesy visualization.
|
||||
|
||||
|
||||
@ -1194,7 +1195,7 @@ surfaces. External tools like egg-qtess, however, may respect them.
|
||||
|
||||
Although the egg syntax supports trim curves, there are at present
|
||||
no egg processing tools that respect them. For instance, egg-qtess
|
||||
ignores trim curves and always tesselates the entire NURBS surface.
|
||||
ignores trim curves and always tessellates the entire NURBS surface.
|
||||
|
||||
|
||||
MORPH DESCRIPTION ENTRIES
|
||||
@ -1267,7 +1268,7 @@ GROUPING ENTRIES
|
||||
attributes of the group:
|
||||
|
||||
GROUP BINARY ATTRIBUTES
|
||||
|
||||
|
||||
These attributes may be either on or off; they are off by default.
|
||||
They are turned on by specifying a non-zero "boolean-value".
|
||||
|
||||
@ -1310,6 +1311,15 @@ GROUPING ENTRIES
|
||||
vertices; joints and morphs appearing outside of a hierarchy
|
||||
identified with a <Dart> flag are undefined.
|
||||
|
||||
<Dart> { structured }
|
||||
|
||||
This is an optional alternative for the <Dart> flag.
|
||||
By default, Panda will collapse all of the geometry in a group (with the <Dart> { 1 } flag)
|
||||
a single node. While this is optimal for conditions such as characters moving around
|
||||
a scene, it may be suboptimal for larger or more complex characters.
|
||||
This entry is typically generated by the egg-optchar program with the "-dart structured" flag.
|
||||
<Dart> { structured } implies <Dart> { 1 }.
|
||||
|
||||
<Switch> { boolean-value }
|
||||
|
||||
This attribute indicates that the child nodes of this group
|
||||
@ -1446,7 +1456,7 @@ GROUPING ENTRIES
|
||||
of the billboard, not at the origin of the scene.
|
||||
|
||||
<SwitchCondition> {
|
||||
<Distance> {
|
||||
<Distance> {
|
||||
in out [fade] <Vertex> { x y z }
|
||||
}
|
||||
}
|
||||
@ -1483,7 +1493,7 @@ GROUPING ENTRIES
|
||||
Valid types so far are:
|
||||
|
||||
Plane
|
||||
|
||||
|
||||
The geometry represents an infinite plane. The first polygon
|
||||
found in the group will define the plane.
|
||||
|
||||
@ -1550,7 +1560,7 @@ GROUPING ENTRIES
|
||||
most compatibility.
|
||||
|
||||
keep
|
||||
|
||||
|
||||
Don't discard the visible geometry after using it to define a
|
||||
collision surface; create both an invisible collision surface
|
||||
and the visible geometry.
|
||||
@ -1619,7 +1629,8 @@ GROUPING ENTRIES
|
||||
|
||||
There may also be additional predefined egg object types not
|
||||
listed here; see the *.pp files that are installed into the etc
|
||||
directory for a complete list.
|
||||
directory for a complete list. Additionally, you can reference
|
||||
the file located in $PANDA/src/doc/howto.MultiGenModelFlags
|
||||
|
||||
<Transform> { transform-definition }
|
||||
|
||||
@ -1683,9 +1694,9 @@ GROUPING ENTRIES
|
||||
current group, regardless of the group in which the geometry is
|
||||
actually defined. See the <Joint> description, below.
|
||||
|
||||
<AnimPreload> {
|
||||
<AnimPreload> {
|
||||
<Scalar> fps { float-value }
|
||||
<Scalar> num-frames { integer-value }
|
||||
<Scalar> num-frames { integer-value }
|
||||
}
|
||||
|
||||
One or more AnimPreload entries may appear within the <Group> that
|
||||
@ -1720,7 +1731,7 @@ GROUPING ENTRIES
|
||||
geometry in the scene graph. The syntax is:
|
||||
|
||||
<Instance> name {
|
||||
<Ref> { group-name }
|
||||
<Ref> { group-name }
|
||||
[ <Ref> { group-name } ... ]
|
||||
}
|
||||
|
||||
@ -1746,8 +1757,8 @@ GROUPING ENTRIES
|
||||
and it may contain other joints.
|
||||
|
||||
A tree of <Joint> nodes only makes sense within a character
|
||||
definition, which is created by applying the <DART> flag to a group.
|
||||
See <DART>, above.
|
||||
definition, which is created by applying the <Dart> flag to a group.
|
||||
See <Dart>, above.
|
||||
|
||||
The vertex assignment is crucial. This is how the geometry of a
|
||||
character is made to move with the joints. The character's geometry
|
||||
@ -1790,7 +1801,7 @@ GROUPING ENTRIES
|
||||
bundles, or any one of the following (<Scalar> entries are optional,
|
||||
and default as shown):
|
||||
|
||||
<S$Anim> name {
|
||||
<S$Anim> name {
|
||||
<Scalar> fps { 24 }
|
||||
<V> { values }
|
||||
}
|
||||
@ -1844,7 +1855,7 @@ GROUPING ENTRIES
|
||||
an animation sequence.
|
||||
|
||||
|
||||
<VertexAnim> name {
|
||||
<VertexAnim> name {
|
||||
<Scalar> width { table-width }
|
||||
<Scalar> fps { 24 }
|
||||
<V> { values }
|
||||
@ -1913,6 +1924,10 @@ ANIMATION STRUCTURE
|
||||
animated model description. Without the <Dart> flag, joints will be
|
||||
treated as ordinary groups, and morphs will be ignored.
|
||||
|
||||
It is important to note that utilizing <Dart> { 1 } will collapse all of the
|
||||
model's geometry into a single node. To omit this, use <Dart> { structured } instead.
|
||||
(See <Dart> above.)
|
||||
|
||||
In the above, UPPERCASE NAMES represent an arbitrary name that you
|
||||
may choose. The name of the enclosing group, CHARACTER_NAME, is
|
||||
taken as the name of the animated model. It should generally match
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
This document describes the different kinds of model flags one can place in
|
||||
the comment field of MultiGen group beads. The general format for a model
|
||||
flag is:
|
||||
flag is:
|
||||
<egg> { <FLAGNAME> {value} }
|
||||
|
||||
The most up-to-date version of this document can be found in:
|
||||
@ -30,7 +30,7 @@ The most up-to-date version of this document can be found in:
|
||||
<egg> { <ObjectType> {camera-barrier} } Invisible collision surface for camera and colliders
|
||||
<egg> { <ObjectType> {camera-barrier-sphere} } Invisible sphere collision surface for camera and colliders
|
||||
<egg> { <ObjectType> {backstage} } Modeling reference object
|
||||
<egg> { <Decal> {1} } Decal the node below to me
|
||||
<egg> { <Decal> {1} } Decal the node below to me
|
||||
(like a window on a wall)
|
||||
<egg> { <Scalar> fps { # } } Set rate of animation for a pfSequence
|
||||
|
||||
@ -52,12 +52,12 @@ common flag/value pairs and describes what they are used for.
|
||||
which one places the flag (so names like red-hut are more useful than
|
||||
names like o34).
|
||||
|
||||
<egg> { <Model> {1} }
|
||||
<egg> { <Model> {1} }
|
||||
|
||||
Used to show/hide, change the color, or change the collision properties
|
||||
Used to show/hide, change the color, or change the collision properties
|
||||
of a chunk.
|
||||
|
||||
<egg> { <DCS> {1} }
|
||||
<egg> { <DCS> {1} }
|
||||
|
||||
Used to move, rotate, or scale a chunk of the model. Also can be used
|
||||
(like the <Model> flag) to show/hide, change the color, and change the
|
||||
@ -91,7 +91,7 @@ common flag/value pairs and describes what they are used for.
|
||||
a door, for example, so the player can tell when the avatar has
|
||||
moved through the door.
|
||||
- BACKSTAGE objects are not translated over to the player. Modelers
|
||||
should use this flag on reference objects that they include to help
|
||||
should use this flag on reference objects that they include to help
|
||||
in the modeling task (such as scale references)
|
||||
|
||||
IMPORTANT NOTE:
|
||||
@ -108,7 +108,7 @@ common flag/value pairs and describes what they are used for.
|
||||
|
||||
********** PROPERTIES **********
|
||||
|
||||
These are used to control properties of selected chunks.
|
||||
These are used to control properties of selected chunks.
|
||||
|
||||
<egg> { <Scalar> fps { frame-rate } }
|
||||
|
||||
@ -124,7 +124,7 @@ These are used to control properties of selected chunks.
|
||||
Multiple Flag/value pairs can be combined within an single <egg> field.
|
||||
For example:
|
||||
|
||||
<egg> { <Model> {1}
|
||||
<egg> { <Model> {1}
|
||||
<ObjectType> {barrier} }
|
||||
|
||||
Generally, the <Model> flag can be combined with most other flags
|
||||
@ -134,7 +134,7 @@ These are used to control properties of selected chunks.
|
||||
could also be written as:
|
||||
|
||||
<egg>{<model>{1}<objecttype>{barrier}}
|
||||
|
||||
|
||||
3) Where to place the flags
|
||||
|
||||
All model flags except <Normal> flags are generally placed in the
|
||||
@ -154,6 +154,6 @@ These are used to control properties of selected chunks.
|
||||
4) Flags at different levels in the model
|
||||
|
||||
Flags in lower level beads generally override flags in upper level
|
||||
beads.
|
||||
beads.
|
||||
|
||||
5) For more detailed information see $PANDA/src/doc/eggSyntax.txt.
|
||||
|
@ -36,10 +36,6 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -589,16 +585,15 @@ determine_bin_home(EggBin *egg_bin) {
|
||||
// ahead and make an implicit node for the joint.
|
||||
|
||||
if (egg_group->get_dcs_type() == EggGroup::DC_none) {
|
||||
/*
|
||||
* Unless the user specifically forbade exposing the joint by putting an
|
||||
* explicit "<DCS> { none }" entry in the joint. In this case, we return NULL
|
||||
* to treat the geometry as dynamic (and animate it by animating its
|
||||
* vertices), but display lists and vertex buffers will perform better if more
|
||||
* geometry is rigid. There's a tradeoff, though, since the cull traverser
|
||||
* will have to do more work with additional transforms in the scene graph,
|
||||
* and this may also break up the geometry into more individual pieces, which
|
||||
* is the biggest limiting factor on modern PC graphics cards.
|
||||
*/
|
||||
// Unless the user specifically forbade exposing the joint by putting an
|
||||
// explicit "<DCS> { none }" entry in the joint. In this case, we return
|
||||
// nullptr to treat the geometry as dynamic (and animate it by animating
|
||||
// its vertices), but display lists and vertex buffers will perform better
|
||||
// if more geometry is rigid. There's a tradeoff, though, since the cull
|
||||
// traverser will have to do more work with additional transforms in the
|
||||
// scene graph, and this may also break up the geometry into more
|
||||
// individual pieces, which is the biggest limiting factor on modern PC
|
||||
// graphics cards.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -149,3 +149,35 @@ update_mods(ModifierButtons &mods) const {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE ButtonHandle ButtonEvent::
|
||||
get_button() const {
|
||||
return _button;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE int ButtonEvent::
|
||||
get_keycode() const {
|
||||
return _keycode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE ButtonEvent::Type ButtonEvent::
|
||||
get_type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE double ButtonEvent::
|
||||
get_time() const {
|
||||
return _time;
|
||||
}
|
||||
|
@ -44,19 +44,20 @@ class DatagramIterator;
|
||||
* character set.
|
||||
*/
|
||||
class EXPCL_PANDA_EVENT ButtonEvent {
|
||||
public:
|
||||
PUBLISHED:
|
||||
enum Type {
|
||||
/*
|
||||
* T_down and T_up represent a button changing state correspondingly.
|
||||
* T_resume_down is a special event that is only thrown when focus is returned
|
||||
* to a window and a button is detected as being held down at that point; it
|
||||
* indicates that the button should be considered down now (if it wasn't
|
||||
* already), but it didn't just get pressed down at this moment, it was
|
||||
* depressed some time ago. It's mainly used for correct tracking of modifier
|
||||
* keys like shift and control, and can be ignored for other keys.
|
||||
*/
|
||||
// T_down is sent when a button was just pressed.
|
||||
T_down,
|
||||
|
||||
// T_resume_down is a special event that is only thrown when focus is
|
||||
// returned to a window and a button is detected as being held down at that
|
||||
// point; it indicates that the button should be considered down now (if it
|
||||
// wasn't already), but it didn't just get pressed down at this moment, it
|
||||
// was depressed some time ago. It's mainly used for correct tracking of
|
||||
// modifier keys like shift and control, and can be ignored for other keys.
|
||||
T_resume_down,
|
||||
|
||||
// T_down is sent when a button is released.
|
||||
T_up,
|
||||
|
||||
// T_repeat is sent for each a keyrepeat event generated by the system,
|
||||
@ -84,6 +85,7 @@ public:
|
||||
T_raw_up,
|
||||
};
|
||||
|
||||
public:
|
||||
INLINE ButtonEvent();
|
||||
INLINE ButtonEvent(ButtonHandle button, Type type, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
INLINE ButtonEvent(int keycode, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
@ -92,17 +94,30 @@ public:
|
||||
INLINE ButtonEvent(const ButtonEvent ©);
|
||||
INLINE void operator = (const ButtonEvent ©);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE bool operator == (const ButtonEvent &other) const;
|
||||
INLINE bool operator != (const ButtonEvent &other) const;
|
||||
INLINE bool operator < (const ButtonEvent &other) const;
|
||||
|
||||
public:
|
||||
INLINE bool update_mods(ModifierButtons &mods) const;
|
||||
|
||||
INLINE ButtonHandle get_button() const;
|
||||
INLINE int get_keycode() const;
|
||||
INLINE Type get_type() const;
|
||||
INLINE double get_time() const;
|
||||
|
||||
void output(std::ostream &out) const;
|
||||
|
||||
void write_datagram(Datagram &dg) const;
|
||||
void read_datagram(DatagramIterator &scan);
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(button, get_button);
|
||||
MAKE_PROPERTY(keycode, get_keycode);
|
||||
MAKE_PROPERTY(type, get_type);
|
||||
MAKE_PROPERTY(time, get_time);
|
||||
|
||||
public:
|
||||
// _button will be filled in if type is T_down, T_resume_down, or T_up.
|
||||
ButtonHandle _button;
|
||||
|
@ -47,6 +47,8 @@ PUBLISHED:
|
||||
virtual void output(std::ostream &out) const;
|
||||
void write(std::ostream &out, int indent_level = 0) const;
|
||||
|
||||
MAKE_SEQ_PROPERTY(events, get_num_events, get_event);
|
||||
|
||||
private:
|
||||
typedef pvector<ButtonEvent> Events;
|
||||
Events _events;
|
||||
|
@ -14190,7 +14190,8 @@ upload_simple_texture(CLP(TextureContext) *gtc) {
|
||||
#endif
|
||||
GLenum external_format = GL_BGRA;
|
||||
|
||||
const unsigned char *image_ptr = tex->get_simple_ram_image();
|
||||
CPTA_uchar image = tex->get_simple_ram_image();
|
||||
const unsigned char *image_ptr = image.p();
|
||||
if (image_ptr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2911,10 +2911,13 @@ update_shader_texture_bindings(ShaderContext *prev) {
|
||||
|
||||
// Bindless texturing wasn't supported or didn't work, so let's just bind
|
||||
// the texture normally.
|
||||
// Note that simple RAM images are always 2-D for now, so to avoid errors,
|
||||
// we must load the real texture if this is not for a sampler2D.
|
||||
bool force = (spec._desired_type != Texture::TT_2d_texture);
|
||||
#ifndef OPENGLES
|
||||
if (multi_bind) {
|
||||
// Multi-bind case.
|
||||
if (!_glgsg->update_texture(gtc, false)) {
|
||||
if (!_glgsg->update_texture(gtc, force)) {
|
||||
textures[i] = 0;
|
||||
} else {
|
||||
gtc->set_active(true);
|
||||
@ -2934,7 +2937,7 @@ update_shader_texture_bindings(ShaderContext *prev) {
|
||||
{
|
||||
// Non-multibind case.
|
||||
_glgsg->set_active_texture_stage(i);
|
||||
if (!_glgsg->update_texture(gtc, false)) {
|
||||
if (!_glgsg->update_texture(gtc, force)) {
|
||||
continue;
|
||||
}
|
||||
_glgsg->apply_texture(gtc);
|
||||
|
@ -10351,10 +10351,12 @@ make_this_from_bam(const FactoryParams ¶ms) {
|
||||
// object to read all of the attributes from the bam stream.
|
||||
Texture *dummy = this;
|
||||
AutoTextureScale auto_texture_scale = ATS_unspecified;
|
||||
bool has_simple_ram_image = false;
|
||||
{
|
||||
CDWriter cdata_dummy(dummy->_cycler, true);
|
||||
dummy->do_fillin_body(cdata_dummy, scan, manager);
|
||||
auto_texture_scale = cdata_dummy->_auto_texture_scale;
|
||||
has_simple_ram_image = !cdata_dummy->_simple_ram_image._image.empty();
|
||||
}
|
||||
|
||||
if (filename.empty()) {
|
||||
@ -10387,6 +10389,61 @@ make_this_from_bam(const FactoryParams ¶ms) {
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
case TT_1d_texture_array:
|
||||
// If we don't want to preload textures, and we already have a simple
|
||||
// RAM image (or don't need one), we don't need to load it from disk.
|
||||
// We do check for it in the texture pool first, though, in case it has
|
||||
// already been loaded.
|
||||
if ((options.get_texture_flags() & LoaderOptions::TF_preload) == 0 &&
|
||||
(has_simple_ram_image || (options.get_texture_flags() & LoaderOptions::TF_preload_simple) == 0)) {
|
||||
if (alpha_filename.empty()) {
|
||||
me = TexturePool::get_texture(filename, primary_file_num_channels,
|
||||
has_read_mipmaps);
|
||||
} else {
|
||||
me = TexturePool::get_texture(filename, alpha_filename,
|
||||
primary_file_num_channels,
|
||||
alpha_file_channel,
|
||||
has_read_mipmaps);
|
||||
}
|
||||
if (me != nullptr && me->get_texture_type() == texture_type) {
|
||||
// We can use this.
|
||||
break;
|
||||
}
|
||||
|
||||
// We don't have a texture, but we didn't need to preload it, so we
|
||||
// can just use this one. We just need to know where we can find it
|
||||
// when we do need to reload it.
|
||||
Filename fullpath = filename;
|
||||
Filename alpha_fullpath = alpha_filename;
|
||||
const DSearchPath &model_path = get_model_path();
|
||||
if (vfs->resolve_filename(fullpath, model_path) &&
|
||||
(alpha_fullpath.empty() || vfs->resolve_filename(alpha_fullpath, model_path))) {
|
||||
me = dummy;
|
||||
me->set_name(name);
|
||||
|
||||
{
|
||||
CDWriter cdata_me(me->_cycler, true);
|
||||
cdata_me->_filename = filename;
|
||||
cdata_me->_alpha_filename = alpha_filename;
|
||||
cdata_me->_fullpath = fullpath;
|
||||
cdata_me->_alpha_fullpath = alpha_fullpath;
|
||||
cdata_me->_primary_file_num_channels = primary_file_num_channels;
|
||||
cdata_me->_alpha_file_channel = alpha_file_channel;
|
||||
cdata_me->_texture_type = texture_type;
|
||||
cdata_me->_loaded_from_image = true;
|
||||
cdata_me->_has_read_mipmaps = has_read_mipmaps;
|
||||
}
|
||||
|
||||
// To manage the reference count, explicitly ref it now, then unref
|
||||
// it in the finalize callback.
|
||||
me->ref();
|
||||
manager->register_finalize(me);
|
||||
|
||||
// Do add it to the cache now, so that future uses of this same
|
||||
// texture are unified.
|
||||
TexturePool::add_texture(me);
|
||||
return me;
|
||||
}
|
||||
}
|
||||
if (alpha_filename.empty()) {
|
||||
me = TexturePool::load_texture(filename, primary_file_num_channels,
|
||||
has_read_mipmaps, options);
|
||||
|
@ -33,6 +33,29 @@ verify_texture(const Filename &filename) {
|
||||
return load_texture(filename) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture that has already been previously loaded, or NULL
|
||||
* otherwise.
|
||||
*/
|
||||
INLINE Texture *TexturePool::
|
||||
get_texture(const Filename &filename, int primary_file_num_channels,
|
||||
bool read_mipmaps) {
|
||||
return get_global_ptr()->ns_get_texture(filename, primary_file_num_channels,
|
||||
read_mipmaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture that has already been previously loaded, or NULL
|
||||
* otherwise.
|
||||
*/
|
||||
INLINE Texture *TexturePool::
|
||||
get_texture(const Filename &filename, const Filename &alpha_filename,
|
||||
int primary_file_num_channels, int alpha_file_channel,
|
||||
bool read_mipmaps) {
|
||||
return get_global_ptr()->ns_get_texture(filename, primary_file_num_channels,
|
||||
read_mipmaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given filename up into a texture, if it has not already been
|
||||
* loaded, and returns the new texture. If a texture with the same filename
|
||||
|
@ -273,6 +273,62 @@ ns_has_texture(const Filename &orig_filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nonstatic implementation of get_texture().
|
||||
*/
|
||||
Texture *TexturePool::
|
||||
ns_get_texture(const Filename &orig_filename, int primary_file_num_channels,
|
||||
bool read_mipmaps) {
|
||||
LookupKey key;
|
||||
key._primary_file_num_channels = primary_file_num_channels;
|
||||
{
|
||||
MutexHolder holder(_lock);
|
||||
resolve_filename(key._fullpath, orig_filename, read_mipmaps, LoaderOptions());
|
||||
|
||||
Textures::const_iterator ti;
|
||||
ti = _textures.find(key);
|
||||
if (ti != _textures.end()) {
|
||||
// This texture was previously loaded.
|
||||
Texture *tex = (*ti).second;
|
||||
nassertr(!tex->get_fullpath().empty(), tex);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nonstatic implementation of get_texture().
|
||||
*/
|
||||
Texture *TexturePool::
|
||||
ns_get_texture(const Filename &orig_filename,
|
||||
const Filename &orig_alpha_filename,
|
||||
int primary_file_num_channels,
|
||||
int alpha_file_channel,
|
||||
bool read_mipmaps) {
|
||||
LookupKey key;
|
||||
key._primary_file_num_channels = primary_file_num_channels;
|
||||
key._alpha_file_channel = alpha_file_channel;
|
||||
{
|
||||
MutexHolder holder(_lock);
|
||||
LoaderOptions options;
|
||||
resolve_filename(key._fullpath, orig_filename, read_mipmaps, options);
|
||||
resolve_filename(key._alpha_fullpath, orig_alpha_filename, read_mipmaps, options);
|
||||
|
||||
Textures::const_iterator ti;
|
||||
ti = _textures.find(key);
|
||||
if (ti != _textures.end()) {
|
||||
// This texture was previously loaded.
|
||||
Texture *tex = (*ti).second;
|
||||
nassertr(!tex->get_fullpath().empty(), tex);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nonstatic implementation of load_texture().
|
||||
*/
|
||||
|
@ -38,6 +38,14 @@ class EXPCL_PANDA_GOBJ TexturePool {
|
||||
PUBLISHED:
|
||||
INLINE static bool has_texture(const Filename &filename);
|
||||
INLINE static bool verify_texture(const Filename &filename);
|
||||
INLINE static Texture *get_texture(const Filename &filename,
|
||||
int primary_file_num_channels = 0,
|
||||
bool read_mipmaps = false);
|
||||
INLINE static Texture *get_texture(const Filename &filename,
|
||||
const Filename &alpha_filename,
|
||||
int primary_file_num_channels = 0,
|
||||
int alpha_file_channel = 0,
|
||||
bool read_mipmaps = false);
|
||||
BLOCKING INLINE static Texture *load_texture(const Filename &filename,
|
||||
int primary_file_num_channels = 0,
|
||||
bool read_mipmaps = false,
|
||||
@ -109,6 +117,14 @@ private:
|
||||
TexturePool();
|
||||
|
||||
bool ns_has_texture(const Filename &orig_filename);
|
||||
Texture *ns_get_texture(const Filename &filename,
|
||||
int primary_file_num_channels = 0,
|
||||
bool read_mipmaps = false);
|
||||
Texture *ns_get_texture(const Filename &filename,
|
||||
const Filename &alpha_filename,
|
||||
int primary_file_num_channels = 0,
|
||||
int alpha_file_channel = 0,
|
||||
bool read_mipmaps = false);
|
||||
Texture *ns_load_texture(const Filename &orig_filename,
|
||||
int primary_file_num_channels,
|
||||
bool read_mipmaps,
|
||||
|
@ -22,28 +22,34 @@ TypeHandle TextureReloadRequest::_type_handle;
|
||||
AsyncTask::DoneStatus TextureReloadRequest::
|
||||
do_task() {
|
||||
// Don't reload the texture if it doesn't need it.
|
||||
if (_texture->was_image_modified(_pgo)) {
|
||||
double delay = async_load_delay;
|
||||
if (delay != 0.0) {
|
||||
Thread::sleep(delay);
|
||||
}
|
||||
if (!_texture->was_image_modified(_pgo) &&
|
||||
(_allow_compressed ? _texture->has_ram_image() : _texture->has_uncompressed_ram_image())) {
|
||||
return DS_done;
|
||||
}
|
||||
|
||||
if (_texture->was_image_modified(_pgo)) {
|
||||
if (_allow_compressed) {
|
||||
_texture->get_ram_image();
|
||||
} else {
|
||||
_texture->get_uncompressed_ram_image();
|
||||
}
|
||||
double delay = async_load_delay;
|
||||
if (delay != 0.0) {
|
||||
Thread::sleep(delay);
|
||||
|
||||
// Now that we've loaded the texture, we should ensure it actually gets
|
||||
// prepared--even if it's no longer visible in the frame--or it may
|
||||
// become a kind of a leak (if the texture is never rendered again on
|
||||
// this GSG, we'll just end up carrying the texture memory in RAM
|
||||
// forever, instead of dumping it as soon as it gets prepared).
|
||||
_pgo->enqueue_texture(_texture);
|
||||
if (!_texture->was_image_modified(_pgo) &&
|
||||
(_allow_compressed ? _texture->has_ram_image() : _texture->has_uncompressed_ram_image())) {
|
||||
return DS_done;
|
||||
}
|
||||
}
|
||||
|
||||
if (_allow_compressed) {
|
||||
_texture->get_ram_image();
|
||||
} else {
|
||||
_texture->get_uncompressed_ram_image();
|
||||
}
|
||||
|
||||
// Now that we've loaded the texture, we should ensure it actually gets
|
||||
// prepared--even if it's no longer visible in the frame--or it may become a
|
||||
// kind of a leak (if the texture is never rendered again on this GSG, we'll
|
||||
// just end up carrying the texture memory in RAM forever, instead of dumping
|
||||
// it as soon as it gets prepared).
|
||||
_pgo->enqueue_texture(_texture);
|
||||
|
||||
// Don't continue the task; we're done.
|
||||
return DS_done;
|
||||
}
|
||||
|
@ -106,7 +106,6 @@ set_hpr(const FLOATNAME(LVecBase3) &hpr, CoordinateSystem cs) {
|
||||
v = FLOATNAME(LVector3)::right(cs);
|
||||
a = deg_2_rad(hpr[1] * 0.5f);
|
||||
csincos(a, &s, &c);
|
||||
s = csin(a);
|
||||
quat_p.set(c, v[0] * s, v[1] * s, v[2] * s);
|
||||
v = FLOATNAME(LVector3)::forward(cs);
|
||||
a = deg_2_rad(hpr[2] * 0.5f);
|
||||
|
Loading…
x
Reference in New Issue
Block a user