Merge branch 'master' into interrogate-overhaul
This commit is contained in:
commit
b5a49efc2e
|
|
@ -132,7 +132,7 @@ typedef ios::seekdir ios_seekdir;
|
|||
# else
|
||||
# define NOEXCEPT
|
||||
# endif
|
||||
# if __has_extension(cxx_rvalue_references)
|
||||
# if __has_extension(cxx_rvalue_references) && (__cplusplus >= 201103L)
|
||||
# define USE_MOVE_SEMANTICS
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && (__cplusplus >= 201103L)
|
||||
|
|
@ -141,6 +141,11 @@ typedef ios::seekdir ios_seekdir;
|
|||
# define CONSTEXPR constexpr
|
||||
# define NOEXCEPT noexcept
|
||||
# define USE_MOVE_SEMANTICS
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
// MSVC 2010 has move semantics.
|
||||
# define CONSTEXPR INLINE
|
||||
# define NOEXCEPT throw()
|
||||
# define USE_MOVE_SEMANTICS
|
||||
#else
|
||||
# define CONSTEXPR INLINE
|
||||
# define NOEXCEPT
|
||||
|
|
|
|||
|
|
@ -234,3 +234,25 @@ INLINE size_t indirect_method_hash<Key, Compare>::
|
|||
operator () (const Key &key) const {
|
||||
return (*key).get_hash();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: indirect_equals_hash::operator ()
|
||||
// Access: Public
|
||||
// Description: Calls the Key's get_hash() method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key>
|
||||
INLINE size_t indirect_equals_hash<Key>::
|
||||
operator () (const Key &key) const {
|
||||
return (*key).get_hash();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: indirect_equals_hash::is_equal
|
||||
// Access: Public
|
||||
// Description: Returns true if a is equal to b, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key>
|
||||
INLINE bool indirect_equals_hash<Key>::
|
||||
is_equal(const Key &a, const Key &b) const {
|
||||
return (a == b || (*a) == (*b));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#include <map> // for less
|
||||
|
|
@ -212,6 +211,23 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : indirect_equals_hash
|
||||
// Description : An STL function object class, this is intended to be
|
||||
// used on any ordered collection of pointers to classes
|
||||
// that contain an operator ==() method. It defines
|
||||
// the equality of the pointers via operator ==().
|
||||
//
|
||||
// Since it doesn't define the ordering of the pointers,
|
||||
// it can only be used with hash containers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key>
|
||||
class indirect_equals_hash {
|
||||
public:
|
||||
INLINE size_t operator () (const Key &key) const;
|
||||
INLINE bool is_equal(const Key &a, const Key &b) const;
|
||||
};
|
||||
|
||||
#include "stl_compares.I"
|
||||
|
||||
typedef floating_point_hash<float> float_hash;
|
||||
|
|
@ -234,5 +250,3 @@ class indirect_compare_names_hash : public indirect_method_hash<Key, indirect_co
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#define TYPEHANDLE_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "typeRegistry.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
|
|
@ -143,7 +142,7 @@ private:
|
|||
int _index;
|
||||
static TypeHandle _none;
|
||||
|
||||
friend class TypeRegistry;
|
||||
friend class TypeRegistry;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,3 +39,30 @@ init_lock() {
|
|||
_lock = new MutexImpl;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeRegistry::look_up
|
||||
// Access: Private
|
||||
// Description: Returns the TypeRegistryNode associated with the
|
||||
// indicated TypeHandle. If there is no associated
|
||||
// TypeRegistryNode, reports an error condition and
|
||||
// returns NULL.
|
||||
//
|
||||
// The associated TypedObject pointer is the pointer to
|
||||
// the object that owns the handle, if available. It is
|
||||
// only used in an error condition, if for some reason
|
||||
// the handle was uninitialized.
|
||||
//
|
||||
// Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TypeRegistryNode *TypeRegistry::
|
||||
look_up(TypeHandle handle, TypedObject *object) const {
|
||||
#ifndef NDEBUG
|
||||
if (handle._index >= (int)_handle_registry.size() ||
|
||||
handle._index <= 0) {
|
||||
// Invalid or uninitialized type handle.
|
||||
return look_up_invalid(handle, object);
|
||||
}
|
||||
#endif
|
||||
return _handle_registry[handle._index];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ get_parent_towards(TypeHandle child, TypeHandle base,
|
|||
TypeHandle handle;
|
||||
const TypeRegistryNode *child_node = look_up(child, child_object);
|
||||
const TypeRegistryNode *base_node = look_up(base, NULL);
|
||||
assert(child_node != (TypeRegistryNode *)NULL &&
|
||||
assert(child_node != (TypeRegistryNode *)NULL &&
|
||||
base_node != (TypeRegistryNode *)NULL);
|
||||
freshen_derivations();
|
||||
handle = TypeRegistryNode::get_parent_towards(child_node, base_node);
|
||||
|
|
@ -688,22 +688,17 @@ write_node(ostream &out, int indent_level, const TypeRegistryNode *node) const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeRegistry::look_up
|
||||
// Function: TypeRegistry::look_up_invalid
|
||||
// Access: Private
|
||||
// Description: Returns the TypeRegistryNode associated with the
|
||||
// indicated TypeHandle. If there is no associated
|
||||
// TypeRegistryNode, reports an error condition and
|
||||
// returns NULL.
|
||||
//
|
||||
// The associated TypedObject pointer is the pointer to
|
||||
// the object that owns the handle, if available. It is
|
||||
// only used in an error condition, if for some reason
|
||||
// the handle was uninitialized.
|
||||
// Description: Called by look_up when it detects an invalid
|
||||
// TypeHandle pointer. In non-release builds, this
|
||||
// method will do what it can to recover from this
|
||||
// and initialize the type anyway.
|
||||
//
|
||||
// Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeRegistryNode *TypeRegistry::
|
||||
look_up(TypeHandle handle, TypedObject *object) const {
|
||||
look_up_invalid(TypeHandle handle, TypedObject *object) const {
|
||||
#ifndef NDEBUG
|
||||
if (handle._index == 0) {
|
||||
// The TypeHandle is unregistered. This is an error condition.
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ private:
|
|||
TypeRegistry();
|
||||
|
||||
static void init_global_pointer();
|
||||
TypeRegistryNode *look_up(TypeHandle type, TypedObject *object) const;
|
||||
INLINE TypeRegistryNode *look_up(TypeHandle type, TypedObject *object) const;
|
||||
TypeRegistryNode *look_up_invalid(TypeHandle type, TypedObject *object) const;
|
||||
|
||||
INLINE void freshen_derivations();
|
||||
void rebuild_derivations();
|
||||
|
|
@ -120,6 +121,8 @@ private:
|
|||
// Helper function to allow for "C" interaction into the type system
|
||||
extern "C" EXPCL_DTOOL int get_best_parent_from_Set(int id, const std::set<int> &this_set);
|
||||
|
||||
#include "typeHandle.h"
|
||||
|
||||
#include "typeRegistry.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,11 +48,6 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) {
|
|||
// code. Therefore, we go through some pains to make this function
|
||||
// as efficient as possible.
|
||||
|
||||
// (Actually, it appears that the function is not called as often as
|
||||
// I'd first thought, and it wasn't really all that expensive to
|
||||
// begin with. So much of this complexity is of limited usefulness.
|
||||
// Oh well.)
|
||||
|
||||
// First, compare the subtree tops. If they are the same, then this
|
||||
// node and the base node are within the same single-inheritance
|
||||
// subtree, and we can use our bitmask trick to determine the
|
||||
|
|
|
|||
|
|
@ -1953,7 +1953,7 @@ DTOOL_CONFIG=[
|
|||
("DO_PSTATS", 'UNDEF', 'UNDEF'),
|
||||
("DO_DCAST", 'UNDEF', 'UNDEF'),
|
||||
("DO_COLLISION_RECORDING", 'UNDEF', 'UNDEF'),
|
||||
("SUPPORT_IMMEDIATE_MODE", '1', '1'),
|
||||
("SUPPORT_IMMEDIATE_MODE", 'UNDEF', 'UNDEF'),
|
||||
("TRACK_IN_INTERPRETER", 'UNDEF', 'UNDEF'),
|
||||
("DO_MEMORY_USAGE", 'UNDEF', 'UNDEF'),
|
||||
("DO_PIPELINING", '1', '1'),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#ifdef HAVE_FMODEX //[
|
||||
|
||||
#include "config_fmodAudio.h"
|
||||
#include "audioManager.h"
|
||||
|
|
@ -73,5 +72,3 @@ get_audio_manager_func_fmod_audio() {
|
|||
init_libFmodAudio();
|
||||
return &Create_FmodAudioManager;
|
||||
}
|
||||
|
||||
#endif //]
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_FMODEX //[
|
||||
#include "notifyCategoryProxy.h"
|
||||
#include "dconfig.h"
|
||||
#include "audioManager.h"
|
||||
|
|
@ -30,6 +29,4 @@ extern ConfigVariableInt fmod_audio_preload_threshold;
|
|||
extern EXPCL_FMOD_AUDIO void init_libFmodAudio();
|
||||
extern "C" EXPCL_FMOD_AUDIO Create_AudioManager_proc *get_audio_manager_func_fmod_audio();
|
||||
|
||||
#endif //]
|
||||
|
||||
#endif // CONFIG_FMODAUDIO_H
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "renderState.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
#include "config_pgraph.h"
|
||||
|
||||
#include "cullTraverser.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawCullHandler::record_object
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class EXPCL_PANDA_CULL DrawCullHandler : public CullHandler {
|
|||
public:
|
||||
INLINE DrawCullHandler(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
virtual void record_object(CullableObject *object,
|
||||
virtual void record_object(CullableObject *object,
|
||||
const CullTraverser *traverser);
|
||||
|
||||
private:
|
||||
|
|
@ -46,5 +46,3 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -365,6 +365,9 @@ set_coordinate_system(CoordinateSystem cs) {
|
|||
if (cs == CS_default) {
|
||||
cs = get_default_coordinate_system();
|
||||
}
|
||||
if (_coordinate_system == cs) {
|
||||
return;
|
||||
}
|
||||
_coordinate_system = cs;
|
||||
|
||||
// Changing the external coordinate system changes the cs_transform.
|
||||
|
|
@ -1041,7 +1044,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
return &t;
|
||||
}
|
||||
case Shader::SMO_attr_material: {
|
||||
const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()));
|
||||
const MaterialAttrib *target_material = (const MaterialAttrib *)
|
||||
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
|
||||
// Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
|
||||
if (target_material->is_off()) {
|
||||
t = LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
|
||||
|
|
@ -1060,7 +1064,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
return &t;
|
||||
}
|
||||
case Shader::SMO_attr_color: {
|
||||
const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot()));
|
||||
const ColorAttrib *target_color = (const ColorAttrib *)
|
||||
_target_rs->get_attrib_def(ColorAttrib::get_class_slot());
|
||||
if (target_color->get_color_type() != ColorAttrib::T_flat) {
|
||||
return &LMatrix4::ones_mat();
|
||||
}
|
||||
|
|
@ -1069,7 +1074,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
return &t;
|
||||
}
|
||||
case Shader::SMO_attr_colorscale: {
|
||||
const ColorScaleAttrib *target_color = DCAST(ColorScaleAttrib, _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()));
|
||||
const ColorScaleAttrib *target_color = (const ColorScaleAttrib *)
|
||||
_target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
|
||||
if (target_color->is_identity()) {
|
||||
return &LMatrix4::ones_mat();
|
||||
}
|
||||
|
|
@ -1078,7 +1084,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
return &t;
|
||||
}
|
||||
case Shader::SMO_attr_fog: {
|
||||
const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
|
||||
const FogAttrib *target_fog = (const FogAttrib *)
|
||||
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
|
||||
Fog *fog = target_fog->get_fog();
|
||||
if (fog == (Fog*) NULL) {
|
||||
return &LMatrix4::ones_mat();
|
||||
|
|
@ -1089,7 +1096,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
return &t;
|
||||
}
|
||||
case Shader::SMO_attr_fogcolor: {
|
||||
const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
|
||||
const FogAttrib *target_fog = (const FogAttrib *)
|
||||
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
|
||||
Fog *fog = target_fog->get_fog();
|
||||
if (fog == (Fog*) NULL) {
|
||||
return &LMatrix4::ones_mat();
|
||||
|
|
@ -2074,8 +2082,12 @@ get_render_buffer(int buffer_type, const FrameBufferProperties &prop) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) GraphicsStateGuardian::
|
||||
get_cs_transform_for(CoordinateSystem cs) const {
|
||||
if (_internal_coordinate_system == CS_default ||
|
||||
_internal_coordinate_system == cs) {
|
||||
if (_coordinate_system == cs) {
|
||||
// We've already calculated this.
|
||||
return _cs_transform;
|
||||
|
||||
} else if (_internal_coordinate_system == CS_default ||
|
||||
_internal_coordinate_system == cs) {
|
||||
return TransformState::make_identity();
|
||||
|
||||
} else {
|
||||
|
|
@ -2111,7 +2123,9 @@ do_issue_clip_plane() {
|
|||
int num_enabled = 0;
|
||||
int num_on_planes = 0;
|
||||
|
||||
const ClipPlaneAttrib *target_clip_plane = DCAST(ClipPlaneAttrib, _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
|
||||
const ClipPlaneAttrib *target_clip_plane = (const ClipPlaneAttrib *)
|
||||
_target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
|
||||
|
||||
if (target_clip_plane != (ClipPlaneAttrib *)NULL) {
|
||||
CPT(ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
|
||||
|
||||
|
|
@ -2171,7 +2185,9 @@ do_issue_clip_plane() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
do_issue_color() {
|
||||
const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot()));
|
||||
const ColorAttrib *target_color = (const ColorAttrib *)
|
||||
_target_rs->get_attrib_def(ColorAttrib::get_class_slot());
|
||||
|
||||
switch (target_color->get_color_type()) {
|
||||
case ColorAttrib::T_flat:
|
||||
// Color attribute flat: it specifies a scene graph color that
|
||||
|
|
@ -2219,7 +2235,9 @@ do_issue_color_scale() {
|
|||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
|
||||
const ColorScaleAttrib *target_color_scale = DCAST(ColorScaleAttrib, _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()));
|
||||
const ColorScaleAttrib *target_color_scale = (const ColorScaleAttrib *)
|
||||
_target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
|
||||
|
||||
_color_scale_enabled = target_color_scale->has_scale();
|
||||
_current_color_scale = target_color_scale->get_scale();
|
||||
_has_texture_alpha_scale = false;
|
||||
|
|
@ -2278,7 +2296,9 @@ do_issue_light() {
|
|||
int num_enabled = 0;
|
||||
int num_on_lights = 0;
|
||||
|
||||
const LightAttrib *target_light = DCAST(LightAttrib, _target_rs->get_attrib_def(LightAttrib::get_class_slot()));
|
||||
const LightAttrib *target_light = (const LightAttrib *)
|
||||
_target_rs->get_attrib_def(LightAttrib::get_class_slot());
|
||||
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
<< "do_issue_light: " << target_light << "\n";
|
||||
|
|
@ -2639,8 +2659,10 @@ end_bind_clip_planes() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
determine_target_texture() {
|
||||
const TextureAttrib *target_texture = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
|
||||
const TexGenAttrib *target_tex_gen = DCAST(TexGenAttrib, _target_rs->get_attrib_def(TexGenAttrib::get_class_slot()));
|
||||
const TextureAttrib *target_texture = (const TextureAttrib *)
|
||||
_target_rs->get_attrib_def(TextureAttrib::get_class_slot());
|
||||
const TexGenAttrib *target_tex_gen = (const TexGenAttrib *)
|
||||
_target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
|
||||
|
||||
nassertv(target_texture != (TextureAttrib *)NULL &&
|
||||
target_tex_gen != (TexGenAttrib *)NULL);
|
||||
|
|
|
|||
|
|
@ -366,3 +366,20 @@ INLINE void MemoryUsage::
|
|||
show_trend_ages() {
|
||||
get_global_ptr()->ns_show_trend_ages();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MemoryUsage::get_global_ptr
|
||||
// Access: Private, Static
|
||||
// Description: Returns the pointer to the only MemoryUsage object in
|
||||
// the world.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MemoryUsage *MemoryUsage::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (MemoryUsage *)NULL) {
|
||||
init_memory_hook();
|
||||
_global_ptr = new MemoryUsage(*memory_hook);
|
||||
memory_hook = _global_ptr;
|
||||
}
|
||||
|
||||
return _global_ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,24 +564,6 @@ overflow_heap_size() {
|
|||
_report_memory_usage = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MemoryUsage::get_global_ptr
|
||||
// Access: Private, Static
|
||||
// Description: Returns the pointer to the only MemoryUsage object in
|
||||
// the world.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MemoryUsage *MemoryUsage::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (MemoryUsage *)NULL) {
|
||||
init_memory_hook();
|
||||
_global_ptr = new MemoryUsage(*memory_hook);
|
||||
memory_hook = _global_ptr;
|
||||
}
|
||||
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MemoryUsage::ns_record_pointer
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ protected:
|
|||
|
||||
private:
|
||||
MemoryUsage(const MemoryHook ©);
|
||||
static MemoryUsage *get_global_ptr();
|
||||
INLINE static MemoryUsage *get_global_ptr();
|
||||
|
||||
void ns_record_pointer(ReferenceCount *ptr);
|
||||
void ns_update_type(ReferenceCount *ptr, TypeHandle type);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,36 @@ INLINE NodePointerTo<T>::
|
|||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerTo::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodePointerTo<T>::
|
||||
NodePointerTo(NodePointerTo<T> &&from) NOEXCEPT :
|
||||
NodePointerToBase<T>((NodePointerToBase<T> &&)from)
|
||||
{
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerTo::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodePointerTo<T> &NodePointerTo<T>::
|
||||
operator = (NodePointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerTo::Dereference operator
|
||||
|
|
@ -192,6 +222,64 @@ INLINE NodeConstPointerTo<T>::
|
|||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeConstPointerTo::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodeConstPointerTo<T>::
|
||||
NodeConstPointerTo(NodePointerTo<T> &&from) NOEXCEPT :
|
||||
NodePointerToBase<T>((NodePointerToBase<T> &&)from)
|
||||
{
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeConstPointerTo::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodeConstPointerTo<T>::
|
||||
NodeConstPointerTo(NodeConstPointerTo<T> &&from) NOEXCEPT :
|
||||
NodePointerToBase<T>((NodePointerToBase<T> &&)from)
|
||||
{
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeConstPointerTo::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodeConstPointerTo<T> &NodeConstPointerTo<T>::
|
||||
operator = (NodePointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeConstPointerTo::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodeConstPointerTo<T> &NodeConstPointerTo<T>::
|
||||
operator = (NodeConstPointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeConstPointerTo::Dereference operator
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ public:
|
|||
INLINE NodePointerTo(const NodePointerTo<T> ©);
|
||||
INLINE ~NodePointerTo();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE NodePointerTo(NodePointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE NodePointerTo<T> &operator = (NodePointerTo<T> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE To &operator *() const;
|
||||
INLINE To *operator -> () const;
|
||||
|
||||
|
|
@ -67,6 +72,13 @@ public:
|
|||
INLINE NodeConstPointerTo(const NodeConstPointerTo<T> ©);
|
||||
INLINE ~NodeConstPointerTo();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE NodeConstPointerTo(NodePointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE NodeConstPointerTo(NodeConstPointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE NodeConstPointerTo<T> &operator = (NodePointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE NodeConstPointerTo<T> &operator = (NodeConstPointerTo<T> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE const To &operator *() const;
|
||||
INLINE const To *operator -> () const;
|
||||
INLINE operator const T *() const;
|
||||
|
|
@ -79,6 +91,16 @@ public:
|
|||
#endif // CPPPARSER
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void swap(NodePointerTo<T> &one, NodePointerTo<T> &two) NOEXCEPT {
|
||||
one.swap(two);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(NodeConstPointerTo<T> &one, NodeConstPointerTo<T> &two) NOEXCEPT {
|
||||
one.swap(two);
|
||||
}
|
||||
|
||||
#define NPT(type) NodePointerTo< type >
|
||||
#define NCPT(type) NodeConstPointerTo< type >
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,43 @@ INLINE NodePointerToBase<T>::
|
|||
reassign((To *)NULL);
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerToBase::Move Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE NodePointerToBase<T>::
|
||||
NodePointerToBase(NodePointerToBase<T> &&from) NOEXCEPT {
|
||||
_void_ptr = from._void_ptr;
|
||||
from._void_ptr = (void *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerToBase::reassign
|
||||
// Access: Protected
|
||||
// Description: This version of reassign is called when a
|
||||
// NodePointerTo is assigned to this Node PointerTo
|
||||
// as an rvalue. In this case, we can steal the
|
||||
// reference count from the other PointerTo, without
|
||||
// needing to call ref() and unref() unnecessarily.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE void NodePointerToBase<T>::
|
||||
reassign(NodePointerToBase<T> &&from) NOEXCEPT {
|
||||
To *old_ptr = (To *)this->_void_ptr;
|
||||
|
||||
this->_void_ptr = from._void_ptr;
|
||||
from._void_ptr = NULL;
|
||||
|
||||
// Now delete the old pointer.
|
||||
if (old_ptr != (To *)NULL) {
|
||||
node_unref_delete(old_ptr);
|
||||
}
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePointerToBase::reassign
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ protected:
|
|||
INLINE NodePointerToBase(const NodePointerToBase<T> ©);
|
||||
INLINE ~NodePointerToBase();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE NodePointerToBase(NodePointerToBase<T> &&from) NOEXCEPT;
|
||||
INLINE void reassign(NodePointerToBase<To> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
void reassign(To *ptr);
|
||||
INLINE void reassign(const NodePointerToBase<To> ©);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ PointerTo(const PointerTo<T> ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE PointerTo<T>::
|
||||
PointerTo(PointerTo<T> &&move) NOEXCEPT :
|
||||
PointerToBase<T>((PointerToBase<T> &&)move)
|
||||
PointerTo(PointerTo<T> &&from) NOEXCEPT :
|
||||
PointerToBase<T>(move(from))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -55,19 +55,11 @@ PointerTo(PointerTo<T> &&move) NOEXCEPT :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE PointerTo<T> &PointerTo<T>::
|
||||
operator = (PointerTo<T> &&move) NOEXCEPT {
|
||||
To *old_ptr = (To *)this->_void_ptr;
|
||||
|
||||
this->_void_ptr = move._void_ptr;
|
||||
move._void_ptr = NULL;
|
||||
|
||||
if (old_ptr != (To *)NULL) {
|
||||
unref_delete(old_ptr);
|
||||
}
|
||||
|
||||
operator = (PointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerTo::Destructor
|
||||
|
|
@ -208,8 +200,20 @@ ConstPointerTo(const ConstPointerTo<T> ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE ConstPointerTo<T>::
|
||||
ConstPointerTo(ConstPointerTo<T> &&move) NOEXCEPT :
|
||||
PointerToBase<T>((PointerToBase<T> &&)move)
|
||||
ConstPointerTo(PointerTo<T> &&from) NOEXCEPT :
|
||||
PointerToBase<T>(move(from))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerTo::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE ConstPointerTo<T>::
|
||||
ConstPointerTo(ConstPointerTo<T> &&from) NOEXCEPT :
|
||||
PointerToBase<T>(move(from))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -220,19 +224,23 @@ ConstPointerTo(ConstPointerTo<T> &&move) NOEXCEPT :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE ConstPointerTo<T> &ConstPointerTo<T>::
|
||||
operator = (ConstPointerTo<T> &&move) NOEXCEPT {
|
||||
To *old_ptr = (To *)this->_void_ptr;
|
||||
|
||||
this->_void_ptr = move._void_ptr;
|
||||
move._void_ptr = NULL;
|
||||
|
||||
if (old_ptr != (To *)NULL) {
|
||||
unref_delete(old_ptr);
|
||||
}
|
||||
|
||||
operator = (PointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerTo::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE ConstPointerTo<T> &ConstPointerTo<T>::
|
||||
operator = (ConstPointerTo<T> &&from) NOEXCEPT {
|
||||
this->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerTo::Dereference operator
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerTo(PointerTo<T> &&move) NOEXCEPT;
|
||||
INLINE PointerTo<T> &operator = (PointerTo<T> &&move) NOEXCEPT;
|
||||
INLINE PointerTo(PointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE PointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE To &operator *() const;
|
||||
|
|
@ -150,8 +150,10 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE ConstPointerTo(ConstPointerTo<T> &&move) NOEXCEPT;
|
||||
INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&move) NOEXCEPT;
|
||||
INLINE ConstPointerTo(PointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerTo(ConstPointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE const To &operator *() const;
|
||||
|
|
@ -177,12 +179,12 @@ PUBLISHED:
|
|||
// of PointerTo objects without incurring the cost of unnecessary
|
||||
// reference count changes. The performance difference is dramatic!
|
||||
template <class T>
|
||||
void swap(PointerTo<T> &one, PointerTo<T> &two) {
|
||||
void swap(PointerTo<T> &one, PointerTo<T> &two) NOEXCEPT {
|
||||
one.swap(two);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(ConstPointerTo<T> &one, ConstPointerTo<T> &two) {
|
||||
void swap(ConstPointerTo<T> &one, ConstPointerTo<T> &two) NOEXCEPT {
|
||||
one.swap(two);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,6 @@ PointerToBase(const PointerToBase<T> ©) {
|
|||
reassign(copy);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToBase::Move Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
template<class T>
|
||||
INLINE PointerToBase<T>::
|
||||
PointerToBase(PointerToBase<T> &&move) NOEXCEPT {
|
||||
_void_ptr = move._void_ptr;
|
||||
move._void_ptr = (void *)NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToBase::Destructor
|
||||
// Access: Protected
|
||||
|
|
@ -60,6 +46,43 @@ INLINE PointerToBase<T>::
|
|||
reassign((To *)NULL);
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToBase::Move Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE PointerToBase<T>::
|
||||
PointerToBase(PointerToBase<T> &&from) NOEXCEPT {
|
||||
_void_ptr = from._void_ptr;
|
||||
from._void_ptr = (void *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToBase::reassign
|
||||
// Access: Protected
|
||||
// Description: This version of reassign is called when a PointerTo
|
||||
// is assigned to this PointerTo as an rvalue. In
|
||||
// this case, we can steal the reference count from
|
||||
// the other PointerTo, without needing to call ref()
|
||||
// and unref() unnecessarily.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE void PointerToBase<T>::
|
||||
reassign(PointerToBase<T> &&from) NOEXCEPT {
|
||||
To *old_ptr = (To *)this->_void_ptr;
|
||||
|
||||
this->_void_ptr = from._void_ptr;
|
||||
from._void_ptr = NULL;
|
||||
|
||||
// Now delete the old pointer.
|
||||
if (old_ptr != (To *)NULL) {
|
||||
unref_delete(old_ptr);
|
||||
}
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToBase::reassign
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ protected:
|
|||
INLINE ~PointerToBase();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerToBase(PointerToBase<T> &&move) NOEXCEPT;
|
||||
INLINE PointerToBase(PointerToBase<T> &&from) NOEXCEPT;
|
||||
INLINE void reassign(PointerToBase<To> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE void reassign(To *ptr);
|
||||
|
|
|
|||
|
|
@ -110,8 +110,13 @@ operator != (const PointerToVoid &other) const {
|
|||
// Access: Public
|
||||
// Description: Swaps the contents of this PointerTo with the other,
|
||||
// without touching the reference counts.
|
||||
//
|
||||
// For internal use only. Use the global swap()
|
||||
// function instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PointerToVoid::
|
||||
swap(PointerToVoid &other) {
|
||||
std::swap(_void_ptr, other._void_ptr);
|
||||
swap(PointerToVoid &other) NOEXCEPT {
|
||||
AtomicAdjust::Pointer temp = _void_ptr;
|
||||
_void_ptr = other._void_ptr;
|
||||
other._void_ptr = temp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
INLINE bool operator == (const PointerToVoid &other) const;
|
||||
INLINE bool operator != (const PointerToVoid &other) const;
|
||||
|
||||
INLINE void swap(PointerToVoid &other);
|
||||
INLINE void swap(PointerToVoid &other) NOEXCEPT;
|
||||
|
||||
protected:
|
||||
// Within the PointerToVoid class, we only store a void pointer.
|
||||
|
|
|
|||
|
|
@ -2288,6 +2288,7 @@ clear(DrawableRegion *clearable) {
|
|||
return;
|
||||
}
|
||||
|
||||
//XXX rdb: Is this line really necessary?
|
||||
set_state_and_transform(RenderState::make_empty(), _internal_transform);
|
||||
|
||||
int mask = 0;
|
||||
|
|
@ -2842,7 +2843,7 @@ end_frame(Thread *current_thread) {
|
|||
|
||||
// Now is a good time to delete any pending display lists.
|
||||
#ifndef OPENGLES
|
||||
{
|
||||
if (display_lists) {
|
||||
LightMutexHolder holder(_lock);
|
||||
if (!_deleted_display_lists.empty()) {
|
||||
DeletedNames::iterator ddli;
|
||||
|
|
@ -2857,10 +2858,13 @@ end_frame(Thread *current_thread) {
|
|||
}
|
||||
_deleted_display_lists.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// And deleted queries, too, unless we're using query timers
|
||||
// in which case we'll need to reuse lots of them.
|
||||
if (!get_timer_queries_active() && !_deleted_queries.empty()) {
|
||||
// And deleted queries, too, unless we're using query timers
|
||||
// in which case we'll need to reuse lots of them.
|
||||
if (_supports_occlusion_query && !get_timer_queries_active()) {
|
||||
LightMutexHolder holder(_lock);
|
||||
if (!_deleted_queries.empty()) {
|
||||
if (GLCAT.is_spam()) {
|
||||
DeletedNames::iterator dqi;
|
||||
for (dqi = _deleted_queries.begin();
|
||||
|
|
@ -5122,9 +5126,9 @@ issue_timer_query(int pstats_index) {
|
|||
// Issue the timestamp query.
|
||||
_glQueryCounter(query->_index, GL_TIMESTAMP);
|
||||
|
||||
_pending_timer_queries.push_back(DCAST(TimerQueryContext, query));
|
||||
_pending_timer_queries.push_back((TimerQueryContext *)query);
|
||||
|
||||
return DCAST(TimerQueryContext, query);
|
||||
return (TimerQueryContext *)query;
|
||||
|
||||
#else
|
||||
return NULL;
|
||||
|
|
@ -5637,7 +5641,9 @@ do_issue_transform() {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_shade_model() {
|
||||
#ifndef OPENGLES_2
|
||||
const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot()));
|
||||
const ShadeModelAttrib *target_shade_model = (const ShadeModelAttrib *)
|
||||
_target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot());
|
||||
|
||||
switch (target_shade_model->get_mode()) {
|
||||
case ShadeModelAttrib::M_smooth:
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
|
@ -5720,7 +5726,9 @@ do_issue_shader(bool state_has_changed) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_render_mode() {
|
||||
const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot()));
|
||||
const RenderModeAttrib *target_render_mode = (const RenderModeAttrib *)
|
||||
_target_rs->get_attrib_def(RenderModeAttrib::get_class_slot());
|
||||
|
||||
_render_mode = target_render_mode->get_mode();
|
||||
_point_size = target_render_mode->get_thickness();
|
||||
_point_perspective = target_render_mode->get_perspective();
|
||||
|
|
@ -5764,7 +5772,9 @@ do_issue_render_mode() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_antialias() {
|
||||
const AntialiasAttrib *target_antialias = DCAST(AntialiasAttrib, _target_rs->get_attrib_def(AntialiasAttrib::get_class_slot()));
|
||||
const AntialiasAttrib *target_antialias = (const AntialiasAttrib *)
|
||||
_target_rs->get_attrib_def(AntialiasAttrib::get_class_slot());
|
||||
|
||||
if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
|
||||
// In this special mode, we must enable antialiasing on a
|
||||
// case-by-case basis, because we enable it differently for
|
||||
|
|
@ -5830,7 +5840,9 @@ do_issue_antialias() {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_rescale_normal() {
|
||||
#ifndef OPENGLES_2 // OpenGL ES 2.0 doesn't support rescaling normals.
|
||||
const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot()));
|
||||
const RescaleNormalAttrib *target_rescale_normal = (const RescaleNormalAttrib *)
|
||||
_target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot());
|
||||
|
||||
RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
|
||||
|
||||
_auto_rescale_normal = false;
|
||||
|
|
@ -5882,7 +5894,9 @@ do_issue_rescale_normal() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_depth_test() {
|
||||
const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot()));
|
||||
const DepthTestAttrib *target_depth_test = (const DepthTestAttrib *)
|
||||
_target_rs->get_attrib_def(DepthTestAttrib::get_class_slot());
|
||||
|
||||
DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
|
||||
if (mode == DepthTestAttrib::M_none) {
|
||||
enable_depth_test(false);
|
||||
|
|
@ -5903,7 +5917,9 @@ do_issue_alpha_test() {
|
|||
if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
|
||||
enable_alpha_test(false);
|
||||
} else {
|
||||
const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot()));
|
||||
const AlphaTestAttrib *target_alpha_test = (const AlphaTestAttrib *)
|
||||
_target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot());
|
||||
|
||||
AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
|
||||
if (mode == AlphaTestAttrib::M_none) {
|
||||
enable_alpha_test(false);
|
||||
|
|
@ -5924,7 +5940,9 @@ do_issue_alpha_test() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_depth_write() {
|
||||
const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot()));
|
||||
const DepthWriteAttrib *target_depth_write = (const DepthWriteAttrib *)
|
||||
_target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot());
|
||||
|
||||
DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
|
||||
if (mode == DepthWriteAttrib::M_off) {
|
||||
#ifdef GSG_VERBOSE
|
||||
|
|
@ -5949,7 +5967,9 @@ do_issue_depth_write() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_cull_face() {
|
||||
const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot()));
|
||||
const CullFaceAttrib *target_cull_face = (const CullFaceAttrib *)
|
||||
_target_rs->get_attrib_def(CullFaceAttrib::get_class_slot());
|
||||
|
||||
CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
|
||||
|
||||
switch (mode) {
|
||||
|
|
@ -5979,7 +5999,9 @@ do_issue_cull_face() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_fog() {
|
||||
const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
|
||||
const FogAttrib *target_fog = (const FogAttrib *)
|
||||
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
|
||||
|
||||
if (!target_fog->is_off()) {
|
||||
enable_fog(true);
|
||||
Fog *fog = target_fog->get_fog();
|
||||
|
|
@ -5998,7 +6020,9 @@ do_issue_fog() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_depth_offset() {
|
||||
const DepthOffsetAttrib *target_depth_offset = DCAST(DepthOffsetAttrib, _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot()));
|
||||
const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
|
||||
_target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
|
||||
|
||||
int offset = target_depth_offset->get_offset();
|
||||
|
||||
if (offset != 0) {
|
||||
|
|
@ -6039,7 +6063,8 @@ do_issue_material() {
|
|||
static Material empty;
|
||||
const Material *material;
|
||||
|
||||
const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()));
|
||||
const MaterialAttrib *target_material = (const MaterialAttrib *)
|
||||
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
|
||||
|
||||
if (target_material == (MaterialAttrib *)NULL ||
|
||||
target_material->is_off()) {
|
||||
|
|
@ -6146,7 +6171,8 @@ do_issue_blending() {
|
|||
// all the other blending-related stuff doesn't matter. If the
|
||||
// device doesn't support color-write, we use blending tricks
|
||||
// to effectively disable color write.
|
||||
const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot()));
|
||||
const ColorWriteAttrib *target_color_write = (const ColorWriteAttrib *)
|
||||
_target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot());
|
||||
|
||||
unsigned int color_channels =
|
||||
target_color_write->get_channels() & _color_write_mask;
|
||||
|
|
@ -6176,11 +6202,13 @@ do_issue_blending() {
|
|||
}
|
||||
|
||||
|
||||
const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot()));
|
||||
const ColorBlendAttrib *target_color_blend = (const ColorBlendAttrib *)
|
||||
_target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot());
|
||||
CPT(ColorBlendAttrib) color_blend = target_color_blend;
|
||||
ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
|
||||
|
||||
const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot()));
|
||||
const TransparencyAttrib *target_transparency = (const TransparencyAttrib *)
|
||||
_target_rs->get_attrib_def(TransparencyAttrib::get_class_slot());
|
||||
TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
|
||||
|
||||
_color_blend_involves_color_scale = color_blend->involves_color_scale();
|
||||
|
|
@ -8731,7 +8759,8 @@ set_state_and_transform(const RenderState *target,
|
|||
}
|
||||
_target_rs = target;
|
||||
|
||||
_target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
|
||||
_target_shader = (const ShaderAttrib *)
|
||||
_target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
|
||||
#ifndef OPENGLES
|
||||
_instance_count = _target_shader->get_instance_count();
|
||||
#endif
|
||||
|
|
@ -9558,7 +9587,9 @@ do_issue_tex_matrix() {
|
|||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
|
||||
const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
|
||||
const TexMatrixAttrib *target_tex_matrix = (const TexMatrixAttrib *)
|
||||
_target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot());
|
||||
|
||||
if (target_tex_matrix->has_stage(stage)) {
|
||||
GLPf(LoadMatrix)(target_tex_matrix->get_mat(stage).get_data());
|
||||
} else {
|
||||
|
|
@ -11886,7 +11917,8 @@ do_issue_stencil() {
|
|||
return;
|
||||
}
|
||||
|
||||
const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib(StencilAttrib::get_class_slot()));
|
||||
const StencilAttrib *stencil = (const StencilAttrib *)
|
||||
_target_rs->get_attrib(StencilAttrib::get_class_slot());
|
||||
|
||||
if (stencil != (const StencilAttrib *)NULL) {
|
||||
// DEBUG
|
||||
|
|
@ -11974,7 +12006,8 @@ do_issue_stencil() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_scissor() {
|
||||
const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot()));
|
||||
const ScissorAttrib *target_scissor = (const ScissorAttrib *)
|
||||
_target_rs->get_attrib_def(ScissorAttrib::get_class_slot());
|
||||
|
||||
if (!target_scissor->is_off()) {
|
||||
// A non-off ScissorAttrib means to override the scissor setting
|
||||
|
|
|
|||
|
|
@ -380,14 +380,14 @@ clear_bounds() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Geom::
|
||||
calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
|
||||
do_calc_tight_bounds(min_point, max_point, found_any,
|
||||
vertex_data, got_mat, mat,
|
||||
|
||||
do_calc_tight_bounds(min_point, max_point, found_any,
|
||||
vertex_data, got_mat, mat,
|
||||
InternalName::get_vertex(),
|
||||
cdata, current_thread);
|
||||
}
|
||||
|
|
@ -409,7 +409,7 @@ INLINE void Geom::
|
|||
calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any, Thread *current_thread) const {
|
||||
calc_tight_bounds(min_point, max_point, found_any,
|
||||
get_vertex_data(current_thread), false,
|
||||
get_vertex_data(current_thread), false,
|
||||
LMatrix4::ident_mat(),
|
||||
current_thread);
|
||||
}
|
||||
|
|
@ -422,15 +422,15 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Geom::
|
||||
calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
const InternalName *column_name,
|
||||
Thread *current_thread) const {
|
||||
CDReader cdata(_cycler, current_thread);
|
||||
|
||||
do_calc_tight_bounds(min_point, max_point, found_any,
|
||||
vertex_data, got_mat, mat,
|
||||
|
||||
do_calc_tight_bounds(min_point, max_point, found_any,
|
||||
vertex_data, got_mat, mat,
|
||||
column_name, cdata, current_thread);
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +450,7 @@ mark_internal_bounds_stale(CData *cdata) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CDataCache::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CDataCache::
|
||||
CDataCache() :
|
||||
|
|
@ -463,7 +463,7 @@ CDataCache() :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CDataCache::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CDataCache::
|
||||
CDataCache(const Geom::CDataCache ©) :
|
||||
|
|
@ -500,7 +500,7 @@ set_result(const Geom *geom_result, const GeomVertexData *data_result) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheKey::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheKey::
|
||||
CacheKey(const GeomVertexData *source_data, const GeomMunger *modifier) :
|
||||
|
|
@ -509,6 +509,32 @@ CacheKey(const GeomVertexData *source_data, const GeomMunger *modifier) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheKey::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheKey::
|
||||
CacheKey(const CacheKey ©) :
|
||||
_source_data(copy._source_data),
|
||||
_modifier(copy._modifier)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheKey::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheKey::
|
||||
CacheKey(CacheKey &&from) NOEXCEPT :
|
||||
_source_data(move(from._source_data)),
|
||||
_modifier(move(from._modifier))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheKey::operator <
|
||||
// Access: Public
|
||||
|
|
@ -531,7 +557,7 @@ operator < (const CacheKey &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheEntry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheEntry::
|
||||
CacheEntry(Geom *source, const GeomVertexData *source_data,
|
||||
|
|
@ -541,6 +567,31 @@ CacheEntry(Geom *source, const GeomVertexData *source_data,
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheEntry::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheEntry::
|
||||
CacheEntry(Geom *source, const Geom::CacheKey &key) :
|
||||
_source(source),
|
||||
_key(key)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CacheEntry::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::CacheEntry::
|
||||
CacheEntry(Geom *source, Geom::CacheKey &&key) NOEXCEPT :
|
||||
_source(source),
|
||||
_key(move(key))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::CData::Constructor
|
||||
|
|
@ -667,7 +718,7 @@ get_current_thread() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_primitive_type
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::PrimitiveType GeomPipelineReader::
|
||||
get_primitive_type() const {
|
||||
|
|
@ -677,7 +728,7 @@ get_primitive_type() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_shade_model
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::ShadeModel GeomPipelineReader::
|
||||
get_shade_model() const {
|
||||
|
|
@ -687,7 +738,7 @@ get_shade_model() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_geom_rendering
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPipelineReader::
|
||||
get_geom_rendering() const {
|
||||
|
|
@ -697,7 +748,7 @@ get_geom_rendering() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::UsageHint GeomPipelineReader::
|
||||
get_usage_hint() const {
|
||||
|
|
@ -708,7 +759,7 @@ get_usage_hint() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_vertex_data
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(GeomVertexData) GeomPipelineReader::
|
||||
get_vertex_data() const {
|
||||
|
|
@ -718,7 +769,7 @@ get_vertex_data() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_num_primitives
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPipelineReader::
|
||||
get_num_primitives() const {
|
||||
|
|
@ -728,7 +779,7 @@ get_num_primitives() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_primitive
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(GeomPrimitive) GeomPipelineReader::
|
||||
get_primitive(int i) const {
|
||||
|
|
@ -739,7 +790,7 @@ get_primitive(int i) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomPipelineReader::
|
||||
get_modified() const {
|
||||
|
|
|
|||
|
|
@ -142,24 +142,24 @@ PUBLISHED:
|
|||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
public:
|
||||
bool draw(GraphicsStateGuardianBase *gsg,
|
||||
bool draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool force, Thread *current_thread) const;
|
||||
|
||||
|
||||
INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
Thread *current_thread) const;
|
||||
INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any, Thread *current_thread) const;
|
||||
INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
const InternalName *column_name,
|
||||
|
|
@ -174,7 +174,7 @@ private:
|
|||
void compute_internal_bounds(CData *cdata, Thread *current_thread) const;
|
||||
|
||||
void do_calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
const InternalName *column_name,
|
||||
|
|
@ -220,7 +220,7 @@ private:
|
|||
Geom *_source; // A back pointer to the containing Geom
|
||||
const Geom *_geom_result; // ref-counted if not NULL and not same as _source
|
||||
CPT(GeomVertexData) _data_result;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -228,7 +228,7 @@ private:
|
|||
static void init_type() {
|
||||
register_type(_type_handle, "Geom::CDataCache");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -245,6 +245,10 @@ public:
|
|||
public:
|
||||
INLINE CacheKey(const GeomVertexData *source_data,
|
||||
const GeomMunger *modifier);
|
||||
INLINE CacheKey(const CacheKey ©);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CacheKey(CacheKey &&from) NOEXCEPT;
|
||||
#endif
|
||||
INLINE bool operator < (const CacheKey &other) const;
|
||||
|
||||
CPT(GeomVertexData) _source_data;
|
||||
|
|
@ -253,9 +257,13 @@ public:
|
|||
// It is not clear why MSVC7 needs this class to be public.
|
||||
class CacheEntry : public GeomCacheEntry {
|
||||
public:
|
||||
INLINE CacheEntry(Geom *source,
|
||||
INLINE CacheEntry(Geom *source,
|
||||
const GeomVertexData *source_data,
|
||||
const GeomMunger *modifier);
|
||||
INLINE CacheEntry(Geom *source, const CacheKey &key);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CacheEntry(Geom *source, CacheKey &&key) NOEXCEPT;
|
||||
#endif
|
||||
ALLOC_DELETED_CHAIN(CacheEntry);
|
||||
|
||||
virtual void evict_callback();
|
||||
|
|
@ -265,7 +273,7 @@ public:
|
|||
CacheKey _key;
|
||||
|
||||
PipelineCycler<CDataCache> _cycler;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -275,7 +283,7 @@ public:
|
|||
register_type(_type_handle, "Geom::CacheEntry",
|
||||
GeomCacheEntry::get_class_type());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -304,13 +312,13 @@ private:
|
|||
UsageHint _usage_hint;
|
||||
bool _got_usage_hint;
|
||||
UpdateSeq _modified;
|
||||
|
||||
|
||||
CPT(BoundingVolume) _internal_bounds;
|
||||
int _nested_vertices;
|
||||
bool _internal_bounds_stale;
|
||||
BoundingVolume::BoundsType _bounds_type;
|
||||
CPT(BoundingVolume) _user_bounds;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -318,11 +326,11 @@ private:
|
|||
static void init_type() {
|
||||
register_type(_type_handle, "Geom::CData");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataLockedReader<CData> CDLockedReader;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ PStatCollector GeomMunger::_munge_pcollector("*:Munge");
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomMunger::
|
||||
GeomMunger(GraphicsStateGuardianBase *gsg) :
|
||||
|
|
@ -44,7 +44,7 @@ GeomMunger(GraphicsStateGuardianBase *gsg) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomMunger::
|
||||
GeomMunger(const GeomMunger ©) :
|
||||
|
|
@ -60,7 +60,7 @@ GeomMunger(const GeomMunger ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomMunger::
|
||||
operator = (const GeomMunger ©) {
|
||||
|
|
@ -70,7 +70,7 @@ operator = (const GeomMunger ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomMunger::
|
||||
~GeomMunger() {
|
||||
|
|
@ -96,7 +96,7 @@ remove_data(const GeomVertexData *data) {
|
|||
// Access: Public
|
||||
// Description: Applies the indicated munger to the geom and its
|
||||
// data, and returns a (possibly different) geom and
|
||||
// data, according to the munger's whim.
|
||||
// data, according to the munger's whim.
|
||||
//
|
||||
// The assumption is that for a particular geom and a
|
||||
// particular munger, the result will always be the
|
||||
|
|
@ -110,13 +110,12 @@ remove_data(const GeomVertexData *data) {
|
|||
bool GeomMunger::
|
||||
munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
||||
bool force, Thread *current_thread) {
|
||||
CPT(GeomVertexData) source_data = data;
|
||||
|
||||
// Look up the munger in the geom's cache--maybe we've recently
|
||||
// applied it.
|
||||
PT(Geom::CacheEntry) entry;
|
||||
|
||||
Geom::CacheKey key(source_data, this);
|
||||
Geom::CacheKey key(data, this);
|
||||
|
||||
geom->_cache_lock.acquire();
|
||||
Geom::Cache::const_iterator ci = geom->_cache.find(&key);
|
||||
|
|
@ -126,12 +125,12 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||
entry = (*ci).second;
|
||||
geom->_cache_lock.release();
|
||||
nassertr(entry->_source == geom, false);
|
||||
|
||||
|
||||
// Here's an element in the cache for this computation. Record a
|
||||
// cache hit, so this element will stay in the cache a while
|
||||
// longer.
|
||||
entry->refresh(current_thread);
|
||||
|
||||
|
||||
// Now check that it's fresh.
|
||||
Geom::CDCacheReader cdata(entry->_cycler, current_thread);
|
||||
if (cdata->_source == geom &&
|
||||
|
|
@ -139,12 +138,12 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||
geom->get_modified(current_thread) <= cdata->_geom_result->get_modified(current_thread) &&
|
||||
data->get_modified(current_thread) <= cdata->_data_result->get_modified(current_thread)) {
|
||||
// The cache entry is still good; use it.
|
||||
|
||||
|
||||
geom = cdata->_geom_result;
|
||||
data = cdata->_data_result;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// The cache entry is stale, but we'll recompute it below. Note
|
||||
// that there's a small race condition here; another thread might
|
||||
// recompute the cache at the same time. No big deal, since it'll
|
||||
|
|
@ -166,7 +165,12 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||
// Record the new result in the cache.
|
||||
if (entry == (Geom::CacheEntry *)NULL) {
|
||||
// Create a new entry for the result.
|
||||
entry = new Geom::CacheEntry(orig_geom, source_data, this);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
// We don't need the key anymore, move the pointers into the CacheEntry.
|
||||
entry = new Geom::CacheEntry(orig_geom, move(key));
|
||||
#else
|
||||
entry = new Geom::CacheEntry(orig_geom, key);
|
||||
#endif
|
||||
{
|
||||
LightMutexHolder holder(orig_geom->_cache_lock);
|
||||
bool inserted = orig_geom->_cache.insert(Geom::Cache::value_type(&entry->_key, entry)).second;
|
||||
|
|
@ -176,7 +180,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// And tell the cache manager about the new entry. (It might
|
||||
// immediately request a delete from the cache of the thing we
|
||||
// just added.)
|
||||
|
|
@ -198,7 +202,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||
// exists just to cast away the const pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomVertexFormat) GeomMunger::
|
||||
do_munge_format(const GeomVertexFormat *format,
|
||||
do_munge_format(const GeomVertexFormat *format,
|
||||
const GeomVertexAnimationSpec &animation) {
|
||||
nassertr(_is_registered, NULL);
|
||||
nassertr(format->is_registered(), NULL);
|
||||
|
|
@ -248,7 +252,7 @@ munge_data_impl(const GeomVertexData *data) {
|
|||
nassertr(_is_registered, NULL);
|
||||
|
||||
CPT(GeomVertexFormat) orig_format = data->get_format();
|
||||
CPT(GeomVertexFormat) new_format =
|
||||
CPT(GeomVertexFormat) new_format =
|
||||
munge_format(orig_format, orig_format->get_animation());
|
||||
|
||||
if (new_format == orig_format) {
|
||||
|
|
@ -384,7 +388,7 @@ make_registry() {
|
|||
_registry = new Registry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::do_register
|
||||
// Access: Private
|
||||
|
|
@ -408,7 +412,7 @@ do_register(Thread *current_thread) {
|
|||
|
||||
_is_registered = true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::do_unregister
|
||||
// Access: Private
|
||||
|
|
@ -430,7 +434,7 @@ do_unregister() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::CacheEntry::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomMunger::CacheEntry::
|
||||
output(ostream &out) const {
|
||||
|
|
@ -440,7 +444,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomMunger::Registry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomMunger::Registry::
|
||||
Registry() {
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ INLINE int GeomVertexData::
|
|||
add_transform(TransformTable *table, const VertexTransform *transform,
|
||||
TransformMap &already_added) {
|
||||
pair<TransformMap::iterator, bool> result = already_added.insert(TransformMap::value_type(transform, table->get_num_transforms()));
|
||||
|
||||
|
||||
if (result.second) {
|
||||
table->add_transform(transform);
|
||||
}
|
||||
|
|
@ -425,7 +425,7 @@ add_transform(TransformTable *table, const VertexTransform *transform,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CDataCache::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CDataCache::
|
||||
CDataCache() {
|
||||
|
|
@ -434,7 +434,7 @@ CDataCache() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CDataCache::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CDataCache::
|
||||
CDataCache(const GeomVertexData::CDataCache ©) :
|
||||
|
|
@ -445,7 +445,7 @@ CDataCache(const GeomVertexData::CDataCache ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheKey::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheKey::
|
||||
CacheKey(const GeomVertexFormat *modifier) :
|
||||
|
|
@ -453,6 +453,30 @@ CacheKey(const GeomVertexFormat *modifier) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheKey::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheKey::
|
||||
CacheKey(const CacheKey ©) :
|
||||
_modifier(copy._modifier)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheKey::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheKey::
|
||||
CacheKey(CacheKey &&from) NOEXCEPT :
|
||||
_modifier(move(from._modifier))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheKey::operator <
|
||||
// Access: Public
|
||||
|
|
@ -466,7 +490,7 @@ operator < (const CacheKey &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheEntry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheEntry::
|
||||
CacheEntry(GeomVertexData *source, const GeomVertexFormat *modifier) :
|
||||
|
|
@ -475,6 +499,32 @@ CacheEntry(GeomVertexData *source, const GeomVertexFormat *modifier) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheEntry::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheEntry::
|
||||
CacheEntry(GeomVertexData *source, const CacheKey &key) :
|
||||
_source(source),
|
||||
_key(key)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheEntry::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData::CacheEntry::
|
||||
CacheEntry(GeomVertexData *source, CacheKey &&key) NOEXCEPT :
|
||||
_source(source),
|
||||
_key(move(key))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CData::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -511,7 +561,7 @@ CData(const GeomVertexData::CData ©) :
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineBase::
|
||||
GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
Thread *current_thread,
|
||||
GeomVertexData::CData *cdata) :
|
||||
_object(object),
|
||||
|
|
@ -560,7 +610,7 @@ get_current_thread() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineBase::UsageHint GeomVertexDataPipelineBase::
|
||||
get_usage_hint() const {
|
||||
|
|
@ -570,7 +620,7 @@ get_usage_hint() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_format
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexFormat *GeomVertexDataPipelineBase::
|
||||
get_format() const {
|
||||
|
|
@ -580,7 +630,7 @@ get_format() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::has_column
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineBase::
|
||||
has_column(const InternalName *name) const {
|
||||
|
|
@ -590,7 +640,7 @@ has_column(const InternalName *name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_num_arrays
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexDataPipelineBase::
|
||||
get_num_arrays() const {
|
||||
|
|
@ -600,7 +650,7 @@ get_num_arrays() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_array
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(GeomVertexArrayData) GeomVertexDataPipelineBase::
|
||||
get_array(int i) const {
|
||||
|
|
@ -611,7 +661,7 @@ get_array(int i) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_transform_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformTable *GeomVertexDataPipelineBase::
|
||||
get_transform_table() const {
|
||||
|
|
@ -621,7 +671,7 @@ get_transform_table() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_transform_blend_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformBlendTable) GeomVertexDataPipelineBase::
|
||||
get_transform_blend_table() const {
|
||||
|
|
@ -631,7 +681,7 @@ get_transform_blend_table() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_slider_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const SliderTable *GeomVertexDataPipelineBase::
|
||||
get_slider_table() const {
|
||||
|
|
@ -641,7 +691,7 @@ get_slider_table() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomVertexDataPipelineBase::
|
||||
get_modified() const {
|
||||
|
|
@ -654,7 +704,7 @@ get_modified() const {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineReader::
|
||||
GeomVertexDataPipelineReader(const GeomVertexData *object,
|
||||
GeomVertexDataPipelineReader(const GeomVertexData *object,
|
||||
Thread *current_thread) :
|
||||
GeomVertexDataPipelineBase((GeomVertexData *)object, current_thread,
|
||||
(GeomVertexData::CData *)object->_cycler.read_unlocked(current_thread)),
|
||||
|
|
@ -668,7 +718,7 @@ GeomVertexDataPipelineReader(const GeomVertexData *object,
|
|||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineReader::
|
||||
GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©) :
|
||||
GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©) :
|
||||
GeomVertexDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
|
|
@ -710,7 +760,7 @@ get_object() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::check_array_readers
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineReader::
|
||||
check_array_readers() const {
|
||||
|
|
@ -722,7 +772,7 @@ check_array_readers() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_array_reader
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayDataHandle *GeomVertexDataPipelineReader::
|
||||
get_array_reader(int i) const {
|
||||
|
|
@ -734,7 +784,7 @@ get_array_reader(int i) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_vertex() const {
|
||||
|
|
@ -744,7 +794,7 @@ has_vertex() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::is_vertex_transformed
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
is_vertex_transformed() const {
|
||||
|
|
@ -759,7 +809,7 @@ is_vertex_transformed() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_normal
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_normal() const {
|
||||
|
|
@ -769,7 +819,7 @@ has_normal() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_color
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_color() const {
|
||||
|
|
@ -782,7 +832,7 @@ has_color() const {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineWriter::
|
||||
GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0,
|
||||
GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0,
|
||||
Thread *current_thread) :
|
||||
GeomVertexDataPipelineBase(object, current_thread,
|
||||
object->_cycler.write_upstream(force_to_0, current_thread)),
|
||||
|
|
@ -803,7 +853,7 @@ GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0,
|
|||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineWriter::
|
||||
GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©) :
|
||||
GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©) :
|
||||
GeomVertexDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
|
|
@ -845,7 +895,7 @@ get_object() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::check_array_writers
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineWriter::
|
||||
check_array_writers() const {
|
||||
|
|
@ -857,7 +907,7 @@ check_array_writers() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::get_array_writer
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataHandle *GeomVertexDataPipelineWriter::
|
||||
get_array_writer(int i) const {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ make_cow_copy() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexData::
|
||||
GeomVertexData(const string &name,
|
||||
|
|
@ -97,7 +97,7 @@ GeomVertexData(const string &name,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexData::
|
||||
GeomVertexData(const GeomVertexData ©) :
|
||||
|
|
@ -127,7 +127,7 @@ GeomVertexData(const GeomVertexData ©) :
|
|||
// and it allows you to specify a different format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexData::
|
||||
GeomVertexData(const GeomVertexData ©,
|
||||
GeomVertexData(const GeomVertexData ©,
|
||||
const GeomVertexFormat *format) :
|
||||
CopyOnWriteObject(copy),
|
||||
_name(copy._name),
|
||||
|
|
@ -159,7 +159,7 @@ GeomVertexData(const GeomVertexData ©,
|
|||
}
|
||||
CLOSE_ITERATE_ALL_STAGES(_cycler);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::Copy Assignment Operator
|
||||
// Access: Published
|
||||
|
|
@ -186,14 +186,14 @@ operator = (const GeomVertexData ©) {
|
|||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_animated_vertices = NULL;
|
||||
cdata->_animated_vertices_modified = UpdateSeq();
|
||||
}
|
||||
}
|
||||
CLOSE_ITERATE_ALL_STAGES(_cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexData::
|
||||
~GeomVertexData() {
|
||||
|
|
@ -564,22 +564,22 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
pset<int> done_arrays;
|
||||
|
||||
for (source_i = 0; source_i < num_arrays; ++source_i) {
|
||||
const GeomVertexArrayFormat *source_array_format =
|
||||
const GeomVertexArrayFormat *source_array_format =
|
||||
source_format->get_array(source_i);
|
||||
|
||||
bool array_done = false;
|
||||
|
||||
int dest_num_arrays = dest_format->get_num_arrays();
|
||||
for (int dest_i = 0;
|
||||
dest_i < dest_num_arrays && !array_done;
|
||||
for (int dest_i = 0;
|
||||
dest_i < dest_num_arrays && !array_done;
|
||||
++dest_i) {
|
||||
const GeomVertexArrayFormat *dest_array_format =
|
||||
const GeomVertexArrayFormat *dest_array_format =
|
||||
dest_format->get_array(dest_i);
|
||||
if (dest_array_format->is_data_subset_of(*source_array_format)) {
|
||||
// Great! Just use the same data for this one.
|
||||
if (keep_data_objects) {
|
||||
// Copy the data, but keep the same GeomVertexArrayData object.
|
||||
|
||||
// Copy the data, but keep the same GeomVertexArrayData object.
|
||||
|
||||
PT(GeomVertexArrayData) dest_data = modify_array(dest_i);
|
||||
CPT(GeomVertexArrayData) source_data = source->get_array(source_i);
|
||||
dest_data->modify_handle()->copy_data_from(source_data->get_handle());
|
||||
|
|
@ -613,9 +613,9 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
int dest_i = dest_format->get_array_with(source_column->get_name());
|
||||
if (dest_i >= 0 && done_arrays.count(dest_i) == 0) {
|
||||
// The data type exists in the new format; we have to copy it.
|
||||
const GeomVertexArrayFormat *dest_array_format =
|
||||
const GeomVertexArrayFormat *dest_array_format =
|
||||
dest_format->get_array(dest_i);
|
||||
const GeomVertexColumn *dest_column =
|
||||
const GeomVertexColumn *dest_column =
|
||||
dest_array_format->get_column(source_column->get_name());
|
||||
nassertv(dest_column != (const GeomVertexColumn *)NULL);
|
||||
|
||||
|
|
@ -625,12 +625,12 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
PT(GeomVertexArrayDataHandle) dest_handle = dest_array_obj->modify_handle();
|
||||
unsigned char *dest_array_data = dest_handle->get_write_pointer();
|
||||
|
||||
bytewise_copy(dest_array_data + dest_column->get_start(),
|
||||
bytewise_copy(dest_array_data + dest_column->get_start(),
|
||||
dest_array_format->get_stride(),
|
||||
array_data + source_column->get_start(), source_array_format->get_stride(),
|
||||
source_column, num_rows);
|
||||
|
||||
} else if (dest_column->is_packed_argb() &&
|
||||
} else if (dest_column->is_packed_argb() &&
|
||||
source_column->is_uint8_rgba()) {
|
||||
// A common special case: OpenGL color to DirectX color.
|
||||
PT(GeomVertexArrayData) dest_array_obj = modify_array(dest_i);
|
||||
|
|
@ -638,12 +638,12 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
unsigned char *dest_array_data = dest_handle->get_write_pointer();
|
||||
|
||||
uint8_rgba_to_packed_argb
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
dest_array_format->get_stride(),
|
||||
array_data + source_column->get_start(), source_array_format->get_stride(),
|
||||
num_rows);
|
||||
|
||||
} else if (dest_column->is_uint8_rgba() &&
|
||||
} else if (dest_column->is_uint8_rgba() &&
|
||||
source_column->is_packed_argb()) {
|
||||
// Another common special case: DirectX color to OpenGL
|
||||
// color.
|
||||
|
|
@ -652,7 +652,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
unsigned char *dest_array_data = dest_handle->get_write_pointer();
|
||||
|
||||
packed_argb_to_uint8_rgba
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
dest_array_format->get_stride(),
|
||||
array_data + source_column->get_start(), source_array_format->get_stride(),
|
||||
num_rows);
|
||||
|
|
@ -661,7 +661,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// A generic copy.
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "generic copy " << *dest_column << " from "
|
||||
<< "generic copy " << *dest_column << " from "
|
||||
<< *source_column << "\n";
|
||||
}
|
||||
GeomVertexWriter to(this);
|
||||
|
|
@ -695,13 +695,13 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
GeomVertexWriter weight(this, InternalName::get_transform_weight());
|
||||
GeomVertexWriter index(this, InternalName::get_transform_index());
|
||||
GeomVertexReader from(source, InternalName::get_transform_blend());
|
||||
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
|
||||
LVecBase4 weights = LVecBase4::zero();
|
||||
LVecBase4i indices(0, 0, 0, 0);
|
||||
nassertv(blend.get_num_transforms() <= 4);
|
||||
|
||||
|
||||
for (int i = 0; i < blend.get_num_transforms(); i++) {
|
||||
weights[i] = blend.get_weight(i);
|
||||
indices[i] = add_transform(transform_table, blend.get_transform(i),
|
||||
|
|
@ -717,11 +717,11 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// use the same n transforms, in the same order, for each vertex.
|
||||
GeomVertexWriter weight(this, InternalName::get_transform_weight());
|
||||
GeomVertexReader from(source, InternalName::get_transform_blend());
|
||||
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
|
||||
LVecBase4 weights = LVecBase4::zero();
|
||||
|
||||
|
||||
for (int i = 0; i < blend.get_num_transforms(); i++) {
|
||||
int index = add_transform(transform_table, blend.get_transform(i),
|
||||
already_added);
|
||||
|
|
@ -733,7 +733,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
clear_transform_blend_table();
|
||||
set_transform_table(TransformTable::register_table(transform_table));
|
||||
}
|
||||
|
|
@ -754,7 +754,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
int source_row, Thread *current_thread) {
|
||||
const GeomVertexFormat *source_format = source->get_format();
|
||||
const GeomVertexFormat *dest_format = get_format();
|
||||
|
|
@ -842,7 +842,7 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||
}
|
||||
PStatTimer timer(_convert_pcollector);
|
||||
|
||||
PT(GeomVertexData) new_data =
|
||||
PT(GeomVertexData) new_data =
|
||||
new GeomVertexData(get_name(), new_format, get_usage_hint());
|
||||
new_data->set_transform_blend_table(get_transform_blend_table());
|
||||
new_data->set_slider_table(get_slider_table());
|
||||
|
|
@ -852,7 +852,12 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||
// Record the new result in the cache.
|
||||
if (entry == (CacheEntry *)NULL) {
|
||||
// Create a new entry for the result.
|
||||
entry = new CacheEntry((GeomVertexData *)this, new_format);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
// We don't need the key anymore, move the pointers into the CacheEntry.
|
||||
entry = new CacheEntry((GeomVertexData *)this, move(key));
|
||||
#else
|
||||
entry = new CacheEntry((GeomVertexData *)this, key);
|
||||
#endif
|
||||
{
|
||||
LightMutexHolder holder(_cache_lock);
|
||||
bool inserted = ((GeomVertexData *)this)->_cache.insert(Cache::value_type(&entry->_key, entry)).second;
|
||||
|
|
@ -862,7 +867,7 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||
return new_data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// And tell the cache manager about the new entry. (It might
|
||||
// immediately request a delete from the cache of the thing we
|
||||
// just added.)
|
||||
|
|
@ -876,7 +881,6 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||
return new_data;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::scale_color
|
||||
// Access: Published
|
||||
|
|
@ -888,7 +892,7 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomVertexData) GeomVertexData::
|
||||
scale_color(const LVecBase4 &color_scale) const {
|
||||
const GeomVertexColumn *old_column =
|
||||
const GeomVertexColumn *old_column =
|
||||
get_format()->get_column(InternalName::get_color());
|
||||
if (old_column == (GeomVertexColumn *)NULL) {
|
||||
return this;
|
||||
|
|
@ -965,7 +969,7 @@ scale_color(const LVecBase4 &color_scale, int num_components,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomVertexData) GeomVertexData::
|
||||
set_color(const LColor &color) const {
|
||||
const GeomVertexColumn *old_column =
|
||||
const GeomVertexColumn *old_column =
|
||||
get_format()->get_column(InternalName::get_color());
|
||||
if (old_column == (GeomVertexColumn *)NULL) {
|
||||
return this;
|
||||
|
|
@ -1026,7 +1030,7 @@ set_color(const LColor &color, int num_components,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomVertexData) GeomVertexData::
|
||||
reverse_normals() const {
|
||||
const GeomVertexColumn *old_column =
|
||||
const GeomVertexColumn *old_column =
|
||||
get_format()->get_column(InternalName::get_normal());
|
||||
if (old_column == (GeomVertexColumn *)NULL) {
|
||||
return this;
|
||||
|
|
@ -1094,16 +1098,16 @@ animate_vertices(bool force, Thread *current_thread) const {
|
|||
PStatTimer timer2(((GeomVertexData *)this)->_blends_pcollector, current_thread);
|
||||
if (!cdata->_transform_blend_table.is_null()) {
|
||||
if (cdata->_slider_table != (SliderTable *)NULL) {
|
||||
modified =
|
||||
modified =
|
||||
max(cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread),
|
||||
cdata->_slider_table->get_modified(current_thread));
|
||||
} else {
|
||||
modified = cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread);
|
||||
}
|
||||
|
||||
|
||||
} else if (cdata->_slider_table != (SliderTable *)NULL) {
|
||||
modified = cdata->_slider_table->get_modified(current_thread);
|
||||
|
||||
|
||||
} else {
|
||||
// No transform blend table or slider table--ergo, no vertex
|
||||
// animation.
|
||||
|
|
@ -1185,7 +1189,7 @@ transform_vertices(const LMatrix4 &mat, int begin_row, int end_row) {
|
|||
GeomVertexRewriter data(this, format->get_point(ci));
|
||||
do_transform_point_column(format, data, mat, begin_row, end_row);
|
||||
}
|
||||
|
||||
|
||||
for (ci = 0; ci < format->get_num_vectors(); ci++) {
|
||||
GeomVertexRewriter data(this, format->get_vector(ci));
|
||||
do_transform_vector_column(format, data, mat, begin_row, end_row);
|
||||
|
|
@ -1208,7 +1212,7 @@ bytewise_copy(unsigned char *to, int to_stride,
|
|||
<< ", " << (const void *)from << ", " << from_stride
|
||||
<< ", " << *from_type << ", " << num_records << ")\n";
|
||||
}
|
||||
if (to_stride == from_type->get_total_bytes() &&
|
||||
if (to_stride == from_type->get_total_bytes() &&
|
||||
from_stride == from_type->get_total_bytes()) {
|
||||
// Fantastic! It's just a linear array of this one data type.
|
||||
// Copy the whole thing all at once.
|
||||
|
|
@ -1257,32 +1261,32 @@ replace_column(InternalName *name, int num_components,
|
|||
// just drop the whole array.
|
||||
new_format->remove_array(old_type_array);
|
||||
removed_type_array = true;
|
||||
|
||||
|
||||
} else {
|
||||
// Remove the description for the type, but don't bother to
|
||||
// repack the array.
|
||||
array_format->remove_column(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now define a new array to contain just the type.
|
||||
int new_type_array = -1;
|
||||
if (num_components != 0) {
|
||||
PT(GeomVertexArrayFormat) type_array_format =
|
||||
PT(GeomVertexArrayFormat) type_array_format =
|
||||
new GeomVertexArrayFormat(name, num_components, numeric_type, contents);
|
||||
new_type_array = new_format->add_array(type_array_format);
|
||||
}
|
||||
|
||||
CPT(GeomVertexFormat) format =
|
||||
CPT(GeomVertexFormat) format =
|
||||
GeomVertexFormat::register_format(new_format);
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Replacing data type " << *name << "; converting "
|
||||
<< get_num_rows() << " rows from "
|
||||
<< get_num_rows() << " rows from "
|
||||
<< *cdata->_format << " to " << *format << "\n";
|
||||
}
|
||||
|
||||
|
||||
PT(GeomVertexData) new_data = new GeomVertexData(*this, format);
|
||||
|
||||
int j = 0;
|
||||
|
|
@ -1320,7 +1324,7 @@ replace_column(InternalName *name, int num_components,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
output(ostream &out) const {
|
||||
|
|
@ -1333,7 +1337,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::
|
||||
write(ostream &out, int indent_level) const {
|
||||
|
|
@ -1369,16 +1373,16 @@ describe_vertex(ostream &out, int row) const {
|
|||
if (format->get_animation().get_animation_type() == AT_panda) {
|
||||
tb_table = get_transform_blend_table();
|
||||
}
|
||||
|
||||
|
||||
int num_columns = format->get_num_columns();
|
||||
for (int ci = 0; ci < num_columns; ++ci) {
|
||||
int ai = format->get_array_with(ci);
|
||||
const GeomVertexColumn *column = format->get_column(ci);
|
||||
reader.set_column(ai, column);
|
||||
|
||||
|
||||
int num_values = min(column->get_num_values(), 4);
|
||||
const LVecBase4 &d = reader.get_data4();
|
||||
|
||||
|
||||
out << " " << *column->get_name();
|
||||
for (int v = 0; v < num_values; v++) {
|
||||
out << " " << d[v];
|
||||
|
|
@ -1545,7 +1549,7 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
|
||||
if (cdata->_animated_vertices == (GeomVertexData *)NULL) {
|
||||
new_format = orig_format->get_post_animated_format();
|
||||
cdata->_animated_vertices =
|
||||
cdata->_animated_vertices =
|
||||
new GeomVertexData(get_name(), new_format,
|
||||
min(get_usage_hint(), UH_dynamic));
|
||||
}
|
||||
|
|
@ -1670,7 +1674,7 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
|
||||
CPT(GeomVertexArrayFormat) blend_array_format = orig_format->get_array(blend_array_index);
|
||||
|
||||
if (blend_array_format->get_stride() == 2 &&
|
||||
if (blend_array_format->get_stride() == 2 &&
|
||||
blend_array_format->get_column(0)->get_component_bytes() == 2) {
|
||||
// The blend indices are a table of ushorts. Optimize this
|
||||
// common case.
|
||||
|
|
@ -1688,11 +1692,11 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
|
||||
int first_vertex = begin;
|
||||
int first_bi = blendt[first_vertex];
|
||||
|
||||
|
||||
while (first_vertex < end) {
|
||||
// At this point, first_vertex is the first of a series of
|
||||
// vertices that shares the blend index first_bi.
|
||||
|
||||
|
||||
// Scan for the end of this series of vertices--we're
|
||||
// looking for the next vertex with a different blend index.
|
||||
int next_vertex = first_vertex;
|
||||
|
|
@ -1705,13 +1709,13 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
}
|
||||
++next_vertex;
|
||||
}
|
||||
|
||||
|
||||
// We've just reached the end of the vertices with a matching
|
||||
// blend index. Transform all those vertices as a block.
|
||||
LMatrix4 mat;
|
||||
tb_table->get_blend(first_bi).get_blend(mat, current_thread);
|
||||
new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
|
||||
|
||||
|
||||
first_vertex = next_vertex;
|
||||
first_bi = next_bi;
|
||||
}
|
||||
|
|
@ -1728,11 +1732,11 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
|
||||
int first_vertex = begin;
|
||||
int first_bi = blendt[first_vertex];
|
||||
|
||||
|
||||
while (first_vertex < end) {
|
||||
// At this point, first_vertex is the first of a series of
|
||||
// vertices that shares the blend index first_bi.
|
||||
|
||||
|
||||
// Scan for the end of this series of vertices--we're
|
||||
// looking for the next vertex with a different blend index.
|
||||
int next_vertex = first_vertex;
|
||||
|
|
@ -1745,13 +1749,13 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
}
|
||||
++next_vertex;
|
||||
}
|
||||
|
||||
|
||||
// We've just reached the end of the vertices with a matching
|
||||
// blend index. Transform all those vertices as a block.
|
||||
LMatrix4 mat;
|
||||
tb_table->get_blend(first_bi).get_blend(mat, current_thread);
|
||||
new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
|
||||
|
||||
|
||||
first_vertex = next_vertex;
|
||||
first_bi = next_bi;
|
||||
}
|
||||
|
|
@ -1773,14 +1777,14 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
int end = rows.get_subrange_end(i);
|
||||
nassertv(begin < end);
|
||||
blendi.set_row_unsafe(begin);
|
||||
|
||||
|
||||
int first_vertex = begin;
|
||||
int first_bi = blendi.get_data1i();
|
||||
|
||||
|
||||
while (first_vertex < end) {
|
||||
// At this point, first_vertex is the first of a series of
|
||||
// vertices that shares the blend index first_bi.
|
||||
|
||||
|
||||
// Scan for the end of this series of vertices--we're
|
||||
// looking for the next vertex with a different blend index.
|
||||
int next_vertex = first_vertex;
|
||||
|
|
@ -1793,13 +1797,13 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
}
|
||||
++next_vertex;
|
||||
}
|
||||
|
||||
|
||||
// We've just reached the end of the vertices with a matching
|
||||
// blend index. Transform all those vertices as a block.
|
||||
LMatrix4 mat;
|
||||
tb_table->get_blend(first_bi).get_blend(mat, current_thread);
|
||||
new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
|
||||
|
||||
|
||||
first_vertex = next_vertex;
|
||||
first_bi = next_bi;
|
||||
}
|
||||
|
|
@ -1814,14 +1818,14 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
int end = rows.get_subrange_end(i);
|
||||
nassertv(begin != end);
|
||||
blendi.set_row_unsafe(begin);
|
||||
|
||||
|
||||
int first_vertex = begin;
|
||||
int first_bi = blendi.get_data1i();
|
||||
|
||||
|
||||
while (first_vertex < end) {
|
||||
// At this point, first_vertex is the first of a series of
|
||||
// vertices that shares the blend index first_bi.
|
||||
|
||||
|
||||
// Scan for the end of this series of vertices--we're
|
||||
// looking for the next vertex with a different blend index.
|
||||
int next_vertex = first_vertex;
|
||||
|
|
@ -1834,13 +1838,13 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
}
|
||||
++next_vertex;
|
||||
}
|
||||
|
||||
|
||||
// We've just reached the end of the vertices with a matching
|
||||
// blend index. Transform all those vertices as a block.
|
||||
LMatrix4 mat;
|
||||
tb_table->get_blend(first_bi).get_blend(mat, current_thread);
|
||||
new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
|
||||
|
||||
|
||||
first_vertex = next_vertex;
|
||||
first_bi = next_bi;
|
||||
}
|
||||
|
|
@ -1880,11 +1884,11 @@ do_transform_point_column(const GeomVertexFormat *format, GeomVertexRewriter &da
|
|||
} else {
|
||||
table_xform_vecbase4f(datat, num_rows, stride, matf);
|
||||
}
|
||||
|
||||
|
||||
} else if (num_values == 4) {
|
||||
// Use the GeomVertexRewriter to adjust the 4-component
|
||||
// points.
|
||||
|
||||
|
||||
data.set_row_unsafe(begin_row);
|
||||
for (int j = begin_row; j < end_row; ++j) {
|
||||
LPoint4 vertex = data.get_data4();
|
||||
|
|
@ -2110,7 +2114,7 @@ finalize(BamReader *manager) {
|
|||
CDWriter cdata(_cycler, true);
|
||||
|
||||
for (size_t i = 0; i < cdata->_arrays.size(); ++i) {
|
||||
CPT(GeomVertexFormat) new_format =
|
||||
CPT(GeomVertexFormat) new_format =
|
||||
GeomVertexFormat::register_format(cdata->_format);
|
||||
manager->change_pointer(cdata->_format, new_format);
|
||||
cdata->_format = new_format;
|
||||
|
|
@ -2124,14 +2128,14 @@ finalize(BamReader *manager) {
|
|||
}
|
||||
|
||||
if (cdata->_transform_table != (TransformTable *)NULL) {
|
||||
CPT(TransformTable) new_transform_table =
|
||||
CPT(TransformTable) new_transform_table =
|
||||
TransformTable::register_table(cdata->_transform_table);
|
||||
manager->change_pointer(cdata->_transform_table, new_transform_table);
|
||||
cdata->_transform_table = new_transform_table;
|
||||
}
|
||||
|
||||
if (cdata->_slider_table != (SliderTable *)NULL) {
|
||||
CPT(SliderTable) new_slider_table =
|
||||
CPT(SliderTable) new_slider_table =
|
||||
SliderTable::register_table(cdata->_slider_table);
|
||||
manager->change_pointer(cdata->_slider_table, new_slider_table);
|
||||
cdata->_slider_table = new_slider_table;
|
||||
|
|
@ -2181,11 +2185,11 @@ evict_callback() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::CacheEntry::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexData::CacheEntry::
|
||||
output(ostream &out) const {
|
||||
out << "vertex data " << (void *)_source << " to "
|
||||
out << "vertex data " << (void *)_source << " to "
|
||||
<< *_key._modifier;
|
||||
}
|
||||
|
||||
|
|
@ -2236,7 +2240,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
|
||||
Arrays::iterator ai;
|
||||
for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
|
||||
(*ai) = DCAST(GeomVertexArrayData, p_list[pi++]);
|
||||
(*ai) = DCAST(GeomVertexArrayData, p_list[pi++]);
|
||||
}
|
||||
|
||||
_transform_table = DCAST(TransformTable, p_list[pi++]);
|
||||
|
|
@ -2295,7 +2299,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_num_bytes
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomVertexDataPipelineBase::
|
||||
get_num_bytes() const {
|
||||
|
|
@ -2312,7 +2316,7 @@ get_num_bytes() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_num_rows
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomVertexDataPipelineReader::
|
||||
get_num_rows() const {
|
||||
|
|
@ -2332,13 +2336,13 @@ get_num_rows() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_array_info
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_array_info(const InternalName *name,
|
||||
get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
nassertr(_got_array_readers, false);
|
||||
int array_index;
|
||||
|
|
@ -2357,12 +2361,12 @@ get_array_info(const InternalName *name,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_vertex_info
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
nassertr(_got_array_readers, false);
|
||||
int array_index = _cdata->_format->get_vertex_array_index();
|
||||
|
|
@ -2382,11 +2386,11 @@ get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_normal_info
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
nassertr(_got_array_readers, false);
|
||||
int array_index = _cdata->_format->get_normal_array_index();
|
||||
|
|
@ -2405,12 +2409,12 @@ get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_color_info
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_color_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
nassertr(_got_array_readers, false);
|
||||
int array_index = _cdata->_format->get_color_array_index();
|
||||
|
|
@ -2430,7 +2434,7 @@ get_color_info(const GeomVertexArrayDataHandle *&array_reader,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::make_array_readers
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexDataPipelineReader::
|
||||
make_array_readers() {
|
||||
|
|
@ -2449,7 +2453,7 @@ make_array_readers() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::delete_array_readers
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexDataPipelineReader::
|
||||
delete_array_readers() {
|
||||
|
|
@ -2462,7 +2466,7 @@ delete_array_readers() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::get_num_rows
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomVertexDataPipelineWriter::
|
||||
get_num_rows() const {
|
||||
|
|
@ -2482,7 +2486,7 @@ get_num_rows() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::set_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineWriter::
|
||||
set_num_rows(int n) {
|
||||
|
|
@ -2510,10 +2514,10 @@ set_num_rows(int n) {
|
|||
// (1, 1, 1, 1), for the programmer's convenience.
|
||||
GeomVertexArrayDataHandle *array_writer = _array_writers[color_array];
|
||||
const GeomVertexArrayFormat *array_format = array_writer->get_array_format();
|
||||
const GeomVertexColumn *column =
|
||||
const GeomVertexColumn *column =
|
||||
array_format->get_column(InternalName::get_color());
|
||||
int stride = array_format->get_stride();
|
||||
unsigned char *start =
|
||||
unsigned char *start =
|
||||
array_writer->get_write_pointer() + column->get_start();
|
||||
unsigned char *stop = start + array_writer->get_data_size_bytes();
|
||||
unsigned char *pointer = start + stride * orig_color_rows;
|
||||
|
|
@ -2554,7 +2558,7 @@ set_num_rows(int n) {
|
|||
case NT_stdfloat:
|
||||
// Shouldn't have this type in the format.
|
||||
nassertr(false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (any_changed) {
|
||||
|
|
@ -2569,7 +2573,7 @@ set_num_rows(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::unclean_set_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineWriter::
|
||||
unclean_set_num_rows(int n) {
|
||||
|
|
@ -2598,7 +2602,7 @@ unclean_set_num_rows(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::reserve_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineWriter::
|
||||
reserve_num_rows(int n) {
|
||||
|
|
@ -2619,7 +2623,7 @@ reserve_num_rows(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::modify_array
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GeomVertexArrayData) GeomVertexDataPipelineWriter::
|
||||
modify_array(int i) {
|
||||
|
|
@ -2642,7 +2646,7 @@ modify_array(int i) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::set_array
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexDataPipelineWriter::
|
||||
set_array(int i, const GeomVertexArrayData *array) {
|
||||
|
|
@ -2660,7 +2664,7 @@ set_array(int i, const GeomVertexArrayData *array) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::make_array_writers
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexDataPipelineWriter::
|
||||
make_array_writers() {
|
||||
|
|
@ -2683,7 +2687,7 @@ make_array_writers() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::delete_array_writers
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexDataPipelineWriter::
|
||||
delete_array_writers() {
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ private:
|
|||
GeomVertexData();
|
||||
protected:
|
||||
virtual PT(CopyOnWriteObject) make_cow_copy();
|
||||
|
||||
|
||||
PUBLISHED:
|
||||
GeomVertexData(const string &name,
|
||||
const GeomVertexFormat *format,
|
||||
const GeomVertexFormat *format,
|
||||
UsageHint usage_hint);
|
||||
GeomVertexData(const GeomVertexData ©);
|
||||
GeomVertexData(const GeomVertexData ©,
|
||||
|
|
@ -136,17 +136,17 @@ PUBLISHED:
|
|||
|
||||
void copy_from(const GeomVertexData *source, bool keep_data_objects,
|
||||
Thread *current_thread = Thread::get_current_thread());
|
||||
void copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
void copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
int source_row, Thread *current_thread);
|
||||
CPT(GeomVertexData) convert_to(const GeomVertexFormat *new_format) const;
|
||||
CPT(GeomVertexData)
|
||||
CPT(GeomVertexData)
|
||||
scale_color(const LVecBase4 &color_scale) const;
|
||||
CPT(GeomVertexData)
|
||||
CPT(GeomVertexData)
|
||||
scale_color(const LVecBase4 &color_scale, int num_components,
|
||||
NumericType numeric_type, Contents contents) const;
|
||||
CPT(GeomVertexData)
|
||||
CPT(GeomVertexData)
|
||||
set_color(const LColor &color) const;
|
||||
CPT(GeomVertexData)
|
||||
CPT(GeomVertexData)
|
||||
set_color(const LColor &color, int num_components,
|
||||
NumericType numeric_type, Contents contents) const;
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ PUBLISHED:
|
|||
void transform_vertices(const LMatrix4 &mat);
|
||||
void transform_vertices(const LMatrix4 &mat, int begin_row, int end_row);
|
||||
|
||||
PT(GeomVertexData)
|
||||
PT(GeomVertexData)
|
||||
replace_column(InternalName *name, int num_components,
|
||||
NumericType numeric_type, Contents contents) const;
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ private:
|
|||
int num_records);
|
||||
|
||||
typedef pmap<const VertexTransform *, int> TransformMap;
|
||||
INLINE static int
|
||||
INLINE static int
|
||||
add_transform(TransformTable *table, const VertexTransform *transform,
|
||||
TransformMap &already_added);
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ private:
|
|||
}
|
||||
|
||||
CPT(GeomVertexData) _result;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -220,7 +220,7 @@ private:
|
|||
static void init_type() {
|
||||
register_type(_type_handle, "GeomVertexData::CDataCache");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -236,15 +236,24 @@ public:
|
|||
class EXPCL_PANDA_GOBJ CacheKey {
|
||||
public:
|
||||
INLINE CacheKey(const GeomVertexFormat *modifier);
|
||||
INLINE CacheKey(const CacheKey ©);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CacheKey(CacheKey &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE bool operator < (const CacheKey &other) const;
|
||||
|
||||
CPT(GeomVertexFormat) _modifier;
|
||||
};
|
||||
// It is not clear why MSVC7 needs this class to be public.
|
||||
// It is not clear why MSVC7 needs this class to be public.
|
||||
class EXPCL_PANDA_GOBJ CacheEntry : public GeomCacheEntry {
|
||||
public:
|
||||
INLINE CacheEntry(GeomVertexData *source,
|
||||
const GeomVertexFormat *modifier);
|
||||
INLINE CacheEntry(GeomVertexData *source, const CacheKey &key);
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CacheEntry(GeomVertexData *source, CacheKey &&key) NOEXCEPT;
|
||||
#endif
|
||||
ALLOC_DELETED_CHAIN(CacheEntry);
|
||||
|
||||
virtual void evict_callback();
|
||||
|
|
@ -254,7 +263,7 @@ public:
|
|||
CacheKey _key;
|
||||
|
||||
PipelineCycler<CDataCache> _cycler;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -264,7 +273,7 @@ public:
|
|||
register_type(_type_handle, "GeomVertexData::CacheEntry",
|
||||
GeomCacheEntry::get_class_type());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -294,7 +303,7 @@ private:
|
|||
PT(GeomVertexData) _animated_vertices;
|
||||
UpdateSeq _animated_vertices_modified;
|
||||
UpdateSeq _modified;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -302,7 +311,7 @@ private:
|
|||
static void init_type() {
|
||||
register_type(_type_handle, "GeomVertexData::CData");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -323,11 +332,11 @@ private:
|
|||
const LMatrix4 &mat, int begin_row, int end_row);
|
||||
void do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
|
||||
const LMatrix4 &mat, int begin_row, int end_row);
|
||||
static void table_xform_point3f(unsigned char *datat, size_t num_rows,
|
||||
static void table_xform_point3f(unsigned char *datat, size_t num_rows,
|
||||
size_t stride, const LMatrix4f &matf);
|
||||
static void table_xform_vector3f(unsigned char *datat, size_t num_rows,
|
||||
static void table_xform_vector3f(unsigned char *datat, size_t num_rows,
|
||||
size_t stride, const LMatrix4f &matf);
|
||||
static void table_xform_vecbase4f(unsigned char *datat, size_t num_rows,
|
||||
static void table_xform_vecbase4f(unsigned char *datat, size_t num_rows,
|
||||
size_t stride, const LMatrix4f &matf);
|
||||
|
||||
static PStatCollector _convert_pcollector;
|
||||
|
|
@ -386,7 +395,7 @@ private:
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ GeomVertexDataPipelineBase : public GeomEnums {
|
||||
protected:
|
||||
INLINE GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
INLINE GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
Thread *current_thread,
|
||||
GeomVertexData::CData *cdata);
|
||||
|
||||
|
|
@ -436,15 +445,15 @@ public:
|
|||
INLINE const GeomVertexArrayDataHandle *get_array_reader(int i) const;
|
||||
int get_num_rows() const;
|
||||
|
||||
bool get_array_info(const InternalName *name,
|
||||
bool get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_vertex() const;
|
||||
INLINE bool is_vertex_transformed() const;
|
||||
bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_normal() const;
|
||||
|
|
@ -454,7 +463,7 @@ public:
|
|||
|
||||
INLINE bool has_color() const;
|
||||
bool get_color_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -385,6 +385,17 @@ is_nan() const {
|
|||
cnan(_m(2, 0)) || cnan(_m(2, 1)) || cnan(_m(2, 2));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix3::is_identity
|
||||
// Access: Public
|
||||
// Description: Returns true if this is (close enough to) the
|
||||
// identity matrix, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH bool FLOATNAME(LMatrix3)::
|
||||
is_identity() const {
|
||||
return almost_equal(ident_mat(), NEARLY_ZERO(FLOATTYPE));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix3::get_cell
|
||||
// Access: Published
|
||||
|
|
@ -504,7 +515,7 @@ operator == (const FLOATNAME(LMatrix3) &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH bool FLOATNAME(LMatrix3)::
|
||||
operator != (const FLOATNAME(LMatrix3) &other) const {
|
||||
return !operator == (other);
|
||||
return compare_to(other) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
|||
shear._v(1) * scale._v(2), shear._v(2) * scale._v(2), scale._v(2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_zup_left:
|
||||
if (temp_hpr_fix) {
|
||||
set(scale._v(0), shear._v(0) * scale._v(0), 0.0f,
|
||||
|
|
@ -89,7 +89,7 @@ set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
|||
-shear._v(1) * scale._v(2), -shear._v(2) * scale._v(2), scale._v(2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_yup_right:
|
||||
if (temp_hpr_fix) {
|
||||
set(scale._v(0), 0.0f, shear._v(1) * scale._v(0),
|
||||
|
|
@ -101,7 +101,7 @@ set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
|||
shear._v(1) * scale._v(2), 0.0f, scale._v(2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_yup_left:
|
||||
if (temp_hpr_fix) {
|
||||
set(scale._v(0), 0.0f, -shear._v(1) * scale._v(0),
|
||||
|
|
@ -113,7 +113,7 @@ set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
|||
-shear._v(1) * scale._v(2), 0.0f, scale._v(2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_default:
|
||||
case CS_invalid:
|
||||
default:
|
||||
|
|
@ -352,6 +352,9 @@ set_rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
|
|||
bool FLOATNAME(LMatrix3)::
|
||||
almost_equal(const FLOATNAME(LMatrix3) &other, FLOATTYPE threshold) const {
|
||||
TAU_PROFILE("bool LMatrix3::almost_equal(const LMatrix3 &, FLOATTYPE)", " ", TAU_USER);
|
||||
#ifdef HAVE_EIGEN
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < NEARLY_ZERO(FLOATTYPE));
|
||||
#else
|
||||
return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 2), other(0, 2), threshold) &&
|
||||
|
|
@ -361,9 +364,9 @@ almost_equal(const FLOATNAME(LMatrix3) &other, FLOATTYPE threshold) const {
|
|||
IS_THRESHOLD_EQUAL((*this)(2, 0), other(2, 0), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(2, 1), other(2, 1), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(2, 2), other(2, 2), threshold));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix3::output
|
||||
// Access: Published
|
||||
|
|
@ -440,7 +443,7 @@ void FLOATNAME(LMatrix3)::
|
|||
write_datagram_fixed(Datagram &destination) const {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
#if FLOATTOKEN == 'f'
|
||||
#if FLOATTOKEN == 'f'
|
||||
destination.add_float32(get_cell(i,j));
|
||||
#else
|
||||
destination.add_float64(get_cell(i,j));
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ PUBLISHED:
|
|||
INLINE_LINMATH static int size();
|
||||
|
||||
INLINE_LINMATH bool is_nan() const;
|
||||
INLINE_LINMATH bool is_identity() const;
|
||||
|
||||
INLINE_LINMATH FLOATTYPE get_cell(int row, int col) const;
|
||||
INLINE_LINMATH void set_cell(int row, int col, FLOATTYPE value);
|
||||
|
|
@ -252,28 +253,28 @@ PUBLISHED:
|
|||
scale_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz);
|
||||
|
||||
INLINE_LINMATH void
|
||||
set_shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
set_shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix3)
|
||||
shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix3)
|
||||
shear_mat(FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
shear_mat(FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
void
|
||||
set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix3)
|
||||
scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix3)
|
||||
scale_shear_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz,
|
||||
FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
static const FLOATNAME(LMatrix3) &convert_mat(CoordinateSystem from,
|
||||
|
|
|
|||
|
|
@ -616,6 +616,18 @@ is_nan() const {
|
|||
cnan(_m(3, 0)) || cnan(_m(3, 1)) || cnan(_m(3, 2)) || cnan(_m(3, 3));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix4::is_identity
|
||||
// Access: Public
|
||||
// Description: Returns true if this is (close enough to) the
|
||||
// identity matrix, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH bool FLOATNAME(LMatrix4)::
|
||||
is_identity() const {
|
||||
// Eigen has isIdentity, but it seems to be twice as slow as this.
|
||||
return almost_equal(ident_mat(), NEARLY_ZERO(FLOATTYPE));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix4::get_cell
|
||||
// Access: Public
|
||||
|
|
@ -735,7 +747,7 @@ operator == (const FLOATNAME(LMatrix4) &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH bool FLOATNAME(LMatrix4)::
|
||||
operator != (const FLOATNAME(LMatrix4) &other) const {
|
||||
return !operator == (other);
|
||||
return compare_to(other) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ set_rotate_mat(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
|
|||
FLOATTYPE length_sq = axis_0 * axis_0 + axis_1 * axis_1 + axis_2 * axis_2;
|
||||
nassertv(length_sq != 0.0f);
|
||||
FLOATTYPE recip_length = 1.0f/csqrt(length_sq);
|
||||
|
||||
|
||||
axis_0 *= recip_length;
|
||||
axis_1 *= recip_length;
|
||||
axis_2 *= recip_length;
|
||||
|
|
@ -288,11 +288,16 @@ set_rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
|
|||
// Function: LMatrix4::almost_equal
|
||||
// Access: Public
|
||||
// Description: Returns true if two matrices are memberwise equal
|
||||
// within a specified tolerance.
|
||||
// within a specified tolerance. This is faster than
|
||||
// the equivalence operator as this doesn't have to
|
||||
// guarantee that it is transitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FLOATNAME(LMatrix4)::
|
||||
almost_equal(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) const {
|
||||
TAU_PROFILE("bool LMatrix4::almost_equal(const LMatrix4 &, FLOATTYPE)", " ", TAU_USER);
|
||||
#ifdef HAVE_EIGEN
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < NEARLY_ZERO(FLOATTYPE));
|
||||
#else
|
||||
return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 2), other(0, 2), threshold) &&
|
||||
|
|
@ -309,9 +314,9 @@ almost_equal(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) const {
|
|||
IS_THRESHOLD_EQUAL((*this)(3, 1), other(3, 1), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(3, 2), other(3, 2), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(3, 3), other(3, 3), threshold));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix4::output
|
||||
// Access: Public
|
||||
|
|
@ -520,7 +525,7 @@ void FLOATNAME(LMatrix4)::
|
|||
write_datagram_fixed(Datagram &destination) const {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
#if FLOATTOKEN == 'f'
|
||||
#if FLOATTOKEN == 'f'
|
||||
destination.add_float32(get_cell(i,j));
|
||||
#else
|
||||
destination.add_float64(get_cell(i,j));
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ PUBLISHED:
|
|||
INLINE_LINMATH static int size();
|
||||
|
||||
INLINE_LINMATH bool is_nan() const;
|
||||
INLINE_LINMATH bool is_identity() const;
|
||||
|
||||
INLINE_LINMATH FLOATTYPE get_cell(int row, int col) const;
|
||||
INLINE_LINMATH void set_cell(int row, int col, FLOATTYPE value);
|
||||
|
|
@ -210,13 +211,13 @@ PUBLISHED:
|
|||
INLINE_LINMATH void
|
||||
set_scale_mat(const FLOATNAME(LVecBase3) &scale);
|
||||
INLINE_LINMATH void
|
||||
set_shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
set_shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
INLINE_LINMATH void
|
||||
set_scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
|
||||
INLINE_LINMATH static FLOATNAME(LMatrix4)
|
||||
translate_mat(const FLOATNAME(LVecBase3) &trans);
|
||||
INLINE_LINMATH static FLOATNAME(LMatrix4)
|
||||
|
|
@ -237,19 +238,19 @@ PUBLISHED:
|
|||
scale_mat(FLOATTYPE scale);
|
||||
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix4)
|
||||
shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
shear_mat(const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix4)
|
||||
shear_mat(FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
shear_mat(FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix4)
|
||||
scale_shear_mat(const FLOATNAME(LVecBase3) &scale,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
const FLOATNAME(LVecBase3) &shear,
|
||||
CoordinateSystem cs = CS_default);
|
||||
static INLINE_LINMATH FLOATNAME(LMatrix4)
|
||||
scale_shear_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz,
|
||||
FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
FLOATTYPE shxy, FLOATTYPE shxz, FLOATTYPE shyz,
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH static const FLOATNAME(LMatrix4) &y_to_z_up_mat();
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ ConfigVariableBool fake_view_frustum_cull
|
|||
("fake-view-frustum-cull", false,
|
||||
PRC_DESC("Set this true to cause culling to be performed by rendering the "
|
||||
"object in red wireframe, rather than actually culling it. This "
|
||||
"helps make culling errors obvious."));
|
||||
"helps make culling errors obvious. This variable only has an "
|
||||
"effect when Panda is not compiled for a release build."));
|
||||
|
||||
ConfigVariableBool clip_plane_cull
|
||||
("clip-plane-cull", true,
|
||||
|
|
@ -168,15 +169,6 @@ ConfigVariableBool compose_componentwise
|
|||
"operations when possible. If this is false, the compositions "
|
||||
"are always computed by matrix."));
|
||||
|
||||
ConfigVariableBool uniquify_matrix
|
||||
("uniquify-matrix", true,
|
||||
PRC_DESC("Set this true to look up arbitarary 4x4 transform matrices in the "
|
||||
"cache, to ensure that two differently-computed transforms that "
|
||||
"happen to encode the same matrix will be "
|
||||
"collapsed into a single pointer. Nowadays, "
|
||||
"with the transforms stored in a hashtable, we're generally better "
|
||||
"off with this set true."));
|
||||
|
||||
ConfigVariableBool paranoid_const
|
||||
("paranoid-const", false,
|
||||
PRC_DESC("Set this true to double-check that nothing is inappropriately "
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ extern ConfigVariableBool no_unsupported_copy;
|
|||
extern ConfigVariableBool allow_unrelated_wrt;
|
||||
extern ConfigVariableBool paranoid_compose;
|
||||
extern ConfigVariableBool compose_componentwise;
|
||||
extern ConfigVariableBool uniquify_matrix;
|
||||
extern ConfigVariableBool paranoid_const;
|
||||
extern ConfigVariableBool auto_break_cycles;
|
||||
extern EXPCL_PANDA_PGRAPH ConfigVariableBool garbage_collect_states;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ CullBin(const CullBin ©) :
|
|||
_cull_this_pcollector(copy._cull_this_pcollector),
|
||||
_draw_this_pcollector(copy._draw_this_pcollector)
|
||||
{
|
||||
check_flash_color();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -44,7 +43,6 @@ CullBin(const string &name, CullBin::BinType bin_type,
|
|||
_cull_this_pcollector(_cull_bin_pcollector, name),
|
||||
_draw_this_pcollector(draw_region_pcollector, name)
|
||||
{
|
||||
check_flash_color();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -66,26 +64,3 @@ INLINE CullBin::BinType CullBin::
|
|||
get_bin_type() const {
|
||||
return _bin_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBin::has_flash_color
|
||||
// Access: Public
|
||||
// Description: Returns true if this bin has a flash color configured
|
||||
// via the flash-bin-binname config directive, or false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CullBin::
|
||||
has_flash_color() const {
|
||||
return _has_flash_color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBin::get_flash_color
|
||||
// Access: Public
|
||||
// Description: If has_flash_color returns true, this returns the
|
||||
// color specified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LColor &CullBin::
|
||||
get_flash_color() const {
|
||||
return _flash_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,40 +87,6 @@ make_result_graph() {
|
|||
return root_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBin::check_flash_color
|
||||
// Access: Private
|
||||
// Description: Checks the config variables for a user variable of
|
||||
// the name flash-bin-binname. If found, it defines the
|
||||
// r g b color to flash geometry in this bin.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullBin::
|
||||
check_flash_color() {
|
||||
#ifdef NDEBUG
|
||||
_has_flash_color = false;
|
||||
#else
|
||||
ConfigVariableDouble flash_bin
|
||||
("flash-bin-" + _name, "", "", ConfigVariable::F_dynamic);
|
||||
if (flash_bin.get_num_words() == 0) {
|
||||
_has_flash_color = false;
|
||||
|
||||
} else if (flash_bin.get_num_words() == 3) {
|
||||
_has_flash_color = true;
|
||||
_flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], 1.0f);
|
||||
|
||||
} else if (flash_bin.get_num_words() == 4) {
|
||||
_has_flash_color = true;
|
||||
_flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], flash_bin[3]);
|
||||
|
||||
} else {
|
||||
_has_flash_color = false;
|
||||
pgraph_cat.warning()
|
||||
<< "Invalid value for flash-bin-" << _name << ": "
|
||||
<< flash_bin.get_string_value() << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBin::ResultGraphBuilder::Constructor
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -77,9 +77,6 @@ protected:
|
|||
BinType _bin_type;
|
||||
GraphicsStateGuardianBase *_gsg;
|
||||
|
||||
bool _has_flash_color;
|
||||
LColor _flash_color;
|
||||
|
||||
// Used in make_result_graph() and fill_result_graph().
|
||||
class ResultGraphBuilder {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -284,3 +284,76 @@ set_bin_active(const string &name, bool active) {
|
|||
nassertv(bin_index != -1);
|
||||
set_bin_active(bin_index, active);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::get_bin_flash_active
|
||||
// Access: Published
|
||||
// Description: Returns true if the bin with the given bin_index is
|
||||
// configured to flash at a predetermined color (where
|
||||
// bin_index was retrieved by get_bin() or find_bin()).
|
||||
//
|
||||
// This method is not available in release builds.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CullBinManager::
|
||||
get_bin_flash_active(int bin_index) const {
|
||||
nassertr(bin_index >= 0 && bin_index < (int)_bin_definitions.size(), false);
|
||||
return _bin_definitions[bin_index]._flash_active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::get_bin_flash_color
|
||||
// Access: Published
|
||||
// Description: Returns the color that this bin has been configured
|
||||
// to flash to, if configured.
|
||||
//
|
||||
// This method is not available in release builds.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LColor &CullBinManager::
|
||||
get_bin_flash_color(int bin_index) const {
|
||||
nassertr(bin_index >= 0 && bin_index < (int)_bin_definitions.size(), LColor::zero());
|
||||
return _bin_definitions[bin_index]._flash_color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::set_bin_flash_active
|
||||
// Access: Published
|
||||
// Description: When set to true, the given bin_index is configured
|
||||
// to flash at a predetermined color (where
|
||||
// bin_index was retrieved by get_bin() or find_bin()).
|
||||
//
|
||||
// This method is not available in release builds.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullBinManager::
|
||||
set_bin_flash_active(int bin_index, bool active) {
|
||||
nassertv(bin_index >= 0 && bin_index < (int)_bin_definitions.size());
|
||||
_bin_definitions[bin_index]._flash_active = active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::set_bin_flash_color
|
||||
// Access: Published
|
||||
// Description: Changes the flash color for the given bin index.
|
||||
|
||||
// This method is not available in release builds.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullBinManager::
|
||||
set_bin_flash_color(int bin_index, const LColor &color) {
|
||||
nassertv(bin_index >= 0 && bin_index < (int)_bin_definitions.size());
|
||||
_bin_definitions[bin_index]._flash_color = color;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::get_global_ptr
|
||||
// Access: Published, Static
|
||||
// Description: Returns the pointer to the global CullBinManager
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CullBinManager *CullBinManager::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (CullBinManager *)NULL) {
|
||||
_global_ptr = new CullBinManager;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,29 @@ add_bin(const string &name, BinType type, int sort) {
|
|||
def._sort = sort;
|
||||
def._active = true;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check if there was a flash color configured for this bin name.
|
||||
ConfigVariableDouble flash_bin
|
||||
("flash-bin-" + name, "", "", ConfigVariable::F_dynamic);
|
||||
if (flash_bin.get_num_words() == 0) {
|
||||
def._flash_active = false;
|
||||
|
||||
} else if (flash_bin.get_num_words() == 3) {
|
||||
def._flash_active = true;
|
||||
def._flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], 1.0f);
|
||||
|
||||
} else if (flash_bin.get_num_words() == 4) {
|
||||
def._flash_active = true;
|
||||
def._flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], flash_bin[3]);
|
||||
|
||||
} else {
|
||||
def._flash_active = false;
|
||||
pgraph_cat.warning()
|
||||
<< "Invalid value for flash-bin-" << name << ": "
|
||||
<< flash_bin.get_string_value() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
_bins_by_name.insert(BinsByName::value_type(name, new_bin_index));
|
||||
_sorted_bins.push_back(new_bin_index);
|
||||
_bins_are_sorted = false;
|
||||
|
|
@ -133,7 +156,7 @@ remove_bin(int bin_index) {
|
|||
nassertv(_bin_definitions[bin_index]._in_use);
|
||||
|
||||
_bin_definitions[bin_index]._in_use = false;
|
||||
SortedBins::iterator si =
|
||||
SortedBins::iterator si =
|
||||
find(_sorted_bins.begin(), _sorted_bins.end(), bin_index);
|
||||
nassertv(si != _sorted_bins.end());
|
||||
_sorted_bins.erase(si);
|
||||
|
|
@ -142,7 +165,7 @@ remove_bin(int bin_index) {
|
|||
// Now we have to make sure all of the data objects in the world
|
||||
// that had cached this bin index or have a bin object are correctly
|
||||
// updated.
|
||||
|
||||
|
||||
// First, tell all the RenderStates in the world to reset their bin
|
||||
// index cache.
|
||||
RenderState::bin_removed(bin_index);
|
||||
|
|
@ -170,7 +193,7 @@ find_bin(const string &name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullBinManager::
|
||||
write(ostream &out) const {
|
||||
|
|
@ -185,20 +208,6 @@ write(ostream &out) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::get_global_ptr
|
||||
// Access: Published, Static
|
||||
// Description: Returns the pointer to the global CullBinManager
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CullBinManager *CullBinManager::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (CullBinManager *)NULL) {
|
||||
_global_ptr = new CullBinManager;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::make_new_bin
|
||||
// Access: Public
|
||||
|
|
@ -260,11 +269,11 @@ do_sort_bins() {
|
|||
void CullBinManager::
|
||||
setup_initial_bins() {
|
||||
ConfigVariableList cull_bin
|
||||
("cull-bin",
|
||||
("cull-bin",
|
||||
PRC_DESC("Creates a new cull bin by name, with the specified properties. "
|
||||
"This is a string in three tokens, separated by whitespace: "
|
||||
"'bin_name sort type'."));
|
||||
|
||||
|
||||
// First, add all of the bins specified in the Configrc file.
|
||||
int num_bins = cull_bin.get_num_unique_values();
|
||||
|
||||
|
|
@ -351,26 +360,26 @@ parse_bin_type(const string &bin_type) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullBinManager::BinType output operator
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &
|
||||
operator << (ostream &out, CullBinManager::BinType bin_type) {
|
||||
switch (bin_type) {
|
||||
case CullBinManager::BT_invalid:
|
||||
return out << "invalid";
|
||||
|
||||
|
||||
case CullBinManager::BT_unsorted:
|
||||
return out << "unsorted";
|
||||
|
||||
|
||||
case CullBinManager::BT_state_sorted:
|
||||
return out << "state_sorted";
|
||||
|
||||
|
||||
case CullBinManager::BT_back_to_front:
|
||||
return out << "back_to_front";
|
||||
|
||||
|
||||
case CullBinManager::BT_front_to_back:
|
||||
return out << "front_to_back";
|
||||
|
||||
|
||||
case CullBinManager::BT_fixed:
|
||||
return out << "fixed";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,9 +65,16 @@ PUBLISHED:
|
|||
INLINE void set_bin_active(int bin_index, bool active);
|
||||
INLINE void set_bin_active(const string &name, bool active);
|
||||
|
||||
#ifndef NDEBUG
|
||||
INLINE bool get_bin_flash_active(int bin_index) const;
|
||||
INLINE const LColor &get_bin_flash_color(int bin_index) const;
|
||||
INLINE void set_bin_flash_active(int bin_index, bool active);
|
||||
INLINE void set_bin_flash_color(int bin_index, const LColor &color);
|
||||
#endif
|
||||
|
||||
void write(ostream &out) const;
|
||||
|
||||
static CullBinManager *get_global_ptr();
|
||||
INLINE static CullBinManager *get_global_ptr();
|
||||
|
||||
public:
|
||||
// This interface is only intended to be used by CullResult.
|
||||
|
|
@ -77,7 +84,7 @@ public:
|
|||
// This defines the factory interface for defining constructors to
|
||||
// bin types (the implementations are in the cull directory, not
|
||||
// here in pgraph, so we can't call the constructors directly).
|
||||
typedef CullBin *BinConstructor(const string &name,
|
||||
typedef CullBin *BinConstructor(const string &name,
|
||||
GraphicsStateGuardianBase *gsg,
|
||||
const PStatCollector &draw_region_pcollector);
|
||||
|
||||
|
|
@ -95,6 +102,10 @@ private:
|
|||
BinType _type;
|
||||
int _sort;
|
||||
bool _active;
|
||||
#ifndef NDEBUG
|
||||
bool _flash_active;
|
||||
LColorf _flash_color;
|
||||
#endif
|
||||
};
|
||||
typedef pvector<BinDefinition> BinDefinitions;
|
||||
BinDefinitions _bin_definitions;
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cullPlanes.h"
|
||||
#include "cullTraverser.h"
|
||||
#include "cullTraverserData.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "occluderEffect.h"
|
||||
#include "boundingBox.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullPlanes::make_empty
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "renderState.h"
|
||||
#include "clockObject.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "depthOffsetAttrib.h"
|
||||
|
||||
TypeHandle CullResult::_type_handle;
|
||||
|
||||
|
|
@ -114,12 +115,15 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
|
|||
|
||||
bool force = !traverser->get_effective_incomplete_render();
|
||||
Thread *current_thread = traverser->get_current_thread();
|
||||
CullBinManager *bin_manager = CullBinManager::get_global_ptr();
|
||||
|
||||
// Check to see if there's a special transparency setting.
|
||||
const RenderState *state = object->_state;
|
||||
nassertv(state != (const RenderState *)NULL);
|
||||
|
||||
const TransparencyAttrib *trans = DCAST(TransparencyAttrib, state->get_attrib(TransparencyAttrib::get_class_slot()));
|
||||
const TransparencyAttrib *trans = (const TransparencyAttrib *)
|
||||
state->get_attrib(TransparencyAttrib::get_class_slot());
|
||||
|
||||
if (trans != (const TransparencyAttrib *)NULL) {
|
||||
switch (trans->get_mode()) {
|
||||
case TransparencyAttrib::M_alpha:
|
||||
|
|
@ -168,7 +172,9 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
|
|||
// explicit bin already applied; otherwise, M_dual falls back
|
||||
// to M_alpha.
|
||||
{
|
||||
const CullBinAttrib *bin_attrib = DCAST(CullBinAttrib, state->get_attrib(CullBinAttrib::get_class_slot()));
|
||||
const CullBinAttrib *bin_attrib = (const CullBinAttrib *)
|
||||
state->get_attrib(CullBinAttrib::get_class_slot());
|
||||
|
||||
if (bin_attrib == (CullBinAttrib *)NULL ||
|
||||
bin_attrib->get_bin_name().empty()) {
|
||||
// We make a copy of the object to draw the transparent part;
|
||||
|
|
@ -183,10 +189,14 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
|
|||
if (transparent_part->munge_geom
|
||||
(_gsg, _gsg->get_geom_munger(transparent_part->_state, current_thread),
|
||||
traverser, force)) {
|
||||
CullBin *bin = get_bin(transparent_part->_state->get_bin_index());
|
||||
int transparent_bin_index = transparent_part->_state->get_bin_index();
|
||||
CullBin *bin = get_bin(transparent_bin_index);
|
||||
nassertv(bin != (CullBin *)NULL);
|
||||
#ifndef NDEBUG
|
||||
check_flash_bin(transparent_part->_state, bin);
|
||||
if (bin_manager->get_bin_flash_active(transparent_bin_index)) {
|
||||
do_flash_bin(transparent_part->_state,
|
||||
bin_manager->get_bin_flash_color(transparent_bin_index));
|
||||
}
|
||||
#endif
|
||||
bin->add_object(transparent_part, current_thread);
|
||||
} else {
|
||||
|
|
@ -215,11 +225,15 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
|
|||
}
|
||||
}
|
||||
|
||||
CullBin *bin = get_bin(object->_state->get_bin_index());
|
||||
int bin_index = object->_state->get_bin_index();
|
||||
CullBin *bin = get_bin(bin_index);
|
||||
nassertv(bin != (CullBin *)NULL);
|
||||
|
||||
#ifndef NDEBUG
|
||||
check_flash_bin(object->_state, bin);
|
||||
if (bin_manager->get_bin_flash_active(bin_index)) {
|
||||
do_flash_bin(object->_state,
|
||||
bin_manager->get_bin_flash_color(bin_index));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Munge vertices as needed for the GSG's requirements, and the
|
||||
|
|
@ -346,16 +360,20 @@ make_new_bin(int bin_index) {
|
|||
CullBinManager *bin_manager = CullBinManager::get_global_ptr();
|
||||
PT(CullBin) bin = bin_manager->make_new_bin(bin_index, _gsg,
|
||||
_draw_region_pcollector);
|
||||
if (bin != (CullBin *)NULL) {
|
||||
CullBin *bin_ptr = bin.p();
|
||||
|
||||
if (bin_ptr != (CullBin *)NULL) {
|
||||
// Now store it in the vector.
|
||||
while (bin_index >= (int)_bins.size()) {
|
||||
_bins.push_back((CullBin *)NULL);
|
||||
}
|
||||
nassertr(bin_index >= 0 && bin_index < (int)_bins.size(), NULL);
|
||||
_bins[bin_index] = bin;
|
||||
|
||||
// Prevent unnecessary ref/unref by swapping the PointerTos.
|
||||
swap(_bins[bin_index], bin);
|
||||
}
|
||||
|
||||
return bin;
|
||||
return bin_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -393,25 +411,25 @@ get_binary_state() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullResult::check_flash_bin
|
||||
// Function: CullResult::do-flash_bin
|
||||
// Access: Private
|
||||
// Description: If the user configured flash-bin-binname, then update
|
||||
// the object's state to flash all the geometry in the
|
||||
// bin.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullResult::
|
||||
check_flash_bin(CPT(RenderState) &state, CullBin *bin) {
|
||||
if (bin->has_flash_color()) {
|
||||
int cycle = (int)(ClockObject::get_global_clock()->get_frame_time() * bin_color_flash_rate);
|
||||
if ((cycle & 1) == 0) {
|
||||
state = state->remove_attrib(TextureAttrib::get_class_slot());
|
||||
state = state->remove_attrib(LightAttrib::get_class_slot());
|
||||
state = state->remove_attrib(ColorScaleAttrib::get_class_slot());
|
||||
state = state->remove_attrib(FogAttrib::get_class_slot());
|
||||
state = state->add_attrib(ColorAttrib::make_flat(bin->get_flash_color()),
|
||||
RenderState::get_max_priority());
|
||||
}
|
||||
do_flash_bin(CPT(RenderState) &state, const LColor &flash_color) {
|
||||
#ifndef NDEBUG
|
||||
int cycle = (int)(ClockObject::get_global_clock()->get_frame_time() * bin_color_flash_rate);
|
||||
if ((cycle & 1) == 0) {
|
||||
state = state->remove_attrib(TextureAttrib::get_class_slot());
|
||||
state = state->remove_attrib(LightAttrib::get_class_slot());
|
||||
state = state->remove_attrib(ColorScaleAttrib::get_class_slot());
|
||||
state = state->remove_attrib(FogAttrib::get_class_slot());
|
||||
state = state->add_attrib(ColorAttrib::make_flat(flash_color),
|
||||
RenderState::get_max_priority());
|
||||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -423,6 +441,7 @@ check_flash_bin(CPT(RenderState) &state, CullBin *bin) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CullResult::
|
||||
check_flash_transparency(CPT(RenderState) &state, const LColor &transparency) {
|
||||
#ifndef NDEBUG
|
||||
if (show_transparency) {
|
||||
int cycle = (int)(ClockObject::get_global_clock()->get_frame_time() * bin_color_flash_rate);
|
||||
if ((cycle & 1) == 0) {
|
||||
|
|
@ -434,6 +453,7 @@ check_flash_transparency(CPT(RenderState) &state, const LColor &transparency) {
|
|||
RenderState::get_max_priority());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
|
||||
private:
|
||||
CullBin *make_new_bin(int bin_index);
|
||||
void check_flash_bin(CPT(RenderState) &state, CullBin *bin);
|
||||
void do_flash_bin(CPT(RenderState) &state, const LColor &flash_color);
|
||||
void check_flash_transparency(CPT(RenderState) &state, const LColor &color);
|
||||
|
||||
static CPT(RenderState) get_alpha_state();
|
||||
|
|
|
|||
|
|
@ -245,3 +245,63 @@ flush_level() {
|
|||
_geoms_pcollector.flush_level();
|
||||
_geoms_occluded_pcollector.flush_level();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::do_traverse
|
||||
// Access: Protected
|
||||
// Description: This is implemented inline to reduce recursion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullTraverser::
|
||||
do_traverse(CullTraverserData &data) {
|
||||
if (is_in_view(data)) {
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "\n" << data._node_path
|
||||
<< " " << data._draw_mask << "\n";
|
||||
}
|
||||
|
||||
PandaNodePipelineReader *node_reader = data.node_reader();
|
||||
int fancy_bits = node_reader->get_fancy_bits();
|
||||
|
||||
if ((fancy_bits & (PandaNode::FB_transform |
|
||||
PandaNode::FB_state |
|
||||
PandaNode::FB_effects |
|
||||
PandaNode::FB_tag |
|
||||
PandaNode::FB_draw_mask |
|
||||
PandaNode::FB_cull_callback)) == 0 &&
|
||||
data._cull_planes->is_empty()) {
|
||||
// Nothing interesting in this node; just move on.
|
||||
|
||||
} else {
|
||||
// Something in this node is worth taking a closer look.
|
||||
const RenderEffects *node_effects = node_reader->get_effects();
|
||||
if (node_effects->has_show_bounds()) {
|
||||
// If we should show the bounding volume for this node, make it
|
||||
// up now.
|
||||
show_bounds(data, node_effects->has_show_tight_bounds());
|
||||
}
|
||||
|
||||
data.apply_transform_and_state(this);
|
||||
|
||||
const FogAttrib *fog = (const FogAttrib *)
|
||||
node_reader->get_state()->get_attrib(FogAttrib::get_class_slot());
|
||||
|
||||
if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) {
|
||||
// If we just introduced a FogAttrib here, call adjust_to_camera()
|
||||
// now. This maybe isn't the perfect time to call it, but it's
|
||||
// good enough; and at this time we have all the information we
|
||||
// need for it.
|
||||
fog->get_fog()->adjust_to_camera(get_camera_transform());
|
||||
}
|
||||
|
||||
if (fancy_bits & PandaNode::FB_cull_callback) {
|
||||
PandaNode *node = data.node();
|
||||
if (!node->cull_callback(this, data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse_below(data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include "cullTraverserData.h"
|
||||
#include "transformState.h"
|
||||
#include "renderState.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "renderModeAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
|
|
@ -164,7 +163,7 @@ traverse(const NodePath &root) {
|
|||
_initial_state, _view_frustum,
|
||||
_current_thread);
|
||||
|
||||
traverse(data);
|
||||
do_traverse(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,55 +176,7 @@ traverse(const NodePath &root) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverser::
|
||||
traverse(CullTraverserData &data) {
|
||||
if (is_in_view(data)) {
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "\n" << data._node_path
|
||||
<< " " << data._draw_mask << "\n";
|
||||
}
|
||||
|
||||
PandaNodePipelineReader *node_reader = data.node_reader();
|
||||
int fancy_bits = node_reader->get_fancy_bits();
|
||||
|
||||
if ((fancy_bits & (PandaNode::FB_transform |
|
||||
PandaNode::FB_state |
|
||||
PandaNode::FB_effects |
|
||||
PandaNode::FB_tag |
|
||||
PandaNode::FB_draw_mask |
|
||||
PandaNode::FB_cull_callback)) == 0 &&
|
||||
data._cull_planes->is_empty()) {
|
||||
// Nothing interesting in this node; just move on.
|
||||
traverse_below(data);
|
||||
|
||||
} else {
|
||||
// Something in this node is worth taking a closer look.
|
||||
const RenderEffects *node_effects = node_reader->get_effects();
|
||||
if (node_effects->has_show_bounds()) {
|
||||
// If we should show the bounding volume for this node, make it
|
||||
// up now.
|
||||
show_bounds(data, node_effects->has_show_tight_bounds());
|
||||
}
|
||||
|
||||
data.apply_transform_and_state(this);
|
||||
|
||||
const FogAttrib *fog = DCAST(FogAttrib, node_reader->get_state()->get_attrib(FogAttrib::get_class_slot()));
|
||||
if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) {
|
||||
// If we just introduced a FogAttrib here, call adjust_to_camera()
|
||||
// now. This maybe isn't the perfect time to call it, but it's
|
||||
// good enough; and at this time we have all the information we
|
||||
// need for it.
|
||||
fog->get_fog()->adjust_to_camera(get_camera_transform());
|
||||
}
|
||||
|
||||
if (fancy_bits & PandaNode::FB_cull_callback) {
|
||||
PandaNode *node = data.node();
|
||||
if (!node->cull_callback(this, data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
traverse_below(data);
|
||||
}
|
||||
}
|
||||
do_traverse(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -241,27 +192,24 @@ traverse_below(CullTraverserData &data) {
|
|||
PandaNodePipelineReader *node_reader = data.node_reader();
|
||||
PandaNode *node = data.node();
|
||||
|
||||
bool this_node_hidden = data.is_this_node_hidden(this);
|
||||
|
||||
const RenderEffects *node_effects = node_reader->get_effects();
|
||||
bool has_decal = !this_node_hidden && node_effects->has_decal();
|
||||
|
||||
if (!this_node_hidden) {
|
||||
if (!data.is_this_node_hidden(_camera_mask)) {
|
||||
node->add_for_draw(this, data);
|
||||
}
|
||||
|
||||
if (has_decal) {
|
||||
// If we *are* implementing decals with DepthOffsetAttribs,
|
||||
// apply it now, so that each child of this node gets offset by
|
||||
// a tiny amount.
|
||||
data._state = data._state->compose(get_depth_offset_state());
|
||||
// Check for a decal effect.
|
||||
const RenderEffects *node_effects = node_reader->get_effects();
|
||||
if (node_effects->has_decal()) {
|
||||
// If we *are* implementing decals with DepthOffsetAttribs,
|
||||
// apply it now, so that each child of this node gets offset by
|
||||
// a tiny amount.
|
||||
data._state = data._state->compose(get_depth_offset_state());
|
||||
#ifndef NDEBUG
|
||||
// This is just a sanity check message.
|
||||
if (!node->is_geom_node()) {
|
||||
pgraph_cat.error()
|
||||
<< "DecalEffect applied to " << *node << ", not a GeomNode.\n";
|
||||
}
|
||||
// This is just a sanity check message.
|
||||
if (!node->is_geom_node()) {
|
||||
pgraph_cat.error()
|
||||
<< "DecalEffect applied to " << *node << ", not a GeomNode.\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Now visit all the node's children.
|
||||
|
|
@ -272,14 +220,14 @@ traverse_below(CullTraverserData &data) {
|
|||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
CullTraverserData next_data(data, children.get_child(i));
|
||||
traverse(next_data);
|
||||
do_traverse(next_data);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
CullTraverserData next_data(data, children.get_child(i));
|
||||
traverse(next_data);
|
||||
do_traverse(next_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "drawMask.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "cullTraverserData.h"
|
||||
#include "fogAttrib.h"
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
class PandaNode;
|
||||
|
|
@ -92,6 +94,8 @@ PUBLISHED:
|
|||
const TransformState *modelview_transform) const;
|
||||
|
||||
protected:
|
||||
INLINE void do_traverse(CullTraverserData &data);
|
||||
|
||||
virtual bool is_in_view(CullTraverserData &data);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ is_in_view(const DrawMask &camera_mask) {
|
|||
// rendered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CullTraverserData::
|
||||
is_this_node_hidden(const CullTraverser *trav) const {
|
||||
is_this_node_hidden(const DrawMask &camera_mask) const {
|
||||
return (_draw_mask & PandaNode::get_overall_bit()).is_zero() ||
|
||||
(_draw_mask & trav->get_camera_mask()).is_zero();
|
||||
(_draw_mask & camera_mask).is_zero();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ is_in_view_impl() {
|
|||
|
||||
if (result == BoundingVolume::IF_no_intersection) {
|
||||
// No intersection at all. Cull.
|
||||
#ifdef NDEBUG
|
||||
return false;
|
||||
#else
|
||||
if (!fake_view_frustum_cull) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -155,12 +158,13 @@ is_in_view_impl() {
|
|||
_view_frustum = (GeometricBoundingVolume *)NULL;
|
||||
CPT(RenderState) fake_state = get_fake_view_frustum_cull_state();
|
||||
_state = _state->compose(fake_state);
|
||||
|
||||
#endif
|
||||
|
||||
} else if ((result & BoundingVolume::IF_all) != 0) {
|
||||
// The node and its descendents are completely enclosed within
|
||||
// the frustum. No need to cull further.
|
||||
_view_frustum = (GeometricBoundingVolume *)NULL;
|
||||
|
||||
|
||||
} else {
|
||||
// The node is partially, but not completely, within the viewing
|
||||
// frustum.
|
||||
|
|
@ -197,16 +201,20 @@ is_in_view_impl() {
|
|||
_state->write(pgraph_cat.spam(false), 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (result == BoundingVolume::IF_no_intersection) {
|
||||
// No intersection at all. Cull.
|
||||
#ifdef NDEBUG
|
||||
return false;
|
||||
#else
|
||||
if (!fake_view_frustum_cull) {
|
||||
return false;
|
||||
}
|
||||
_cull_planes = CullPlanes::make_empty();
|
||||
CPT(RenderState) fake_state = get_fake_view_frustum_cull_state();
|
||||
_state = _state->compose(fake_state);
|
||||
|
||||
#endif
|
||||
|
||||
} else if ((result & BoundingVolume::IF_all) != 0) {
|
||||
// The node and its descendents are completely in front of all
|
||||
// of the clip planes and occluders. The do_cull() call should
|
||||
|
|
@ -227,6 +235,9 @@ is_in_view_impl() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) CullTraverserData::
|
||||
get_fake_view_frustum_cull_state() {
|
||||
#ifdef NDEBUG
|
||||
return NULL;
|
||||
#else
|
||||
// Once someone asks for this pointer, we hold its reference count
|
||||
// and never free it.
|
||||
static CPT(RenderState) state = (const RenderState *)NULL;
|
||||
|
|
@ -238,5 +249,5 @@ get_fake_view_frustum_cull_state() {
|
|||
RenderState::get_max_priority());
|
||||
}
|
||||
return state;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@
|
|||
#include "geometricBoundingVolume.h"
|
||||
#include "pointerTo.h"
|
||||
#include "drawMask.h"
|
||||
#include "cullTraverser.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class PandaNode;
|
||||
class CullTraverser;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullTraverserData
|
||||
|
|
@ -67,7 +67,7 @@ PUBLISHED:
|
|||
INLINE const TransformState *get_net_transform(const CullTraverser *trav) const;
|
||||
|
||||
INLINE bool is_in_view(const DrawMask &camera_mask);
|
||||
INLINE bool is_this_node_hidden(const CullTraverser *trav) const;
|
||||
INLINE bool is_this_node_hidden(const DrawMask &camera_mask) const;
|
||||
|
||||
void apply_transform_and_state(CullTraverser *trav);
|
||||
void apply_transform_and_state(CullTraverser *trav,
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
_munged_data->animate_vertices(force, current_thread);
|
||||
if (animated_vertices != _munged_data) {
|
||||
cpu_animated = true;
|
||||
_munged_data = animated_vertices;
|
||||
swap(_munged_data, animated_vertices);
|
||||
}
|
||||
if (!munge_texcoord_light_vector(traverser, force)) {
|
||||
return false;
|
||||
|
|
@ -159,7 +159,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
_munged_data->animate_vertices(force, current_thread);
|
||||
if (animated_vertices != _munged_data) {
|
||||
cpu_animated = true;
|
||||
_munged_data = animated_vertices;
|
||||
swap(_munged_data, animated_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -589,7 +589,12 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
}
|
||||
|
||||
_geom = new_geom.p();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
_munged_data = move(new_data);
|
||||
#else
|
||||
_munged_data = new_data;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,6 +320,29 @@ operator = (const GeomNode::Geoms ©) {
|
|||
_geoms = copy._geoms;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::Geoms::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomNode::Geoms::
|
||||
Geoms(GeomNode::Geoms &&from) NOEXCEPT :
|
||||
_geoms(move(from._geoms))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::Geoms::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomNode::Geoms::
|
||||
operator = (GeomNode::Geoms &&from) NOEXCEPT {
|
||||
_geoms = move(from._geoms);
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::Geoms::get_num_geoms
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -168,6 +168,11 @@ public:
|
|||
INLINE Geoms(const Geoms ©);
|
||||
INLINE void operator = (const Geoms ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Geoms(Geoms &&from) NOEXCEPT;
|
||||
INLINE void operator = (Geoms &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE int get_num_geoms() const;
|
||||
INLINE CPT(Geom) get_geom(int n) const;
|
||||
INLINE const RenderState *get_geom_state(int n) const;
|
||||
|
|
|
|||
|
|
@ -1130,6 +1130,29 @@ operator = (const PandaNode::Children ©) {
|
|||
_down = copy._down;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children::
|
||||
Children(PandaNode::Children &&from) NOEXCEPT :
|
||||
_down(move(from._down))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::Children::
|
||||
operator = (PandaNode::Children &&from) NOEXCEPT {
|
||||
_down = move(from._down);
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::get_num_children
|
||||
// Access: Public
|
||||
|
|
@ -1208,6 +1231,29 @@ operator = (const PandaNode::Stashed ©) {
|
|||
_stashed = copy._stashed;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Stashed::
|
||||
Stashed(PandaNode::Stashed &&from) NOEXCEPT :
|
||||
_stashed(move(from._stashed))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::Stashed::
|
||||
operator = (PandaNode::Stashed &&from) NOEXCEPT {
|
||||
_stashed = move(from._stashed);
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::get_num_stashed
|
||||
// Access: Public
|
||||
|
|
@ -1286,6 +1332,29 @@ operator = (const PandaNode::Parents ©) {
|
|||
_up = copy._up;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Parents::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Parents::
|
||||
Parents(PandaNode::Parents &&from) NOEXCEPT :
|
||||
_up(move(from._up))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Parents::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::Parents::
|
||||
operator = (PandaNode::Parents &&from) NOEXCEPT {
|
||||
_up = move(from._up);
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Parents::get_num_parents
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -69,14 +69,14 @@ class GraphicsStateGuardianBase;
|
|||
// is the base class of all specialized nodes, and also
|
||||
// serves as a generic node with no special properties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritable, public Namable,
|
||||
class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritable, public Namable,
|
||||
public LinkedListNode,
|
||||
virtual public ReferenceCount {
|
||||
PUBLISHED:
|
||||
PandaNode(const string &name);
|
||||
virtual ~PandaNode();
|
||||
//published so that characters can be combined.
|
||||
virtual PandaNode *combine_with(PandaNode *other);
|
||||
//published so that characters can be combined.
|
||||
virtual PandaNode *combine_with(PandaNode *other);
|
||||
|
||||
protected:
|
||||
PandaNode(const PandaNode ©);
|
||||
|
|
@ -105,7 +105,7 @@ public:
|
|||
bool &found_any,
|
||||
const TransformState *transform,
|
||||
Thread *current_thread = Thread::get_current_thread()) const;
|
||||
|
||||
|
||||
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
|
||||
virtual bool has_selective_visibility() const;
|
||||
virtual int get_first_visible_child() const;
|
||||
|
|
@ -195,9 +195,9 @@ PUBLISHED:
|
|||
INLINE bool has_dirty_prev_transform() const;
|
||||
static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread());
|
||||
|
||||
void set_tag(const string &key, const string &value,
|
||||
void set_tag(const string &key, const string &value,
|
||||
Thread *current_thread = Thread::get_current_thread());
|
||||
INLINE string get_tag(const string &key,
|
||||
INLINE string get_tag(const string &key,
|
||||
Thread *current_thread = Thread::get_current_thread()) const;
|
||||
INLINE bool has_tag(const string &key,
|
||||
Thread *current_thread = Thread::get_current_thread()) const;
|
||||
|
|
@ -393,7 +393,7 @@ private:
|
|||
|
||||
// parent-child manipulation for NodePath support. Don't try to
|
||||
// call these directly.
|
||||
static PT(NodePathComponent) attach(NodePathComponent *parent,
|
||||
static PT(NodePathComponent) attach(NodePathComponent *parent,
|
||||
PandaNode *child, int sort,
|
||||
int pipeline_stage, Thread *current_thread);
|
||||
static void detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
|
||||
|
|
@ -402,7 +402,7 @@ private:
|
|||
NodePathComponent *child, int sort, bool as_stashed,
|
||||
int pipeline_stage, Thread *current_thread);
|
||||
static bool reparent_one_stage(NodePathComponent *new_parent,
|
||||
NodePathComponent *child, int sort,
|
||||
NodePathComponent *child, int sort,
|
||||
bool as_stashed, int pipeline_stage, Thread *current_thread);
|
||||
static PT(NodePathComponent) get_component(NodePathComponent *parent,
|
||||
PandaNode *child,
|
||||
|
|
@ -411,7 +411,7 @@ private:
|
|||
int pipeline_stage, Thread *current_thread);
|
||||
PT(NodePathComponent) get_generic_component(bool accept_ambiguity,
|
||||
int pipeline_stage, Thread *current_thread);
|
||||
PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity,
|
||||
PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity,
|
||||
bool &ambiguity_detected,
|
||||
int pipeline_stage, Thread *current_thread);
|
||||
void delete_component(NodePathComponent *component);
|
||||
|
|
@ -421,7 +421,7 @@ private:
|
|||
int pipeline_stage, Thread *current_thread);
|
||||
void fix_path_lengths(int pipeline_stage, Thread *current_thread);
|
||||
void r_list_descendants(ostream &out, int indent_level) const;
|
||||
|
||||
|
||||
INLINE void do_set_dirty_prev_transform();
|
||||
INLINE void do_clear_dirty_prev_transform();
|
||||
|
||||
|
|
@ -461,14 +461,14 @@ private:
|
|||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
static void init_type() {
|
||||
BamReaderAuxData::init_type();
|
||||
register_type(_type_handle, "BamReaderAuxDataDown",
|
||||
BamReaderAuxData::get_class_type());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -513,8 +513,8 @@ private:
|
|||
#ifndef NDEBUG
|
||||
unsigned int _unexpected_change_flags;
|
||||
#endif // !NDEBUG
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
|
||||
class EXPCL_PANDA_PGRAPH CData : public BoundsData {
|
||||
public:
|
||||
|
|
@ -524,7 +524,7 @@ private:
|
|||
ALLOC_DELETED_CHAIN(CData);
|
||||
|
||||
virtual CycleData *make_copy() const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
void update_bam_nested(BamWriter *manager) const;
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
|
@ -545,7 +545,7 @@ private:
|
|||
// are less likely to change as often: tags, collide mask.
|
||||
|
||||
INLINE void set_fancy_bit(int bits, bool value);
|
||||
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
void inc_py_refs();
|
||||
void dec_py_refs();
|
||||
|
|
@ -648,7 +648,7 @@ private:
|
|||
COWPT(Down) _down;
|
||||
COWPT(Down) _stashed;
|
||||
COWPT(Up) _up;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -656,7 +656,7 @@ private:
|
|||
static void init_type() {
|
||||
register_type(_type_handle, "PandaNode::CData");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
|
@ -691,6 +691,11 @@ public:
|
|||
INLINE Children(const Children ©);
|
||||
INLINE void operator = (const Children ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Children(Children &&from) NOEXCEPT;
|
||||
INLINE void operator = (Children &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE int get_num_children() const;
|
||||
INLINE PandaNode *get_child(int n) const;
|
||||
INLINE int get_child_sort(int n) const;
|
||||
|
|
@ -707,6 +712,11 @@ public:
|
|||
INLINE Stashed(const Stashed ©);
|
||||
INLINE void operator = (const Stashed ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Stashed(Stashed &&from) NOEXCEPT;
|
||||
INLINE void operator = (Stashed &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE int get_num_stashed() const;
|
||||
INLINE PandaNode *get_stashed(int n) const;
|
||||
INLINE int get_stashed_sort(int n) const;
|
||||
|
|
@ -723,6 +733,11 @@ public:
|
|||
INLINE Parents(const Parents ©);
|
||||
INLINE void operator = (const Parents ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Parents(Parents &&from) NOEXCEPT;
|
||||
INLINE void operator = (Parents &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE int get_num_parents() const;
|
||||
INLINE PandaNode *get_parent(int n) const;
|
||||
|
||||
|
|
@ -750,7 +765,7 @@ protected:
|
|||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
void fillin_recorder(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -96,11 +96,7 @@ compare_to(const RenderAttrib &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t RenderAttrib::
|
||||
get_hash() const {
|
||||
size_t hash = get_hash_impl();
|
||||
|
||||
// The type is also added to the hash.
|
||||
hash = int_hash::add_hash(hash, get_type().get_index());
|
||||
return hash;
|
||||
return _hash;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -143,6 +139,19 @@ get_auto_shader_attrib(const RenderState *state) const {
|
|||
return get_auto_shader_attrib_impl(state);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::calc_hash
|
||||
// Access: Published
|
||||
// Description: Calculates a suitable hash value for phash_map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RenderAttrib::
|
||||
calc_hash() {
|
||||
size_t hash = get_hash_impl();
|
||||
|
||||
// The type is also added to the hash.
|
||||
_hash = int_hash::add_hash(hash, get_type().get_index());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::register_slot
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ cull_callback(CullTraverser *, const CullTraverserData &) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::get_auto_shader_attrib_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) RenderAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
|
|
@ -191,7 +191,7 @@ unref() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderAttrib::
|
||||
output(ostream &out) const {
|
||||
|
|
@ -201,7 +201,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::write
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderAttrib::
|
||||
write(ostream &out, int indent_level) const {
|
||||
|
|
@ -274,7 +274,7 @@ garbage_collect() {
|
|||
}
|
||||
num_this_pass = min(num_this_pass, size);
|
||||
int stop_at_element = (_garbage_index + num_this_pass) % size;
|
||||
|
||||
|
||||
int num_elements = 0;
|
||||
int si = _garbage_index;
|
||||
do {
|
||||
|
|
@ -291,7 +291,7 @@ garbage_collect() {
|
|||
attrib->release_new();
|
||||
unref_delete(attrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
si = (si + 1) % size;
|
||||
} while (si != stop_at_element);
|
||||
|
|
@ -328,12 +328,11 @@ validate_attribs() {
|
|||
}
|
||||
const RenderAttrib *attrib = _attribs->get_key(si);
|
||||
cerr << si << ": " << attrib << "\n";
|
||||
attrib->get_hash();
|
||||
attrib->write(cerr, 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int size = _attribs->get_size();
|
||||
int si = 0;
|
||||
|
|
@ -391,6 +390,7 @@ CPT(RenderAttrib) RenderAttrib::
|
|||
return_new(RenderAttrib *attrib) {
|
||||
nassertr(attrib != (RenderAttrib *)NULL, attrib);
|
||||
if (!uniquify_attribs) {
|
||||
attrib->calc_hash();
|
||||
return attrib;
|
||||
}
|
||||
|
||||
|
|
@ -415,6 +415,8 @@ CPT(RenderAttrib) RenderAttrib::
|
|||
return_unique(RenderAttrib *attrib) {
|
||||
nassertr(attrib != (RenderAttrib *)NULL, attrib);
|
||||
|
||||
attrib->calc_hash();
|
||||
|
||||
if (!state_cache) {
|
||||
return attrib;
|
||||
}
|
||||
|
|
@ -442,7 +444,7 @@ return_unique(RenderAttrib *attrib) {
|
|||
// There's an equivalent attrib already in the set. Return it.
|
||||
return _attribs->get_key(si);
|
||||
}
|
||||
|
||||
|
||||
// Not already in the set; add it.
|
||||
if (garbage_collect_states) {
|
||||
// If we'll be garbage collecting attribs explicitly, we'll
|
||||
|
|
@ -656,7 +658,7 @@ change_this(TypedWritable *old_ptr, BamReader *manager) {
|
|||
pointer->ref();
|
||||
manager->register_finalize(attrib);
|
||||
}
|
||||
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (RenderAttrib *)pointer.p();
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ PUBLISHED:
|
|||
M_greater, // incoming > reference_alpha
|
||||
M_not_equal, // incoming != reference_alpha
|
||||
M_greater_equal, // incoming >= reference_alpha
|
||||
M_always // Always draw.
|
||||
M_always // Always draw.
|
||||
};
|
||||
|
||||
// This is the enumerated type for TexGenAttrib. It is inherited
|
||||
|
|
@ -181,6 +181,8 @@ PUBLISHED:
|
|||
};
|
||||
|
||||
protected:
|
||||
INLINE void calc_hash();
|
||||
|
||||
static CPT(RenderAttrib) return_new(RenderAttrib *attrib);
|
||||
static CPT(RenderAttrib) return_unique(RenderAttrib *attrib);
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
|
|
@ -212,6 +214,7 @@ private:
|
|||
static Attribs *_attribs;
|
||||
|
||||
int _saved_entry;
|
||||
size_t _hash;
|
||||
|
||||
// This keeps track of our current position through the garbage
|
||||
// collection cycle.
|
||||
|
|
@ -227,7 +230,7 @@ public:
|
|||
protected:
|
||||
static TypedWritable *new_from_bam(RenderAttrib *attrib, BamReader *manager);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,42 @@ has_cull_callback() const {
|
|||
return (_flags & F_has_cull_callback) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::make_empty
|
||||
// Access: Published, Static
|
||||
// Description: Returns a RenderState with no attributes set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderState) RenderState::
|
||||
make_empty() {
|
||||
// The empty state is asked for so often, we make it a special case
|
||||
// and store a pointer forever once we find it the first time.
|
||||
if (_empty_state == (RenderState *)NULL) {
|
||||
RenderState *state = new RenderState;
|
||||
_empty_state = return_unique(state);
|
||||
}
|
||||
|
||||
return _empty_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::make_full_default
|
||||
// Access: Published, Static
|
||||
// Description: Returns a RenderState with all possible attributes
|
||||
// set to their default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderState) RenderState::
|
||||
make_full_default() {
|
||||
// The empty state is asked for so often, we make it a special case
|
||||
// and store a pointer forever once we find it the first time.
|
||||
if (_full_default_state == (RenderState *)NULL) {
|
||||
RenderState *state = new RenderState;
|
||||
state->fill_default();
|
||||
_full_default_state = return_unique(state);
|
||||
}
|
||||
|
||||
return _full_default_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::remove_attrib
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -281,42 +281,6 @@ cull_callback(CullTraverser *trav, const CullTraverserData &data) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::make_empty
|
||||
// Access: Published, Static
|
||||
// Description: Returns a RenderState with no attributes set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) RenderState::
|
||||
make_empty() {
|
||||
// The empty state is asked for so often, we make it a special case
|
||||
// and store a pointer forever once we find it the first time.
|
||||
if (_empty_state == (RenderState *)NULL) {
|
||||
RenderState *state = new RenderState;
|
||||
_empty_state = return_unique(state);
|
||||
}
|
||||
|
||||
return _empty_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::make_full_default
|
||||
// Access: Published, Static
|
||||
// Description: Returns a RenderState with all possible attributes
|
||||
// set to their default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) RenderState::
|
||||
make_full_default() {
|
||||
// The empty state is asked for so often, we make it a special case
|
||||
// and store a pointer forever once we find it the first time.
|
||||
if (_full_default_state == (RenderState *)NULL) {
|
||||
RenderState *state = new RenderState;
|
||||
state->fill_default();
|
||||
_full_default_state = return_unique(state);
|
||||
}
|
||||
|
||||
return _full_default_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::make
|
||||
// Access: Published, Static
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ PUBLISHED:
|
|||
INLINE bool has_cull_callback() const;
|
||||
bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
static CPT(RenderState) make_empty();
|
||||
static CPT(RenderState) make_full_default();
|
||||
INLINE static CPT(RenderState) make_empty();
|
||||
INLINE static CPT(RenderState) make_full_default();
|
||||
static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
|
||||
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
||||
const RenderAttrib *attrib2, int override = 0);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ CPT(RenderAttrib) TexMatrixAttrib::
|
|||
make(const LMatrix4 &mat) {
|
||||
pgraph_cat.warning()
|
||||
<< "Using deprecated TexMatrixAttrib interface.\n";
|
||||
if (mat == LMatrix4::ident_mat()) {
|
||||
if (mat.is_identity()) {
|
||||
return make();
|
||||
}
|
||||
CPT(TransformState) transform = TransformState::make_mat(mat);
|
||||
|
|
|
|||
|
|
@ -14,15 +14,13 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::operator <
|
||||
// Function: TransformState::operator !=
|
||||
// Access: Published
|
||||
// Description: Provides an arbitrary ordering among all unique
|
||||
// TransformStates, so we can store the essentially
|
||||
// different ones in a big set and throw away the rest.
|
||||
// Description: Opposite of operator ==.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformState::
|
||||
operator < (const TransformState &other) const {
|
||||
return compare_to(other) < 0;
|
||||
operator != (const TransformState &other) const {
|
||||
return !(operator == (other));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -31,10 +29,14 @@ operator < (const TransformState &other) const {
|
|||
// Description: Provides an arbitrary ordering among all unique
|
||||
// TransformStates, so we can store the essentially
|
||||
// different ones in a big set and throw away the rest.
|
||||
//
|
||||
// Note that if this returns 0, it doesn't necessarily
|
||||
// imply that operator == returns true; it uses a very
|
||||
// slightly different comparison threshold.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TransformState::
|
||||
compare_to(const TransformState &other) const {
|
||||
return compare_to(other, uniquify_matrix);
|
||||
return compare_to(other, _uniquify_matrix);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -56,7 +58,7 @@ get_hash() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_pos(const LVecBase3 &pos) {
|
||||
return make_pos_hpr_scale(pos,
|
||||
return make_pos_hpr_scale(pos,
|
||||
LVecBase3(0.0f, 0.0f, 0.0f),
|
||||
LVecBase3(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
|
@ -70,7 +72,7 @@ make_pos(const LVecBase3 &pos) {
|
|||
INLINE CPT(TransformState) TransformState::
|
||||
make_hpr(const LVecBase3 &hpr) {
|
||||
return make_pos_hpr_scale(LVecBase3(0.0f, 0.0f, 0.0f),
|
||||
hpr,
|
||||
hpr,
|
||||
LVecBase3(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ make_hpr(const LVecBase3 &hpr) {
|
|||
INLINE CPT(TransformState) TransformState::
|
||||
make_quat(const LQuaternion &quat) {
|
||||
return make_pos_quat_scale(LVecBase3(0.0f, 0.0f, 0.0f),
|
||||
quat,
|
||||
quat,
|
||||
LVecBase3(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ make_shear(const LVecBase3 &shear) {
|
|||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_pos_hpr_scale(const LVecBase3 &pos, const LVecBase3 &hpr,
|
||||
make_pos_hpr_scale(const LVecBase3 &pos, const LVecBase3 &hpr,
|
||||
const LVecBase3 &scale) {
|
||||
return make_pos_hpr_scale_shear(pos, hpr, scale, LVecBase3::zero());
|
||||
}
|
||||
|
|
@ -158,7 +160,7 @@ make_pos_hpr_scale(const LVecBase3 &pos, const LVecBase3 &hpr,
|
|||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_pos_quat_scale(const LVecBase3 &pos, const LQuaternion &quat,
|
||||
make_pos_quat_scale(const LVecBase3 &pos, const LQuaternion &quat,
|
||||
const LVecBase3 &scale) {
|
||||
return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3::zero());
|
||||
}
|
||||
|
|
@ -182,7 +184,7 @@ make_pos2d(const LVecBase2 &pos) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_rotate2d(PN_stdfloat rotate) {
|
||||
return make_pos_rotate_scale2d(LVecBase2(0.0f, 0.0f), rotate,
|
||||
return make_pos_rotate_scale2d(LVecBase2(0.0f, 0.0f), rotate,
|
||||
LVecBase2(1.0f, 1.0f));
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +231,7 @@ make_scale2d(const LVecBase2 &scale) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_shear2d(PN_stdfloat shear) {
|
||||
return make_pos_rotate_scale_shear2d(LVecBase2(0.0f, 0.0f), 0.0f,
|
||||
return make_pos_rotate_scale_shear2d(LVecBase2(0.0f, 0.0f), 0.0f,
|
||||
LVecBase2(1.0f, 1.0f), shear);
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +242,7 @@ make_shear2d(PN_stdfloat shear) {
|
|||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) TransformState::
|
||||
make_pos_rotate_scale2d(const LVecBase2 &pos, PN_stdfloat rotate,
|
||||
make_pos_rotate_scale2d(const LVecBase2 &pos, PN_stdfloat rotate,
|
||||
const LVecBase2 &scale) {
|
||||
return make_pos_rotate_scale_shear2d(pos, rotate, scale, 0.0f);
|
||||
}
|
||||
|
|
@ -353,7 +355,7 @@ hpr_given() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::quat_given
|
||||
// Access: Published
|
||||
// Description: Returns true if the rotation was specified via a
|
||||
// Description: Returns true if the rotation was specified via a
|
||||
// quaternion, false otherwise. If this is true,
|
||||
// get_quat() will be exactly as set; otherwise, it will
|
||||
// return a computed value.
|
||||
|
|
@ -1142,7 +1144,7 @@ calc_mat() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformState::
|
||||
check_uniform_scale() {
|
||||
if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) &&
|
||||
if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) &&
|
||||
IS_NEARLY_EQUAL(_scale[0], _scale[2])) {
|
||||
_flags |= F_uniform_scale;
|
||||
if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) {
|
||||
|
|
@ -1234,7 +1236,7 @@ consider_update_pstats(int old_referenced_bits) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::Composition::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TransformState::Composition::
|
||||
Composition() {
|
||||
|
|
@ -1243,7 +1245,7 @@ Composition() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::Composition::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TransformState::Composition::
|
||||
Composition(const TransformState::Composition ©) :
|
||||
|
|
@ -1254,7 +1256,7 @@ Composition(const TransformState::Composition ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::CompositionCycleDescEntry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TransformState::CompositionCycleDescEntry::
|
||||
CompositionCycleDescEntry(const TransformState *obj,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ CPT(TransformState) TransformState::_identity_state;
|
|||
CPT(TransformState) TransformState::_invalid_state;
|
||||
UpdateSeq TransformState::_last_cycle_detect;
|
||||
int TransformState::_garbage_index = 0;
|
||||
bool TransformState::_uniquify_matrix = true;
|
||||
|
||||
PStatCollector TransformState::_cache_update_pcollector("*:State Cache:Update");
|
||||
PStatCollector TransformState::_garbage_collect_pcollector("*:State Cache:Garbage Collect");
|
||||
|
|
@ -98,7 +99,7 @@ TransformState::
|
|||
// We'd better not call the destructor twice on a particular object.
|
||||
nassertv(!is_destructing());
|
||||
set_destructing();
|
||||
|
||||
|
||||
// Free the inverse matrix computation, if it has been stored.
|
||||
if (_inv_mat != (LMatrix4 *)NULL) {
|
||||
delete _inv_mat;
|
||||
|
|
@ -124,6 +125,10 @@ TransformState::
|
|||
// TransformStates, so we can store the essentially
|
||||
// different ones in a big set and throw away the rest.
|
||||
//
|
||||
// Note that if this returns 0, it doesn't necessarily
|
||||
// imply that operator == returns true; it uses a very
|
||||
// slightly different comparison threshold.
|
||||
//
|
||||
// If uniquify_matrix is true, then matrix-defined
|
||||
// TransformStates are also uniqified. If
|
||||
// uniquify_matrix is false, then only component-defined
|
||||
|
|
@ -132,7 +137,7 @@ TransformState::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int TransformState::
|
||||
compare_to(const TransformState &other, bool uniquify_matrix) const {
|
||||
static const int significant_flags =
|
||||
static const int significant_flags =
|
||||
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);
|
||||
|
||||
int flags = (_flags & significant_flags);
|
||||
|
|
@ -191,6 +196,73 @@ compare_to(const TransformState &other, bool uniquify_matrix) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::operator ==
|
||||
// Access: Published
|
||||
// Description: Tests equivalence between two transform states.
|
||||
// We use this instead of compare_to since this is
|
||||
// faster, and we don't need an ordering between
|
||||
// TransformStates because we use a hash map.
|
||||
//
|
||||
// If uniquify_matrix is true, then matrix-defined
|
||||
// TransformStates are also uniqified. If
|
||||
// uniquify_matrix is false, then only component-defined
|
||||
// TransformStates are uniquified, which is less
|
||||
// expensive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TransformState::
|
||||
operator == (const TransformState &other) const {
|
||||
static const int significant_flags =
|
||||
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);
|
||||
|
||||
int flags = (_flags & significant_flags);
|
||||
int other_flags = (other._flags & significant_flags);
|
||||
if (flags != other_flags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((_flags & (F_is_invalid | F_is_identity)) != 0) {
|
||||
// All invalid transforms are equivalent to each other, and all
|
||||
// identity transforms are equivalent to each other.
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((_flags & F_components_given) != 0) {
|
||||
// If the transform was specified componentwise, compare them
|
||||
// componentwise.
|
||||
if (_pos != other._pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((_flags & F_hpr_given) != 0) {
|
||||
if (_hpr != other._hpr) {
|
||||
return false;
|
||||
}
|
||||
} else if ((_flags & F_quat_given) != 0) {
|
||||
if (_quat != other._quat) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_scale != other._scale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (_shear == other._shear);
|
||||
}
|
||||
|
||||
// Otherwise, compare the matrices . . .
|
||||
if (_uniquify_matrix) {
|
||||
// . . . but only if the user thinks that's a worthwhile
|
||||
// comparison.
|
||||
return get_mat().almost_equal(other.get_mat());
|
||||
|
||||
} else {
|
||||
// If not, we just compare the pointers.
|
||||
return (this == &other);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::make_identity
|
||||
// Access: Published, Static
|
||||
|
|
@ -232,7 +304,7 @@ make_invalid() {
|
|||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) TransformState::
|
||||
make_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr,
|
||||
make_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr,
|
||||
const LVecBase3 &scale, const LVecBase3 &shear) {
|
||||
nassertr(!(pos.is_nan() || hpr.is_nan() || scale.is_nan() || shear.is_nan()) , make_invalid());
|
||||
// Make a special-case check for the identity transform.
|
||||
|
|
@ -260,7 +332,7 @@ make_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr,
|
|||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) TransformState::
|
||||
make_pos_quat_scale_shear(const LVecBase3 &pos, const LQuaternion &quat,
|
||||
make_pos_quat_scale_shear(const LVecBase3 &pos, const LQuaternion &quat,
|
||||
const LVecBase3 &scale, const LVecBase3 &shear) {
|
||||
nassertr(!(pos.is_nan() || quat.is_nan() || scale.is_nan() || shear.is_nan()) , make_invalid());
|
||||
// Make a special-case check for the identity transform.
|
||||
|
|
@ -291,7 +363,7 @@ CPT(TransformState) TransformState::
|
|||
make_mat(const LMatrix4 &mat) {
|
||||
nassertr(!mat.is_nan(), make_invalid());
|
||||
// Make a special-case check for the identity matrix.
|
||||
if (mat == LMatrix4::ident_mat()) {
|
||||
if (mat.is_identity()) {
|
||||
return make_identity();
|
||||
}
|
||||
|
||||
|
|
@ -301,7 +373,6 @@ make_mat(const LMatrix4 &mat) {
|
|||
return return_new(state);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::make_pos_rotate_scale_shear2d
|
||||
// Access: Published, Static
|
||||
|
|
@ -356,7 +427,7 @@ CPT(TransformState) TransformState::
|
|||
make_mat3(const LMatrix3 &mat) {
|
||||
nassertr(!mat.is_nan(), make_invalid());
|
||||
// Make a special-case check for the identity matrix.
|
||||
if (mat == LMatrix3::ident_mat()) {
|
||||
if (mat.is_identity()) {
|
||||
return make_identity();
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +600,7 @@ set_rotate2d(PN_stdfloat rotate) const {
|
|||
}
|
||||
}
|
||||
|
||||
return make_pos_rotate_scale_shear2d(get_pos2d(), rotate, get_scale2d(),
|
||||
return make_pos_rotate_scale_shear2d(get_pos2d(), rotate, get_scale2d(),
|
||||
get_shear2d());
|
||||
}
|
||||
|
||||
|
|
@ -592,7 +663,7 @@ compose(const TransformState *other) const {
|
|||
if (other->is_identity()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// If either transform is invalid, the result is invalid.
|
||||
if (is_invalid()) {
|
||||
return this;
|
||||
|
|
@ -754,7 +825,7 @@ unref() const {
|
|||
// it and tries to ref it.
|
||||
((TransformState *)this)->release_new();
|
||||
((TransformState *)this)->remove_cache_pointers();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -821,7 +892,7 @@ validate_composition_cache() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
output(ostream &out) const {
|
||||
|
|
@ -913,7 +984,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
write(ostream &out, int indent_level) const {
|
||||
|
|
@ -1037,7 +1108,7 @@ get_num_unused_states() {
|
|||
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
<< "Unused state: " << (void *)state << ":"
|
||||
<< "Unused state: " << (void *)state << ":"
|
||||
<< state->get_ref_count() << " =\n";
|
||||
state->write(pgraph_cat.debug(false), 2);
|
||||
}
|
||||
|
|
@ -1167,7 +1238,7 @@ garbage_collect() {
|
|||
}
|
||||
num_this_pass = min(num_this_pass, size);
|
||||
int stop_at_element = (_garbage_index + num_this_pass) % size;
|
||||
|
||||
|
||||
int num_elements = 0;
|
||||
int si = _garbage_index;
|
||||
do {
|
||||
|
|
@ -1197,8 +1268,8 @@ garbage_collect() {
|
|||
state->cache_unref();
|
||||
delete state;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
si = (si + 1) % size;
|
||||
} while (si != stop_at_element);
|
||||
_garbage_index = si;
|
||||
|
|
@ -1276,7 +1347,7 @@ list_cycles(ostream &out) {
|
|||
if (r_detect_reverse_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) {
|
||||
// This state begins a cycle.
|
||||
CompositionCycleDesc::iterator csi;
|
||||
|
||||
|
||||
out << "\nReverse cycle detected of length " << cycle_desc.size() + 1 << ":\n"
|
||||
<< "state ";
|
||||
for (csi = cycle_desc.begin(); csi != cycle_desc.end(); ++csi) {
|
||||
|
|
@ -1292,7 +1363,7 @@ list_cycles(ostream &out) {
|
|||
out << (void *)state << ":"
|
||||
<< state->get_ref_count() << " =\n";
|
||||
state->write(out, 2);
|
||||
|
||||
|
||||
cycle_desc.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1355,7 +1426,7 @@ validate_states() {
|
|||
pgraph_cat.error()
|
||||
<< "TransformState::_states cache is invalid!\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int size = _states->get_size();
|
||||
int si = 0;
|
||||
|
|
@ -1376,13 +1447,11 @@ validate_states() {
|
|||
return false;
|
||||
}
|
||||
const TransformState *ssnext = _states->get_key(snext);
|
||||
int c = ssi->compare_to(*ssnext);
|
||||
int ci = ssnext->compare_to(*ssi);
|
||||
if ((ci < 0) != (c > 0) ||
|
||||
(ci > 0) != (c < 0) ||
|
||||
(ci == 0) != (c == 0)) {
|
||||
bool c = (*ssi) == (*ssnext);
|
||||
bool ci = (*ssnext) == (*ssi);
|
||||
if (c != ci) {
|
||||
pgraph_cat.error()
|
||||
<< "TransformState::compare_to() not defined properly!\n";
|
||||
<< "TransformState::operator == () not defined properly!\n";
|
||||
pgraph_cat.error(false)
|
||||
<< "(a, b): " << c << "\n";
|
||||
pgraph_cat.error(false)
|
||||
|
|
@ -1415,6 +1484,18 @@ void TransformState::
|
|||
init_states() {
|
||||
_states = new States;
|
||||
|
||||
ConfigVariableBool uniquify_matrix
|
||||
("uniquify-matrix", true,
|
||||
PRC_DESC("Set this true to look up arbitrary 4x4 transform matrices in "
|
||||
"the cache, to ensure that two differently-computed transforms "
|
||||
"that happen to encode the same matrix will be collapsed into "
|
||||
"a single pointer. Nowadays, with the transforms stored in a "
|
||||
"hashtable, we're generally better off with this set true."));
|
||||
|
||||
// Store this at the beginning, so that we don't have to query this
|
||||
// every time that the comparison operator is invoked.
|
||||
_uniquify_matrix = uniquify_matrix;
|
||||
|
||||
// TODO: we should have a global Panda mutex to allow us to safely
|
||||
// create _states_lock without a startup race condition. For the
|
||||
// meantime, this is OK because we guarantee that this method is
|
||||
|
|
@ -1424,7 +1505,7 @@ init_states() {
|
|||
_cache_stats.init();
|
||||
nassertv(Thread::get_current_thread() == Thread::get_main_thread());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::return_new
|
||||
// Access: Private, Static
|
||||
|
|
@ -1519,8 +1600,8 @@ do_compose(const TransformState *other) const {
|
|||
nassertr((_flags & F_is_invalid) == 0, this);
|
||||
nassertr((other->_flags & F_is_invalid) == 0, other);
|
||||
|
||||
if (compose_componentwise &&
|
||||
has_uniform_scale() &&
|
||||
if (compose_componentwise &&
|
||||
has_uniform_scale() &&
|
||||
!has_nonzero_shear() && !other->has_nonzero_shear() &&
|
||||
((components_given() && other->has_components()) ||
|
||||
(other->components_given() && has_components()))) {
|
||||
|
|
@ -1541,7 +1622,7 @@ do_compose(const TransformState *other) const {
|
|||
|
||||
rotate += other->get_rotate2d();
|
||||
LVecBase2 new_scale = other->get_scale2d() * scale;
|
||||
|
||||
|
||||
result = make_pos_rotate_scale2d(pos, rotate, new_scale);
|
||||
|
||||
} else {
|
||||
|
|
@ -1549,14 +1630,14 @@ do_compose(const TransformState *other) const {
|
|||
LVecBase3 pos = get_pos();
|
||||
LQuaternion quat = get_norm_quat();
|
||||
PN_stdfloat scale = get_uniform_scale();
|
||||
|
||||
|
||||
pos += quat.xform(other->get_pos()) * scale;
|
||||
quat = other->get_norm_quat() * quat;
|
||||
LVecBase3 new_scale = other->get_scale() * scale;
|
||||
|
||||
|
||||
result = make_pos_quat_scale(pos, quat, new_scale);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (paranoid_compose) {
|
||||
// Now verify against the matrix.
|
||||
|
|
@ -1653,7 +1734,7 @@ store_compose(const TransformState *other, const TransformState *result) {
|
|||
// to decrement it again later, when the composition entry is
|
||||
// removed from the cache.
|
||||
result->cache_ref();
|
||||
|
||||
|
||||
// (If the result was just this again, we still store the
|
||||
// result, but we don't increment the reference count, since
|
||||
// that would be a self-referential leak.)
|
||||
|
|
@ -1730,7 +1811,7 @@ store_invert_compose(const TransformState *other, const TransformState *result)
|
|||
// to decrement it again later, when the composition entry is
|
||||
// removed from the cache.
|
||||
result->cache_ref();
|
||||
|
||||
|
||||
// (If the result was just this again, we still store the
|
||||
// result, but we don't increment the reference count, since
|
||||
// that would be a self-referential leak.)
|
||||
|
|
@ -1751,8 +1832,8 @@ do_invert_compose(const TransformState *other) const {
|
|||
nassertr((_flags & F_is_invalid) == 0, this);
|
||||
nassertr((other->_flags & F_is_invalid) == 0, other);
|
||||
|
||||
if (compose_componentwise &&
|
||||
has_uniform_scale() &&
|
||||
if (compose_componentwise &&
|
||||
has_uniform_scale() &&
|
||||
!has_nonzero_shear() && !other->has_nonzero_shear() &&
|
||||
((components_given() && other->has_components()) ||
|
||||
(other->components_given() && has_components()))) {
|
||||
|
|
@ -1767,7 +1848,7 @@ do_invert_compose(const TransformState *other) const {
|
|||
PN_stdfloat rotate = get_rotate2d();
|
||||
LQuaternion quat = get_norm_quat();
|
||||
PN_stdfloat scale = get_uniform_scale();
|
||||
|
||||
|
||||
// First, invert our own transform.
|
||||
if (scale == 0.0f) {
|
||||
((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
|
||||
|
|
@ -1779,7 +1860,7 @@ do_invert_compose(const TransformState *other) const {
|
|||
LVecBase3 mp = quat.xform(-LVecBase3(pos[0], pos[1], 0.0f));
|
||||
pos = LVecBase2(mp[0], mp[1]) * scale;
|
||||
LVecBase2 new_scale(scale, scale);
|
||||
|
||||
|
||||
// Now compose the inverted transform with the other transform.
|
||||
if (!other->is_identity()) {
|
||||
LPoint3 op = quat.xform(other->get_pos());
|
||||
|
|
@ -1796,7 +1877,7 @@ do_invert_compose(const TransformState *other) const {
|
|||
LVecBase3 pos = get_pos();
|
||||
LQuaternion quat = get_norm_quat();
|
||||
PN_stdfloat scale = get_uniform_scale();
|
||||
|
||||
|
||||
// First, invert our own transform.
|
||||
if (scale == 0.0f) {
|
||||
((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
|
||||
|
|
@ -1806,7 +1887,7 @@ do_invert_compose(const TransformState *other) const {
|
|||
quat.invert_in_place();
|
||||
pos = quat.xform(-pos) * scale;
|
||||
LVecBase3 new_scale(scale, scale, scale);
|
||||
|
||||
|
||||
// Now compose the inverted transform with the other transform.
|
||||
if (!other->is_identity()) {
|
||||
pos += quat.xform(other->get_pos()) * scale;
|
||||
|
|
@ -1879,7 +1960,7 @@ do_invert_compose(const TransformState *other) const {
|
|||
void TransformState::
|
||||
detect_and_break_cycles() {
|
||||
PStatTimer timer(_transform_break_cycles_pcollector);
|
||||
|
||||
|
||||
++_last_cycle_detect;
|
||||
if (r_detect_cycles(this, this, 1, _last_cycle_detect, NULL)) {
|
||||
// Ok, we have a cycle. This will be a leak unless we break the
|
||||
|
|
@ -1888,7 +1969,7 @@ detect_and_break_cycles() {
|
|||
pgraph_cat.debug()
|
||||
<< "Breaking cycle involving " << (*this) << "\n";
|
||||
}
|
||||
|
||||
|
||||
remove_cache_pointers();
|
||||
} else {
|
||||
++_last_cycle_detect;
|
||||
|
|
@ -1897,7 +1978,7 @@ detect_and_break_cycles() {
|
|||
pgraph_cat.debug()
|
||||
<< "Breaking cycle involving " << (*this) << "\n";
|
||||
}
|
||||
|
||||
|
||||
remove_cache_pointers();
|
||||
}
|
||||
}
|
||||
|
|
@ -1936,7 +2017,7 @@ r_detect_cycles(const TransformState *start_state,
|
|||
if (current_state->_composition_cache.has_element(i)) {
|
||||
const TransformState *result = current_state->_composition_cache.get_data(i)._result;
|
||||
if (result != (const TransformState *)NULL) {
|
||||
if (r_detect_cycles(start_state, result, length + 1,
|
||||
if (r_detect_cycles(start_state, result, length + 1,
|
||||
this_seq, cycle_desc)) {
|
||||
// Cycle detected.
|
||||
if (cycle_desc != (CompositionCycleDesc *)NULL) {
|
||||
|
|
@ -2008,7 +2089,7 @@ r_detect_reverse_cycles(const TransformState *start_state,
|
|||
|
||||
const TransformState *result = other->_composition_cache.get_data(oi)._result;
|
||||
if (result != (const TransformState *)NULL) {
|
||||
if (r_detect_reverse_cycles(start_state, result, length + 1,
|
||||
if (r_detect_reverse_cycles(start_state, result, length + 1,
|
||||
this_seq, cycle_desc)) {
|
||||
// Cycle detected.
|
||||
if (cycle_desc != (CompositionCycleDesc *)NULL) {
|
||||
|
|
@ -2033,7 +2114,7 @@ r_detect_reverse_cycles(const TransformState *start_state,
|
|||
|
||||
const TransformState *result = other->_invert_composition_cache.get_data(oi)._result;
|
||||
if (result != (const TransformState *)NULL) {
|
||||
if (r_detect_reverse_cycles(start_state, result, length + 1,
|
||||
if (r_detect_reverse_cycles(start_state, result, length + 1,
|
||||
this_seq, cycle_desc)) {
|
||||
// Cycle detected.
|
||||
if (cycle_desc != (CompositionCycleDesc *)NULL) {
|
||||
|
|
@ -2065,7 +2146,7 @@ r_detect_reverse_cycles(const TransformState *start_state,
|
|||
void TransformState::
|
||||
release_new() {
|
||||
nassertv(_states_lock->debug_is_locked());
|
||||
|
||||
|
||||
if (_saved_entry != -1) {
|
||||
//nassertv(_states->find(this) == _saved_entry);
|
||||
_saved_entry = _states->find(this);
|
||||
|
|
@ -2088,7 +2169,7 @@ release_new() {
|
|||
void TransformState::
|
||||
remove_cache_pointers() {
|
||||
nassertv(_states_lock->debug_is_locked());
|
||||
|
||||
|
||||
// Fortunately, since we added CompositionCache records in pairs, we
|
||||
// know exactly the set of TransformState objects that have us in their
|
||||
// cache: it's the same set of TransformState objects that we have in
|
||||
|
|
@ -2150,11 +2231,11 @@ remove_cache_pointers() {
|
|||
if (oi != -1) {
|
||||
// Hold a copy of the other composition result, too.
|
||||
Composition ocomp = other->_composition_cache.get_data(oi);
|
||||
|
||||
|
||||
other->_composition_cache.remove_element(oi);
|
||||
_cache_stats.add_total_size(-1);
|
||||
_cache_stats.inc_dels();
|
||||
|
||||
|
||||
// It's finally safe to let our held pointers go away. This may
|
||||
// have cascading effects as other TransformState objects are
|
||||
// destructed, but there will be no harm done if they destruct
|
||||
|
|
@ -2213,7 +2294,7 @@ do_calc_hash() {
|
|||
PStatTimer timer(_transform_hash_pcollector);
|
||||
_hash = 0;
|
||||
|
||||
static const int significant_flags =
|
||||
static const int significant_flags =
|
||||
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_is_2d);
|
||||
|
||||
int flags = (_flags & significant_flags);
|
||||
|
|
@ -2222,7 +2303,7 @@ do_calc_hash() {
|
|||
if ((_flags & (F_is_invalid | F_is_identity)) == 0) {
|
||||
// Only bother to put the rest of the stuff in the hash if the
|
||||
// transform is not invalid or empty.
|
||||
|
||||
|
||||
if ((_flags & F_components_given) != 0) {
|
||||
// If the transform was specified componentwise, hash it
|
||||
// componentwise.
|
||||
|
|
@ -2239,7 +2320,7 @@ do_calc_hash() {
|
|||
|
||||
} else {
|
||||
// Otherwise, hash the matrix . . .
|
||||
if (uniquify_matrix) {
|
||||
if (_uniquify_matrix) {
|
||||
// . . . but only if the user thinks that's worthwhile.
|
||||
if ((_flags & F_mat_known) == 0) {
|
||||
// Calculate the matrix without doubly-locking.
|
||||
|
|
@ -2556,7 +2637,7 @@ change_this(TypedWritableReferenceCount *old_ptr, BamReader *manager) {
|
|||
// First, uniquify the pointer.
|
||||
TransformState *state = DCAST(TransformState, old_ptr);
|
||||
CPT(TransformState) pointer = return_unique(state);
|
||||
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (TransformState *)pointer.p();
|
||||
|
|
|
|||
|
|
@ -72,9 +72,10 @@ public:
|
|||
ALLOC_DELETED_CHAIN(TransformState);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE bool operator < (const TransformState &other) const;
|
||||
INLINE bool operator != (const TransformState &other) const;
|
||||
INLINE int compare_to(const TransformState &other) const;
|
||||
int compare_to(const TransformState &other, bool uniquify_matrix) const;
|
||||
bool operator == (const TransformState &other) const;
|
||||
INLINE size_t get_hash() const;
|
||||
|
||||
static CPT(TransformState) make_identity();
|
||||
|
|
@ -88,17 +89,17 @@ PUBLISHED:
|
|||
INLINE static CPT(TransformState) make_scale(const LVecBase3 &scale);
|
||||
INLINE static CPT(TransformState) make_shear(const LVecBase3 &shear);
|
||||
INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3 &pos,
|
||||
const LVecBase3 &hpr,
|
||||
const LVecBase3 &hpr,
|
||||
const LVecBase3 &scale);
|
||||
INLINE static CPT(TransformState) make_pos_quat_scale(const LVecBase3 &pos,
|
||||
const LQuaternion &quat,
|
||||
const LQuaternion &quat,
|
||||
const LVecBase3 &scale);
|
||||
static CPT(TransformState) make_pos_hpr_scale_shear(const LVecBase3 &pos,
|
||||
const LVecBase3 &hpr,
|
||||
const LVecBase3 &hpr,
|
||||
const LVecBase3 &scale,
|
||||
const LVecBase3 &shear);
|
||||
static CPT(TransformState) make_pos_quat_scale_shear(const LVecBase3 &pos,
|
||||
const LQuaternion &quat,
|
||||
const LQuaternion &quat,
|
||||
const LVecBase3 &scale,
|
||||
const LVecBase3 &shear);
|
||||
static CPT(TransformState) make_mat(const LMatrix4 &mat);
|
||||
|
|
@ -112,7 +113,7 @@ PUBLISHED:
|
|||
INLINE static CPT(TransformState) make_scale2d(const LVecBase2 &scale);
|
||||
INLINE static CPT(TransformState) make_shear2d(PN_stdfloat shear);
|
||||
INLINE static CPT(TransformState) make_pos_rotate_scale2d(const LVecBase2 &pos,
|
||||
PN_stdfloat rotate,
|
||||
PN_stdfloat rotate,
|
||||
const LVecBase2 &scale);
|
||||
static CPT(TransformState) make_pos_rotate_scale_shear2d(const LVecBase2 &pos,
|
||||
PN_stdfloat rotate,
|
||||
|
|
@ -257,7 +258,7 @@ private:
|
|||
static LightReMutex *_states_lock;
|
||||
class Empty {
|
||||
};
|
||||
typedef SimpleHashMap<const TransformState *, Empty, indirect_compare_to_hash<const TransformState *> > States;
|
||||
typedef SimpleHashMap<const TransformState *, Empty, indirect_equals_hash<const TransformState *> > States;
|
||||
static States *_states;
|
||||
static CPT(TransformState) _identity_state;
|
||||
static CPT(TransformState) _invalid_state;
|
||||
|
|
@ -272,7 +273,7 @@ private:
|
|||
// remove the entry if *either* of the input TransformStates destructs.
|
||||
// To implement this, we always record Composition entries in pairs,
|
||||
// one in each of the two involved TransformState objects.
|
||||
|
||||
|
||||
// The first element of the map is the object we compose with. This
|
||||
// is not reference counted within this map; instead we store a
|
||||
// companion pointer in the other object, and remove the references
|
||||
|
|
@ -299,6 +300,8 @@ private:
|
|||
// collection cycle.
|
||||
static int _garbage_index;
|
||||
|
||||
static bool _uniquify_matrix;
|
||||
|
||||
static PStatCollector _cache_update_pcollector;
|
||||
static PStatCollector _garbage_collect_pcollector;
|
||||
static PStatCollector _transform_compose_pcollector;
|
||||
|
|
@ -369,7 +372,7 @@ private:
|
|||
LMatrix4 _mat;
|
||||
LMatrix4 *_inv_mat;
|
||||
size_t _hash;
|
||||
|
||||
|
||||
unsigned int _flags;
|
||||
|
||||
// This mutex protects _flags, and all of the above computed values.
|
||||
|
|
@ -385,7 +388,7 @@ public:
|
|||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ draw_mask_changed() {
|
|||
bool PGItem::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
LightReMutexHolder holder(_lock);
|
||||
bool this_node_hidden = data.is_this_node_hidden(trav);
|
||||
bool this_node_hidden = data.is_this_node_hidden(trav->get_camera_mask());
|
||||
if (!this_node_hidden && has_frame() && get_active()) {
|
||||
// The item has a frame, so we want to generate a region for it
|
||||
// and update the MouseWatcher.
|
||||
|
|
|
|||
|
|
@ -717,7 +717,7 @@ reposition() {
|
|||
_needs_reposition = false;
|
||||
|
||||
PN_stdfloat t = get_ratio();
|
||||
|
||||
|
||||
if (_thumb_button != (PGButton *)NULL) {
|
||||
LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
|
||||
CPT(TransformState) transform = TransformState::make_pos(pos);
|
||||
|
|
@ -727,7 +727,7 @@ reposition() {
|
|||
// we'll get caught in an update loop.
|
||||
if (transform == orig_transform) {
|
||||
// No change.
|
||||
} else if (*transform < *orig_transform || *orig_transform < *transform) {
|
||||
} else if (*transform != *orig_transform) {
|
||||
_thumb_button->set_transform(transform);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -720,6 +720,10 @@ is_started(int collector_index, int thread_index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClient::
|
||||
start(int collector_index, int thread_index) {
|
||||
if (!client_is_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
|
||||
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
|
||||
|
|
@ -728,7 +732,7 @@ start(int collector_index, int thread_index) {
|
|||
Collector *collector = get_collector_ptr(collector_index);
|
||||
InternalThread *thread = get_thread_ptr(thread_index);
|
||||
|
||||
if (client_is_connected() && collector->is_active() && thread->_is_active) {
|
||||
if (collector->is_active() && thread->_is_active) {
|
||||
LightMutexHolder holder(thread->_thread_lock);
|
||||
if (collector->_per_thread[thread_index]._nested_count == 0) {
|
||||
// This collector wasn't already started in this thread; record
|
||||
|
|
@ -750,6 +754,10 @@ start(int collector_index, int thread_index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClient::
|
||||
start(int collector_index, int thread_index, double as_of) {
|
||||
if (!client_is_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
|
||||
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
|
||||
|
|
@ -758,7 +766,7 @@ start(int collector_index, int thread_index, double as_of) {
|
|||
Collector *collector = get_collector_ptr(collector_index);
|
||||
InternalThread *thread = get_thread_ptr(thread_index);
|
||||
|
||||
if (client_is_connected() && collector->is_active() && thread->_is_active) {
|
||||
if (collector->is_active() && thread->_is_active) {
|
||||
LightMutexHolder holder(thread->_thread_lock);
|
||||
if (collector->_per_thread[thread_index]._nested_count == 0) {
|
||||
// This collector wasn't already started in this thread; record
|
||||
|
|
@ -780,6 +788,10 @@ start(int collector_index, int thread_index, double as_of) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClient::
|
||||
stop(int collector_index, int thread_index) {
|
||||
if (!client_is_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
|
||||
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
|
||||
|
|
@ -788,7 +800,7 @@ stop(int collector_index, int thread_index) {
|
|||
Collector *collector = get_collector_ptr(collector_index);
|
||||
InternalThread *thread = get_thread_ptr(thread_index);
|
||||
|
||||
if (client_is_connected() && collector->is_active() && thread->_is_active) {
|
||||
if (collector->is_active() && thread->_is_active) {
|
||||
LightMutexHolder holder(thread->_thread_lock);
|
||||
if (collector->_per_thread[thread_index]._nested_count == 0) {
|
||||
if (pstats_cat.is_debug()) {
|
||||
|
|
@ -821,6 +833,10 @@ stop(int collector_index, int thread_index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClient::
|
||||
stop(int collector_index, int thread_index, double as_of) {
|
||||
if (!client_is_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
|
||||
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
|
||||
|
|
@ -829,7 +845,7 @@ stop(int collector_index, int thread_index, double as_of) {
|
|||
Collector *collector = get_collector_ptr(collector_index);
|
||||
InternalThread *thread = get_thread_ptr(thread_index);
|
||||
|
||||
if (client_is_connected() && collector->is_active() && thread->_is_active) {
|
||||
if (collector->is_active() && thread->_is_active) {
|
||||
LightMutexHolder holder(thread->_thread_lock);
|
||||
if (collector->_per_thread[thread_index]._nested_count == 0) {
|
||||
if (pstats_cat.is_debug()) {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,37 @@ INLINE CopyOnWritePointer::
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CopyOnWritePointer::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CopyOnWritePointer::
|
||||
CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT :
|
||||
_cow_object(move._cow_object)
|
||||
{
|
||||
// Steal the other's reference count.
|
||||
move._cow_object = (CopyOnWriteObject *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CopyOnWritePointer::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CopyOnWritePointer::
|
||||
operator = (CopyOnWritePointer &&move) NOEXCEPT {
|
||||
CopyOnWriteObject *old_object = _cow_object;
|
||||
_cow_object = move._cow_object;
|
||||
move._cow_object = NULL;
|
||||
|
||||
if (old_object != (CopyOnWriteObject *)NULL) {
|
||||
cache_unref_delete(old_object);
|
||||
}
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CopyOnWritePointer::operator ==
|
||||
// Access: Public
|
||||
|
|
@ -272,6 +303,35 @@ operator = (To *object) {
|
|||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CopyOnWritePointerTo::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE CopyOnWritePointerTo<T>::
|
||||
CopyOnWritePointerTo(CopyOnWritePointerTo<T> &&move) NOEXCEPT :
|
||||
CopyOnWritePointer((CopyOnWritePointer &&)move)
|
||||
{
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CopyOnWritePointerTo::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
INLINE void CopyOnWritePointerTo<T>::
|
||||
operator = (CopyOnWritePointerTo<T> &&move) NOEXCEPT {
|
||||
CopyOnWritePointer::operator = ((CopyOnWritePointer &&)move);
|
||||
}
|
||||
#endif // CPPPARSER
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifndef CPPPARSER
|
||||
#ifdef COW_THREADED
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ public:
|
|||
INLINE void operator = (CopyOnWriteObject *object);
|
||||
INLINE ~CopyOnWritePointer();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT;
|
||||
INLINE void operator = (CopyOnWritePointer &&move) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE bool operator == (const CopyOnWritePointer &other) const;
|
||||
INLINE bool operator != (const CopyOnWritePointer &other) const;
|
||||
INLINE bool operator < (const CopyOnWritePointer &other) const;
|
||||
|
|
@ -83,6 +88,11 @@ public:
|
|||
INLINE void operator = (const CopyOnWritePointerTo<T> ©);
|
||||
INLINE void operator = (To *object);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE CopyOnWritePointerTo(CopyOnWritePointerTo &&move) NOEXCEPT;
|
||||
INLINE void operator = (CopyOnWritePointerTo &&move) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
#ifdef COW_THREADED
|
||||
INLINE CPT(To) get_read_pointer() const;
|
||||
INLINE PT(To) get_write_pointer();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleHashMap::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key, class Value, class Compare>
|
||||
INLINE SimpleHashMap<Key, Value, Compare>::
|
||||
|
|
@ -32,7 +32,7 @@ SimpleHashMap(const Compare &comp) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleHashMap::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key, class Value, class Compare>
|
||||
INLINE SimpleHashMap<Key, Value, Compare>::
|
||||
|
|
@ -417,7 +417,7 @@ is_empty() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleHashMap::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key, class Value, class Compare>
|
||||
void SimpleHashMap<Key, Value, Compare>::
|
||||
|
|
@ -443,7 +443,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleHashMap::write
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Key, class Value, class Compare>
|
||||
void SimpleHashMap<Key, Value, Compare>::
|
||||
|
|
@ -575,9 +575,9 @@ void SimpleHashMap<Key, Value, Compare>::
|
|||
new_table() {
|
||||
nassertv(_table_size == 0 && _num_entries == 0);
|
||||
|
||||
// Pick a good initial table size. For now, we make it as small as
|
||||
// possible. Maybe that's the right answer.
|
||||
_table_size = 2;
|
||||
// Pick a good initial table size. For now, we make it really
|
||||
// small. Maybe that's the right answer.
|
||||
_table_size = 4;
|
||||
|
||||
// We allocate enough bytes for _table_size elements of TableEntry,
|
||||
// plus _table_size more bytes at the end (for the exists array).
|
||||
|
|
@ -618,7 +618,9 @@ expand_table() {
|
|||
SimpleHashMap<Key, Value, Compare> old_map(_comp);
|
||||
swap(old_map);
|
||||
|
||||
_table_size = (old_map._table_size << 1);
|
||||
// Double the table size.
|
||||
size_t old_table_size = old_map._table_size;
|
||||
_table_size = (old_table_size << 1);
|
||||
nassertv(_table == NULL);
|
||||
|
||||
// We allocate enough bytes for _table_size elements of TableEntry,
|
||||
|
|
@ -626,15 +628,30 @@ expand_table() {
|
|||
size_t alloc_size = _table_size * sizeof(TableEntry) + _table_size;
|
||||
_deleted_chain = memory_hook->get_deleted_chain(alloc_size);
|
||||
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, TypeHandle::none());
|
||||
memset(get_exists_array(), 0, _table_size);
|
||||
unsigned char *exists_array = get_exists_array();
|
||||
memset(exists_array, 0, _table_size);
|
||||
nassertv(_num_entries == 0);
|
||||
|
||||
// Now copy the entries from the old table into the new table.
|
||||
int num_added = 0;
|
||||
for (size_t i = 0; i < old_map._table_size; ++i) {
|
||||
for (size_t i = 0; i < old_table_size; ++i) {
|
||||
if (old_map.has_element(i)) {
|
||||
store(old_map._table[i]._key, old_map._table[i]._data);
|
||||
++num_added;
|
||||
size_t new_index = get_hash(old_map._table[i]._key);
|
||||
|
||||
while (exists_array[new_index] != 0) {
|
||||
// Hash conflict; look for a better spot. This has to succeed.
|
||||
new_index = (new_index + 1) & (_table_size - 1);
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
// Use C++11 rvalue references to invoke the move constructor,
|
||||
// which may be more efficient.
|
||||
new(&_table[new_index]) TableEntry(move(old_map._table[i]));
|
||||
#else
|
||||
new(&_table[new_index]) TableEntry(old_map._table[i]);
|
||||
#endif
|
||||
exists_array[new_index] = true;
|
||||
++_num_entries;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ private:
|
|||
INLINE TableEntry(const Key &key, const Value &data) :
|
||||
_key(key),
|
||||
_data(data) {}
|
||||
INLINE TableEntry(const TableEntry ©) :
|
||||
_key(copy._key),
|
||||
_data(copy._data) {}
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE TableEntry(TableEntry &&from) NOEXCEPT :
|
||||
_key(move(from._key)),
|
||||
_data(move(from._data)) {}
|
||||
#endif
|
||||
Key _key;
|
||||
Value _data;
|
||||
};
|
||||
|
|
@ -103,4 +111,3 @@ inline ostream &operator << (ostream &out, const SimpleHashMap<Key, Value, Compa
|
|||
#endif // CPPPARSER
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ TypeHandle TinyWinGraphicsWindow::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TinyWinGraphicsWindow::
|
||||
TinyWinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
TinyWinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
|
|
@ -85,7 +85,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
|
||||
tinygsg->_current_frame_buffer = _frame_buffer;
|
||||
tinygsg->reset_if_new();
|
||||
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ end_flip() {
|
|||
bmdc, 0, 0,fb_xsize, fb_ysize,
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
|
||||
DeleteDC(bmdc);
|
||||
DeleteObject(bm);
|
||||
GdiFlush();
|
||||
|
|
@ -220,7 +220,7 @@ open_window() {
|
|||
} else {
|
||||
DCAST_INTO_R(tinygsg, _gsg, false);
|
||||
}
|
||||
|
||||
|
||||
_hdc = GetDC(_hWnd);
|
||||
|
||||
create_frame_buffer();
|
||||
|
|
@ -231,7 +231,7 @@ open_window() {
|
|||
}
|
||||
|
||||
tinygsg->_current_frame_buffer = _frame_buffer;
|
||||
|
||||
|
||||
tinygsg->reset_if_new();
|
||||
if (!tinygsg->is_valid()) {
|
||||
close_window();
|
||||
|
|
@ -251,8 +251,10 @@ open_window() {
|
|||
void TinyWinGraphicsWindow::
|
||||
handle_reshape() {
|
||||
WinGraphicsWindow::handle_reshape();
|
||||
ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
|
||||
setup_bitmap_info();
|
||||
if (_frame_buffer != NULL) {
|
||||
ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
|
||||
setup_bitmap_info();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ void
|
|||
ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize) {
|
||||
int size;
|
||||
|
||||
nassertv(zb != NULL);
|
||||
|
||||
/* xsize must be a multiple of 4 */
|
||||
xsize = (xsize + 3) & ~3;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,10 +57,13 @@ ConfigVariableBool ime_hide
|
|||
PRC_DESC("Set this true to hide ime windows."));
|
||||
|
||||
ConfigVariableBool request_dxdisplay_information
|
||||
("request-dxdisplay-information", true,
|
||||
PRC_DESC("Setting this to false skips some display information discovery "
|
||||
"routines that can speed up initialization when DX support is "
|
||||
"present."));
|
||||
("request-dxdisplay-information", false,
|
||||
PRC_DESC("Setting this to true enables lumberingly slow and evil code at "
|
||||
"start-up that creates a Direct3D window and subsequently fills up "
|
||||
"up the video memory with dummy textures in order to find out how "
|
||||
"much video memory there actually is. Leave this disabled unless "
|
||||
"you have a specific need for this information and don't mind "
|
||||
"having a slow start-up."));
|
||||
|
||||
ConfigVariableBool swapbuffer_framelock
|
||||
("swapbuffer-framelock", false,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
TypeHandle WinGraphicsWindow::_type_handle;
|
||||
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
|
||||
|
||||
|
|
@ -86,7 +84,7 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) :
|
||||
GraphicsOutput *host) :
|
||||
GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||
{
|
||||
initialize_input_devices();
|
||||
|
|
@ -124,7 +122,7 @@ WinGraphicsWindow::
|
|||
// Function: WinGraphicsWindow::move_pointer
|
||||
// Access: Published, Virtual
|
||||
// Description: Forces the pointer to the indicated position within
|
||||
// the window, if possible.
|
||||
// the window, if possible.
|
||||
//
|
||||
// Returns true if successful, false on failure. This
|
||||
// may fail if the mouse is not currently within the
|
||||
|
|
@ -142,7 +140,7 @@ move_pointer(int device, int x, int y) {
|
|||
if (device == 0) {
|
||||
// Move the system mouse pointer.
|
||||
if (!_properties.get_foreground() )
|
||||
// !_input_devices[0].get_pointer().get_in_window())
|
||||
// !_input_devices[0].get_pointer().get_in_window())
|
||||
{
|
||||
// If the window doesn't have input focus, or the mouse isn't
|
||||
// currently within the window, forget it.
|
||||
|
|
@ -151,7 +149,7 @@ move_pointer(int device, int x, int y) {
|
|||
|
||||
RECT view_rect;
|
||||
get_client_rect_screen(_hWnd, &view_rect);
|
||||
|
||||
|
||||
SetCursorPos(view_rect.left + x, view_rect.top + y);
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
return true;
|
||||
|
|
@ -235,11 +233,11 @@ process_events() {
|
|||
}
|
||||
_return_control_to_app = false;
|
||||
|
||||
} else
|
||||
} else
|
||||
*/
|
||||
|
||||
MSG msg;
|
||||
|
||||
|
||||
// Handle all the messages on the queue in a row. Some of these
|
||||
// might be for another window, but they will get dispatched
|
||||
// appropriately.
|
||||
|
|
@ -314,18 +312,18 @@ set_properties_now(WindowProperties &properties) {
|
|||
WindowProperties::ZOrder last_z_order = _properties.get_z_order();
|
||||
_properties.set_z_order(properties.get_z_order());
|
||||
adjust_z_order(last_z_order, properties.get_z_order());
|
||||
|
||||
|
||||
properties.clear_z_order();
|
||||
}
|
||||
|
||||
if (properties.has_foreground() && properties.get_foreground()) {
|
||||
if (!SetActiveWindow(_hWnd)) {
|
||||
windisplay_cat.warning()
|
||||
windisplay_cat.warning()
|
||||
<< "SetForegroundWindow() failed!\n";
|
||||
} else {
|
||||
_properties.set_foreground(true);
|
||||
}
|
||||
|
||||
|
||||
properties.clear_foreground();
|
||||
}
|
||||
|
||||
|
|
@ -446,11 +444,11 @@ open_window() {
|
|||
// Now that we have a window handle, store it in our global map, so
|
||||
// future messages for this window can be routed properly.
|
||||
_window_handles.insert(WindowHandles::value_type(_hWnd, this));
|
||||
|
||||
|
||||
// move window to top of zorder.
|
||||
SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0,
|
||||
SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0,
|
||||
SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
|
||||
|
||||
|
||||
// need to do twice to override any minimized flags in StartProcessInfo
|
||||
if (want_minimized) {
|
||||
ShowWindow(_hWnd, SW_MINIMIZE);
|
||||
|
|
@ -492,8 +490,8 @@ open_window() {
|
|||
// Registers to receive the WM_INPUT messages
|
||||
if ((pRegisterRawInputDevices)&&(_input_devices.size() > 1)) {
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.dwFlags = 0;// RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages
|
||||
Rid.hwndTarget = _hWnd;
|
||||
pRegisterRawInputDevices(&Rid, 1, sizeof (Rid));
|
||||
|
|
@ -517,7 +515,7 @@ open_window() {
|
|||
#ifdef HAVE_WIN_TOUCHINPUT
|
||||
RegisterTouchWindow(_hWnd, 0);
|
||||
#endif
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -537,13 +535,13 @@ initialize_input_devices() {
|
|||
PRAWINPUTDEVICELIST pRawInputDeviceList;
|
||||
|
||||
nassertv(_input_devices.size() == 0);
|
||||
|
||||
|
||||
// Clear the handle array, and set up the system keyboard/mouse
|
||||
memset(_input_device_handle, 0, sizeof(_input_device_handle));
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
||||
add_input_device(device);
|
||||
|
||||
|
||||
// Try initializing the Raw Input function pointers.
|
||||
if (pRegisterRawInputDevices==0) {
|
||||
HMODULE user32 = LoadLibrary("user32.dll");
|
||||
|
|
@ -554,7 +552,7 @@ initialize_input_devices() {
|
|||
pGetRawInputData = (tGetRawInputData) GetProcAddress(user32,"GetRawInputData");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pRegisterRawInputDevices==0) return;
|
||||
if (pGetRawInputDeviceList==0) return;
|
||||
if (pGetRawInputDeviceInfoA==0) return;
|
||||
|
|
@ -563,7 +561,7 @@ initialize_input_devices() {
|
|||
// Get the number of devices.
|
||||
if (pGetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
|
||||
return;
|
||||
|
||||
|
||||
// Allocate the array to hold the DeviceList
|
||||
pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(sizeof(RAWINPUTDEVICELIST) * nInputDevices);
|
||||
if (pRawInputDeviceList==0) return;
|
||||
|
|
@ -571,7 +569,7 @@ initialize_input_devices() {
|
|||
// Fill the Array
|
||||
if (pGetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1)
|
||||
return;
|
||||
|
||||
|
||||
// Loop through all raw devices and find the raw mice
|
||||
for (int i = 0; i < (int)nInputDevices; i++) {
|
||||
if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
|
||||
|
|
@ -668,7 +666,7 @@ do_reshape_request(int x_origin, int y_origin, bool has_origin,
|
|||
has_origin = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Compute the appropriate size and placement for the window,
|
||||
// including decorations.
|
||||
RECT view_rect;
|
||||
|
|
@ -725,7 +723,7 @@ handle_reshape() {
|
|||
|
||||
// But in practice, GetClientRect() doesn't really fail, but just
|
||||
// returns all zeroes. Ignore this too.
|
||||
if (view_rect.left == 0 && view_rect.right == 0 &&
|
||||
if (view_rect.left == 0 && view_rect.right == 0 &&
|
||||
view_rect.bottom == 0 && view_rect.top == 0) {
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
|
|
@ -746,17 +744,17 @@ handle_reshape() {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WindowProperties properties;
|
||||
properties.set_size((view_rect.right - view_rect.left),
|
||||
properties.set_size((view_rect.right - view_rect.left),
|
||||
(view_rect.bottom - view_rect.top));
|
||||
|
||||
// _props origin should reflect upper left of view rectangle
|
||||
properties.set_origin(view_rect.left, view_rect.top);
|
||||
|
||||
|
||||
if (windisplay_cat.is_spam()) {
|
||||
windisplay_cat.spam()
|
||||
<< "reshape to origin: (" << properties.get_x_origin() << ","
|
||||
<< "reshape to origin: (" << properties.get_x_origin() << ","
|
||||
<< properties.get_y_origin() << "), size: (" << properties.get_x_size()
|
||||
<< "," << properties.get_y_size() << ")\n";
|
||||
}
|
||||
|
|
@ -788,22 +786,22 @@ do_fullscreen_resize(int x_size, int y_size) {
|
|||
if (!find_acceptable_display_mode(x_size, y_size,
|
||||
dwFullScreenBitDepth, dm)) {
|
||||
windisplay_cat.error()
|
||||
<< "window resize(" << x_size << ", " << y_size
|
||||
<< "window resize(" << x_size << ", " << y_size
|
||||
<< ") failed, no compatible fullscreen display mode found!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// this causes WM_SIZE msg to be produced
|
||||
SetWindowPos(_hWnd, NULL, 0,0, x_size, y_size,
|
||||
SetWindowPos(_hWnd, NULL, 0,0, x_size, y_size,
|
||||
SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING);
|
||||
int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
|
||||
|
||||
if (chg_result != DISP_CHANGE_SUCCESSFUL) {
|
||||
windisplay_cat.error()
|
||||
<< "resize ChangeDisplaySettings failed (error code: "
|
||||
<< "resize ChangeDisplaySettings failed (error code: "
|
||||
<< chg_result << ") for specified res: "
|
||||
<< dm.dmPelsWidth << " x " << dm.dmPelsHeight
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< dm.dmDisplayFrequency << " Hz\n";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -811,7 +809,7 @@ do_fullscreen_resize(int x_size, int y_size) {
|
|||
_fullscreen_display_mode = dm;
|
||||
|
||||
windisplay_cat.info()
|
||||
<< "Resized fullscreen window to " << x_size << ", " << y_size
|
||||
<< "Resized fullscreen window to " << x_size << ", " << y_size
|
||||
<< " bitdepth " << dwFullScreenBitDepth << ", "
|
||||
<< dm.dmDisplayFrequency << "Hz\n";
|
||||
|
||||
|
|
@ -866,7 +864,7 @@ do_windowed_switch() {
|
|||
if (!calculate_metrics(false, window_style, metrics, has_origin)){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// We send SWP_FRAMECHANGED so that the new styles are taken into account.
|
||||
// Also, we place the Windows at 0,0 to play safe until we decide how to
|
||||
// get Panda to remember the windowed origin.
|
||||
|
|
@ -950,7 +948,7 @@ calculate_metrics(bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
|
|||
if (!fullscreen && has_origin) {
|
||||
metrics.x = _properties.get_x_origin();
|
||||
metrics.y = _properties.get_y_origin();
|
||||
|
||||
|
||||
// A coordinate of -2 means to center the window in its client area.
|
||||
if (metrics.x == -2) {
|
||||
metrics.x = 0.5 * (_pipe->get_display_width() - _properties.get_x_size());
|
||||
|
|
@ -974,7 +972,7 @@ calculate_metrics(bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
|
|||
RECT win_rect;
|
||||
SetRect(&win_rect, metrics.x, metrics.y,
|
||||
metrics.x + metrics.width, metrics.y + metrics.height);
|
||||
|
||||
|
||||
// Compute window size based on desired client area size
|
||||
if (!AdjustWindowRect(&win_rect, window_style, FALSE)) {
|
||||
windisplay_cat.error()
|
||||
|
|
@ -1004,7 +1002,7 @@ calculate_metrics(bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
|
|||
bool WinGraphicsWindow::
|
||||
open_graphic_window(bool fullscreen) {
|
||||
DWORD window_style = make_style(fullscreen);
|
||||
|
||||
|
||||
wstring title;
|
||||
if (_properties.has_title()) {
|
||||
TextEncoder encoder;
|
||||
|
|
@ -1026,7 +1024,7 @@ open_graphic_window(bool fullscreen) {
|
|||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
||||
|
||||
_hparent = NULL;
|
||||
|
||||
|
||||
if (!fullscreen){
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
if (window_handle != NULL) {
|
||||
|
|
@ -1036,7 +1034,7 @@ open_graphic_window(bool fullscreen) {
|
|||
if (os_handle != NULL) {
|
||||
windisplay_cat.info()
|
||||
<< "os_handle type " << os_handle->get_type() << "\n";
|
||||
|
||||
|
||||
if (os_handle->is_of_type(NativeWindowHandle::WinHandle::get_class_type())) {
|
||||
NativeWindowHandle::WinHandle *win_handle = DCAST(NativeWindowHandle::WinHandle, os_handle);
|
||||
_hparent = win_handle->get_handle();
|
||||
|
|
@ -1052,7 +1050,7 @@ open_graphic_window(bool fullscreen) {
|
|||
}
|
||||
|
||||
if (!_hparent) { // This can be a regular window or a fullscreen window
|
||||
_hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(), window_style,
|
||||
_hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(), window_style,
|
||||
metrics.x, metrics.y,
|
||||
metrics.width,
|
||||
metrics.height,
|
||||
|
|
@ -1060,18 +1058,18 @@ open_graphic_window(bool fullscreen) {
|
|||
} else { // This is a regular window with a parent
|
||||
int x_origin = 0;
|
||||
int y_origin = 0;
|
||||
|
||||
|
||||
if (!fullscreen && has_origin) {
|
||||
x_origin = _properties.get_x_origin();
|
||||
y_origin = _properties.get_y_origin();
|
||||
}
|
||||
|
||||
_hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(),
|
||||
_hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(),
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
|
||||
x_origin, y_origin,
|
||||
_properties.get_x_size(), _properties.get_y_size(),
|
||||
_hparent, NULL, hinstance, 0);
|
||||
|
||||
|
||||
if (_hWnd) {
|
||||
// join our keyboard state with the parents
|
||||
|
||||
|
|
@ -1079,13 +1077,13 @@ open_graphic_window(bool fullscreen) {
|
|||
// It causes problems with the browser plugin--it deadlocks when
|
||||
// the parent process is waiting on the child process.
|
||||
//AttachThreadInput(GetWindowThreadProcessId(_hparent,NULL), GetCurrentThreadId(),TRUE);
|
||||
|
||||
|
||||
WindowProperties properties;
|
||||
properties.set_foreground(true);
|
||||
system_changed_properties(properties);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!_hWnd) {
|
||||
windisplay_cat.error()
|
||||
<< "CreateWindow() failed!" << endl;
|
||||
|
|
@ -1123,7 +1121,7 @@ do_fullscreen_enable() {
|
|||
// DWORD cur_scrnwidth = GetDeviceCaps(scrnDC, HORZRES);
|
||||
// DWORD cur_scrnheight = GetDeviceCaps(scrnDC, VERTRES);
|
||||
ReleaseDC(hDesktopWindow, scrnDC);
|
||||
|
||||
|
||||
DWORD dwWidth = _properties.get_x_size();
|
||||
DWORD dwHeight = _properties.get_y_size();
|
||||
DWORD dwFullScreenBitDepth = cur_bitdepth;
|
||||
|
|
@ -1131,7 +1129,7 @@ do_fullscreen_enable() {
|
|||
DEVMODE dm;
|
||||
reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
|
||||
if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, dm)) {
|
||||
windisplay_cat.error()
|
||||
windisplay_cat.error()
|
||||
<< "Videocard has no supported display resolutions at specified res ("
|
||||
<< dwWidth << " x " << dwHeight << " x " << dwFullScreenBitDepth <<")\n";
|
||||
return false;
|
||||
|
|
@ -1147,7 +1145,7 @@ do_fullscreen_enable() {
|
|||
<< "ChangeDisplaySettings failed (error code: "
|
||||
<< chg_result << ") for specified res: "
|
||||
<< dm.dmPelsWidth << " x " << dm.dmPelsHeight
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< dm.dmDisplayFrequency << " Hz\n";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1202,13 +1200,13 @@ adjust_z_order(WindowProperties::ZOrder last_z_order,
|
|||
WindowProperties::ZOrder this_z_order) {
|
||||
HWND order;
|
||||
bool do_change = false;
|
||||
|
||||
|
||||
switch (this_z_order) {
|
||||
case WindowProperties::Z_bottom:
|
||||
order = HWND_BOTTOM;
|
||||
do_change = true;
|
||||
break;
|
||||
|
||||
|
||||
case WindowProperties::Z_normal:
|
||||
if ((last_z_order != WindowProperties::Z_normal) &&
|
||||
// If we aren't changing the window order, don't move it to
|
||||
|
|
@ -1223,14 +1221,14 @@ adjust_z_order(WindowProperties::ZOrder last_z_order,
|
|||
do_change = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WindowProperties::Z_top:
|
||||
order = HWND_TOPMOST;
|
||||
do_change = true;
|
||||
break;
|
||||
}
|
||||
if (do_change) {
|
||||
BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
|
||||
BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
|
||||
SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
|
||||
if (!result) {
|
||||
windisplay_cat.warning()
|
||||
|
|
@ -1265,13 +1263,13 @@ track_mouse_leaving(HWND hwnd) {
|
|||
};
|
||||
|
||||
// tell win32 to post WM_MOUSELEAVE msgs
|
||||
BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme);
|
||||
|
||||
BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme);
|
||||
|
||||
if ((!bSucceeded) && windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
|
||||
}
|
||||
|
||||
|
||||
_tracking_mouse_leaving = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1331,7 +1329,7 @@ LONG WinGraphicsWindow::
|
|||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
if (windisplay_cat.is_spam()) {
|
||||
windisplay_cat.spam()
|
||||
<< ClockObject::get_global_clock()->get_real_time()
|
||||
<< ClockObject::get_global_clock()->get_real_time()
|
||||
<< " window_proc(" << (void *)this << ", " << hwnd << ", "
|
||||
<< msg << ", " << wparam << ", " << lparam << ")\n";
|
||||
}
|
||||
|
|
@ -1339,7 +1337,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
int button = -1;
|
||||
|
||||
switch (msg) {
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEMOVE:
|
||||
if (!_tracking_mouse_leaving) {
|
||||
// need to re-call TrackMouseEvent every time mouse re-enters window
|
||||
track_mouse_leaving(hwnd);
|
||||
|
|
@ -1348,22 +1346,22 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
if(handle_mouse_motion(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
|
||||
case WM_INPUT:
|
||||
handle_raw_input((HRAWINPUT)lparam);
|
||||
break;
|
||||
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
_tracking_mouse_leaving = false;
|
||||
handle_mouse_exit();
|
||||
set_cursor_out_of_window();
|
||||
break;
|
||||
|
||||
case WM_CREATE:
|
||||
|
||||
case WM_CREATE:
|
||||
{
|
||||
track_mouse_leaving(hwnd);
|
||||
ClearToBlack(hwnd, _properties);
|
||||
|
||||
|
||||
POINT cpos;
|
||||
GetCursorPos(&cpos);
|
||||
ScreenToClient(hwnd, &cpos);
|
||||
|
|
@ -1399,7 +1397,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
break;
|
||||
*/
|
||||
|
||||
|
||||
case WM_CLOSE:
|
||||
// This is a message from the system indicating that the user
|
||||
// has requested to close the window (e.g. alt-f4).
|
||||
|
|
@ -1410,14 +1408,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
// the request and process it directly.
|
||||
throw_event(close_request_event);
|
||||
return 0;
|
||||
|
||||
|
||||
} else {
|
||||
// In this case, the default case, the app does not intend
|
||||
// to service the request, so we do by closing the window.
|
||||
close_window();
|
||||
properties.set_open(false);
|
||||
system_changed_properties(properties);
|
||||
|
||||
|
||||
// TODO: make sure we release the GSG properly.
|
||||
}
|
||||
}
|
||||
|
|
@ -1429,17 +1427,17 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
<< "WM_CHILDACTIVATE: " << hwnd << "\n";
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_ACTIVATE:
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "WM_ACTIVATE: " << hwnd << ", " << wparam << ", " << lparam << "\n";
|
||||
}
|
||||
properties.set_minimized((wparam & 0xffff0000) != 0);
|
||||
if ((wparam & 0xffff) != WA_INACTIVE)
|
||||
if ((wparam & 0xffff) != WA_INACTIVE)
|
||||
{
|
||||
properties.set_foreground(true);
|
||||
if (is_fullscreen())
|
||||
if (is_fullscreen())
|
||||
{
|
||||
// When a fullscreen window goes active, it automatically gets
|
||||
// un-minimized.
|
||||
|
|
@ -1448,10 +1446,10 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
if (chg_result != DISP_CHANGE_SUCCESSFUL) {
|
||||
const DEVMODE &dm = _fullscreen_display_mode;
|
||||
windisplay_cat.error()
|
||||
<< "restore ChangeDisplaySettings failed (error code: "
|
||||
<< "restore ChangeDisplaySettings failed (error code: "
|
||||
<< chg_result << ") for specified res: "
|
||||
<< dm.dmPelsWidth << " x " << dm.dmPelsHeight
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< " x " << dm.dmBitsPerPel << ", "
|
||||
<< dm.dmDisplayFrequency << " Hz\n";
|
||||
}
|
||||
|
||||
|
|
@ -1460,10 +1458,10 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
fullscreen_restored(properties);
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
properties.set_foreground(false);
|
||||
if (is_fullscreen())
|
||||
if (is_fullscreen())
|
||||
{
|
||||
// When a fullscreen window goes inactive, it automatically
|
||||
// gets minimized.
|
||||
|
|
@ -1489,7 +1487,10 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
<< "WM_SIZE: " << hwnd << ", " << wparam << "\n";
|
||||
}
|
||||
|
||||
handle_reshape();
|
||||
// Resist calling handle_reshape before the window has opened.
|
||||
if (_hWnd == NULL) {
|
||||
handle_reshape();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_EXITSIZEMOVE:
|
||||
|
|
@ -1524,7 +1525,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
// A button-click in the window means to grab the keyboard focus.
|
||||
set_focus();
|
||||
return 0;
|
||||
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
if (_lost_keypresses) {
|
||||
resend_lost_keypresses();
|
||||
|
|
@ -1562,7 +1563,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
if (_lost_keypresses) {
|
||||
resend_lost_keypresses();
|
||||
|
|
@ -1628,7 +1629,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case WM_IME_SETCONTEXT:
|
||||
if (!ime_hide)
|
||||
break;
|
||||
|
|
@ -1640,15 +1641,15 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
windisplay_cat.debug() << "SendMessage failed for " << _ime_hWnd << endl;
|
||||
else
|
||||
windisplay_cat.debug() << "SendMessage Succeeded for " << _ime_hWnd << endl;
|
||||
|
||||
|
||||
windisplay_cat.debug() << "wparam is " << wparam << ", lparam is " << lparam << endl;
|
||||
lparam &= ~ISC_SHOWUIALL;
|
||||
if (ImmIsUIMessage(_ime_hWnd, msg, wparam, lparam))
|
||||
windisplay_cat.debug() << "wparam is " << wparam << ", lparam is " << lparam << endl;
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case WM_IME_NOTIFY:
|
||||
if (wparam == IMN_SETOPENSTATUS) {
|
||||
HIMC hIMC = ImmGetContext(hwnd);
|
||||
|
|
@ -1663,20 +1664,20 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
CANDIDATEFORM canf;
|
||||
ImmGetCompositionWindow(hIMC, &comf);
|
||||
ImmGetCandidateWindow(hIMC, 0, &canf);
|
||||
windisplay_cat.debug() <<
|
||||
"comf style " << comf.dwStyle <<
|
||||
windisplay_cat.debug() <<
|
||||
"comf style " << comf.dwStyle <<
|
||||
" comf point: x" << comf.ptCurrentPos.x << ",y " << comf.ptCurrentPos.y <<
|
||||
" comf rect: l " << comf.rcArea.left << ",t " << comf.rcArea.top << ",r " <<
|
||||
comf.rcArea.right << ",b " << comf.rcArea.bottom << endl;
|
||||
windisplay_cat.debug() <<
|
||||
"canf style " << canf.dwStyle <<
|
||||
windisplay_cat.debug() <<
|
||||
"canf style " << canf.dwStyle <<
|
||||
" canf point: x" << canf.ptCurrentPos.x << ",y " << canf.ptCurrentPos.y <<
|
||||
" canf rect: l " << canf.rcArea.left << ",t " << canf.rcArea.top << ",r " <<
|
||||
canf.rcArea.right << ",b " << canf.rcArea.bottom << endl;
|
||||
comf.dwStyle = CFS_POINT;
|
||||
comf.ptCurrentPos.x = 2000;
|
||||
comf.ptCurrentPos.y = 2000;
|
||||
|
||||
|
||||
canf.dwStyle = CFS_EXCLUDE;
|
||||
canf.dwIndex = 0;
|
||||
canf.ptCurrentPos.x = 0;
|
||||
|
|
@ -1685,14 +1686,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
canf.rcArea.top = 0;
|
||||
canf.rcArea.right = 640;
|
||||
canf.rcArea.bottom = 480;
|
||||
|
||||
|
||||
#if 0
|
||||
comf.rcArea.left = 200;
|
||||
comf.rcArea.top = 200;
|
||||
comf.rcArea.right = 0;
|
||||
comf.rcArea.bottom = 0;
|
||||
#endif
|
||||
|
||||
|
||||
if (ImmSetCompositionWindow(hIMC, &comf))
|
||||
windisplay_cat.debug() << "set composition form: success\n";
|
||||
for (int i=0; i<3; ++i) {
|
||||
|
|
@ -1705,12 +1706,12 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
ImmReleaseContext(hwnd, hIMC);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
support_overlay_window(true);
|
||||
_ime_active = true;
|
||||
break;
|
||||
|
||||
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
support_overlay_window(false);
|
||||
_ime_active = false;
|
||||
|
|
@ -1719,9 +1720,9 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
wstring ws;
|
||||
_input_devices[0].candidate(ws, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
if (ime_aware) {
|
||||
|
||||
|
|
@ -1736,13 +1737,13 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
|
||||
HIMC hIMC = ImmGetContext(hwnd);
|
||||
nassertr(hIMC != 0, 0);
|
||||
|
||||
|
||||
DWORD result_size = 0;
|
||||
static const int ime_buffer_size = 256;
|
||||
static const int ime_buffer_size_bytes = ime_buffer_size / sizeof(wchar_t);
|
||||
wchar_t ime_buffer[ime_buffer_size];
|
||||
size_t cursor_pos, delta_start;
|
||||
|
||||
|
||||
if (lparam & GCS_RESULTSTR) {
|
||||
result_size = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
|
||||
ime_buffer, ime_buffer_size_bytes);
|
||||
|
|
@ -1755,21 +1756,21 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
if (lparam & GCS_COMPSTR) {
|
||||
result_size = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, NULL, 0);
|
||||
cursor_pos = result_size & 0xffff;
|
||||
|
||||
|
||||
result_size = ImmGetCompositionStringW(hIMC, GCS_DELTASTART, NULL, 0);
|
||||
delta_start = result_size & 0xffff;
|
||||
result_size = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, ime_buffer, ime_buffer_size);
|
||||
size_t num_chars = result_size / sizeof(wchar_t);
|
||||
|
||||
_input_devices[0].candidate(wstring(ime_buffer, num_chars),
|
||||
min(cursor_pos, delta_start),
|
||||
max(cursor_pos, delta_start),
|
||||
|
||||
_input_devices[0].candidate(wstring(ime_buffer, num_chars),
|
||||
min(cursor_pos, delta_start),
|
||||
max(cursor_pos, delta_start),
|
||||
cursor_pos);
|
||||
}
|
||||
ImmReleaseContext(hwnd, hIMC);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_CHAR:
|
||||
// Ignore WM_CHAR messages if we have the IME open, since
|
||||
// everything will come in through WM_IME_COMPOSITION. (It's
|
||||
|
|
@ -1786,8 +1787,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
_input_devices[0].keystroke(wparam);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
if (_lost_keypresses) {
|
||||
resend_lost_keypresses();
|
||||
}
|
||||
|
|
@ -1802,7 +1803,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||
get_message_time());
|
||||
|
||||
if ((lparam & 0x40000000) == 0) {
|
||||
|
|
@ -1836,7 +1837,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
if (wparam == SC_KEYMENU) {
|
||||
// if Alt is released (alone w/o other keys), defwindproc will
|
||||
|
|
@ -1850,8 +1851,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if (_lost_keypresses) {
|
||||
resend_lost_keypresses();
|
||||
}
|
||||
|
|
@ -1905,7 +1906,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
!_input_devices.empty()) {
|
||||
HGLOBAL hglb;
|
||||
char *lptstr;
|
||||
|
||||
|
||||
if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) {
|
||||
// Maybe we should support CF_UNICODETEXT if it is available
|
||||
// too?
|
||||
|
|
@ -1985,7 +1986,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
if (_lost_keypresses) {
|
||||
|
|
@ -2031,8 +2032,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "killfocus\n";
|
||||
|
|
@ -2042,8 +2043,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
properties.set_foreground(false);
|
||||
system_changed_properties(properties);
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
|
||||
case WM_SETFOCUS:
|
||||
// You would think that this would be a good time to call
|
||||
// resend_lost_keypresses(), but it turns out that we get
|
||||
// WM_SETFOCUS slightly before Windows starts resending key
|
||||
|
|
@ -2196,9 +2197,9 @@ update_cursor_window(WinGraphicsWindow *to_window) {
|
|||
// We are leaving a graphics window; we should restore the Win2000
|
||||
// effects.
|
||||
if (_got_saved_params) {
|
||||
SystemParametersInfo(SPI_SETMOUSETRAILS, NULL,
|
||||
SystemParametersInfo(SPI_SETMOUSETRAILS, NULL,
|
||||
(PVOID)_saved_mouse_trails, NULL);
|
||||
SystemParametersInfo(SPI_SETCURSORSHADOW, NULL,
|
||||
SystemParametersInfo(SPI_SETCURSORSHADOW, NULL,
|
||||
(PVOID)_saved_cursor_shadow, NULL);
|
||||
SystemParametersInfo(SPI_SETMOUSEVANISH, NULL,
|
||||
(PVOID)_saved_mouse_vanish, NULL);
|
||||
|
|
@ -2216,11 +2217,11 @@ update_cursor_window(WinGraphicsWindow *to_window) {
|
|||
// These parameters are only defined for Win2000/XP, but they
|
||||
// should just cause a silent error on earlier OS's, which is OK.
|
||||
if (!_got_saved_params) {
|
||||
SystemParametersInfo(SPI_GETMOUSETRAILS, NULL,
|
||||
SystemParametersInfo(SPI_GETMOUSETRAILS, NULL,
|
||||
&_saved_mouse_trails, NULL);
|
||||
SystemParametersInfo(SPI_GETCURSORSHADOW, NULL,
|
||||
SystemParametersInfo(SPI_GETCURSORSHADOW, NULL,
|
||||
&_saved_cursor_shadow, NULL);
|
||||
SystemParametersInfo(SPI_GETMOUSEVANISH, NULL,
|
||||
SystemParametersInfo(SPI_GETMOUSEVANISH, NULL,
|
||||
&_saved_mouse_vanish, NULL);
|
||||
_got_saved_params = true;
|
||||
|
||||
|
|
@ -2231,7 +2232,7 @@ update_cursor_window(WinGraphicsWindow *to_window) {
|
|||
|
||||
SetCursor(to_window->_cursor);
|
||||
}
|
||||
|
||||
|
||||
hide_or_show_cursor(hide_cursor);
|
||||
|
||||
_cursor_window = to_window;
|
||||
|
|
@ -2280,18 +2281,18 @@ find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
|
|||
while (1) {
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
|
||||
|
||||
if (!EnumDisplaySettings(NULL, modenum, &dm)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
|
||||
(dm.dmBitsPerPel == bpp)) {
|
||||
return true;
|
||||
}
|
||||
modenum++;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2309,7 +2310,7 @@ show_error_message(DWORD message_id) {
|
|||
if (message_id == 0) {
|
||||
message_id = GetLastError();
|
||||
}
|
||||
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, message_id,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
|
||||
|
|
@ -2681,26 +2682,26 @@ handle_raw_input(HRAWINPUT hraw) {
|
|||
if (pGetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
lpb = (LPBYTE)alloca(sizeof(LPBYTE) * dwSize);
|
||||
if (lpb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pGetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RAWINPUT *raw = (RAWINPUT *)lpb;
|
||||
if (raw->header.hDevice == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 1; i < (int)(_input_devices.size()); ++i) {
|
||||
if (_input_device_handle[i] == raw->header.hDevice) {
|
||||
int adjx = raw->data.mouse.lLastX;
|
||||
int adjy = raw->data.mouse.lLastY;
|
||||
|
||||
|
||||
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
|
||||
_input_devices[i].set_pointer_in_window(adjx, adjy);
|
||||
} else {
|
||||
|
|
@ -2708,7 +2709,7 @@ handle_raw_input(HRAWINPUT hraw) {
|
|||
int oldy = _input_devices[i].get_raw_pointer().get_y();
|
||||
_input_devices[i].set_pointer_in_window(oldx + adjx, oldy + adjy);
|
||||
}
|
||||
|
||||
|
||||
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
|
||||
_input_devices[i].button_down(MouseButton::button(0), get_message_time());
|
||||
}
|
||||
|
|
@ -2871,7 +2872,7 @@ get_cursor(const Filename &filename) {
|
|||
}
|
||||
|
||||
static HCURSOR get_cursor(const Filename &filename);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::register_window_class
|
||||
// Access: Private, Static
|
||||
|
|
@ -2912,7 +2913,7 @@ register_window_class(const WindowProperties &props) {
|
|||
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = wclass._name.c_str();
|
||||
|
||||
|
||||
if (!RegisterClassW(&wc)) {
|
||||
windisplay_cat.error()
|
||||
<< "could not register window class " << wclass._name << "!" << endl;
|
||||
|
|
@ -2925,7 +2926,7 @@ register_window_class(const WindowProperties &props) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::WinWindowHandle::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinGraphicsWindow::WinWindowHandle::
|
||||
WinWindowHandle(WinGraphicsWindow *window, const WindowHandle ©) :
|
||||
|
|
@ -3033,7 +3034,7 @@ void get_client_rect_screen(HWND hwnd, RECT *view_rect) {
|
|||
// Access: Public, Virtual
|
||||
// Description: Adds the specified Windows proc event handler to be called
|
||||
// whenever a Windows event occurs.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::add_window_proc( const GraphicsWindowProc* wnd_proc ){
|
||||
nassertv(wnd_proc != NULL);
|
||||
|
|
@ -3044,7 +3045,7 @@ void WinGraphicsWindow::add_window_proc( const GraphicsWindowProc* wnd_proc ){
|
|||
// Function: WinGraphicsWindow::remove_window_proc
|
||||
// Access: Public, Virtual
|
||||
// Description: Removes the specified Windows proc event handler.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::remove_window_proc( const GraphicsWindowProc* wnd_proc ){
|
||||
nassertv(wnd_proc != NULL);
|
||||
|
|
@ -3055,7 +3056,7 @@ void WinGraphicsWindow::remove_window_proc( const GraphicsWindowProc* wnd_proc )
|
|||
// Function: WinGraphicsWindow::clear_window_procs
|
||||
// Access: Public, Virtual
|
||||
// Description: Removes all Windows proc event handlers.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::clear_window_procs(){
|
||||
_window_proc_classes.clear();
|
||||
|
|
@ -3065,7 +3066,7 @@ void WinGraphicsWindow::clear_window_procs(){
|
|||
// Function: WinGraphicsWindow::supports_window_procs
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns whether this window supports adding of windows proc handlers.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WinGraphicsWindow::supports_window_procs() const{
|
||||
return true;
|
||||
|
|
@ -3075,7 +3076,7 @@ bool WinGraphicsWindow::supports_window_procs() const{
|
|||
// Function: WinGraphicsWindow::is_touch_event
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns whether the specified event msg is a touch message.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WinGraphicsWindow::
|
||||
is_touch_event(GraphicsWindowProcCallbackData* callbackData){
|
||||
|
|
@ -3090,7 +3091,7 @@ is_touch_event(GraphicsWindowProcCallbackData* callbackData){
|
|||
// Function: WinGraphicsWindow::get_num_touches
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the current number of touches on this window.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int WinGraphicsWindow::
|
||||
get_num_touches(){
|
||||
|
|
@ -3105,7 +3106,7 @@ get_num_touches(){
|
|||
// Function: WinGraphicsWindow::get_touch_info
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the TouchInfo object describing the specified touch.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TouchInfo WinGraphicsWindow::
|
||||
get_touch_info(int index){
|
||||
|
|
|
|||
Loading…
Reference in New Issue