This commit is contained in:
David Rose 2016-01-11 13:27:24 -08:00
commit bc58335214
135 changed files with 5429 additions and 3161 deletions

View File

@ -399,7 +399,6 @@ class Interval(DirectObject):
return (space + self.name + ' dur: %.2f' % self.duration)
open_ended = property(getOpenEnded)
loop = property(getLoop, setLoop)
stopped = property(isStopped)
t = property(getT, setT)
play_rate = property(getPlayRate, setPlayRate)

View File

@ -87,6 +87,26 @@ is_trivial() const {
return _element_type->is_trivial();
}
////////////////////////////////////////////////////////////////////
// Function: CPPArrayType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPArrayType::
is_default_constructible() const {
return _element_type->is_default_constructible();
}
////////////////////////////////////////////////////////////////////
// Function: CPPArrayType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPArrayType::
is_copy_constructible() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPArrayType::is_equivalent
// Access: Public, Virtual

View File

@ -41,6 +41,8 @@ public:
CPPScope *global_scope);
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(ostream &out, int indent_level, CPPScope *scope,

File diff suppressed because it is too large Load Diff

View File

@ -1524,6 +1524,14 @@ maybe_initialize_or_function_body:
| '=' const_expr ';'
{
$$ = $2;
}
| '=' KW_DEFAULT ';'
{
$$ = new CPPExpression(CPPExpression::get_default());
}
| '=' KW_DELETE ';'
{
$$ = new CPPExpression(CPPExpression::get_delete());
}
| '=' '{' structure_init '}'
{

View File

@ -112,6 +112,26 @@ is_trivial() const {
return _wrapped_around->is_trivial();
}
////////////////////////////////////////////////////////////////////
// Function: CPPConstType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPConstType::
is_default_constructible() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPConstType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPConstType::
is_copy_constructible() const {
return _wrapped_around->is_copy_constructible();
}
////////////////////////////////////////////////////////////////////
// Function: CPPConstType::is_equivalent
// Access: Public, Virtual

View File

@ -39,6 +39,8 @@ public:
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(ostream &out, int indent_level, CPPScope *scope,

View File

@ -494,6 +494,30 @@ get_nullptr() {
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::get_default
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
const CPPExpression &CPPExpression::
get_default() {
static CPPExpression expr(0);
expr._type = T_default;
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::get_delete
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
const CPPExpression &CPPExpression::
get_delete() {
static CPPExpression expr(0);
expr._type = T_delete;
return expr;
}
////////////////////////////////////////////////////////////////////
// Function: CPPExpression::Destructor
// Access: Public
@ -1619,6 +1643,14 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
}
break;
case T_default:
out << "default";
break;
case T_delete:
out << "delete";
break;
default:
out << "(** invalid operand type " << (int)_type << " **)";
}

View File

@ -52,6 +52,8 @@ public:
static CPPExpression raw_literal(const string &raw, CPPInstance *lit_op);
static const CPPExpression &get_nullptr();
static const CPPExpression &get_default();
static const CPPExpression &get_delete();
~CPPExpression();
@ -124,6 +126,10 @@ public:
T_trinary_operation,
T_literal,
T_raw_literal,
// These are used when parsing =default and =delete methods.
T_default,
T_delete,
};
Type _type;

View File

@ -114,6 +114,26 @@ is_trivial() const {
return (_type == T_enum);
}
////////////////////////////////////////////////////////////////////
// Function: CPPExtensionType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPExtensionType::
is_default_constructible() const {
return (_type == T_enum);
}
////////////////////////////////////////////////////////////////////
// Function: CPPExtensionType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPExtensionType::
is_copy_constructible() const {
return (_type == T_enum);
}
////////////////////////////////////////////////////////////////////
// Function: CPPExtensionType::substitute_decl
// Access: Public, Virtual

View File

@ -48,6 +48,8 @@ public:
virtual bool is_incomplete() const;
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,

View File

@ -251,12 +251,20 @@ void CPPInstance::
set_initializer(CPPExpression *initializer) {
if (_type->as_function_type() != (CPPFunctionType *)NULL) {
// This is a function declaration.
if (initializer == (CPPExpression *)NULL) {
_storage_class &= ~SC_pure_virtual;
} else {
_storage_class |= SC_pure_virtual;
}
_storage_class &= ~(SC_pure_virtual | SC_defaulted | SC_deleted);
_initializer = (CPPExpression *)NULL;
if (initializer != (CPPExpression *)NULL) {
if (initializer->_type == CPPExpression::T_integer) { // = 0
_storage_class |= SC_pure_virtual;
} else if (initializer->_type == CPPExpression::T_default) {
_storage_class |= SC_defaulted;
} else if (initializer->_type == CPPExpression::T_delete) {
_storage_class |= SC_deleted;
}
}
} else {
_initializer = initializer;
}
@ -622,6 +630,12 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
if (_storage_class & SC_pure_virtual) {
out << " = 0";
}
if (_storage_class & SC_defaulted) {
out << " = default";
}
if (_storage_class & SC_deleted) {
out << " = delete";
}
if (_initializer != NULL) {
out << " = " << *_initializer;
}

View File

@ -60,6 +60,10 @@ public:
// And this is for methods tagged with __extension, which declares
// extension methods defined separately from the source code.
SC_extension = 0x2000,
// These are for =default and =delete functions.
SC_defaulted = 0x4000,
SC_deleted = 0x8000,
};
CPPInstance(CPPType *type, const string &name, int storage_class = 0);

View File

@ -114,6 +114,26 @@ is_trivial() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPPointerType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPPointerType::
is_default_constructible() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPPointerType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPPointerType::
is_copy_constructible() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPPointerType::is_equivalent
// Access: Public, Virtual

View File

@ -39,6 +39,8 @@ public:
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(ostream &out, int indent_level, CPPScope *scope,

View File

@ -113,6 +113,26 @@ is_trivial() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPReferenceType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPReferenceType::
is_default_constructible() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPReferenceType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPReferenceType::
is_copy_constructible() const {
return (_value_category == VC_lvalue);
}
////////////////////////////////////////////////////////////////////
// Function: CPPReferenceType::is_equivalent
// Access: Public, Virtual

View File

@ -45,6 +45,8 @@ public:
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(ostream &out, int indent_level, CPPScope *scope,

View File

@ -51,6 +51,26 @@ is_trivial() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPSimpleType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPSimpleType::
is_default_constructible() const {
return (_type != T_void);
}
////////////////////////////////////////////////////////////////////
// Function: CPPSimpleType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPSimpleType::
is_copy_constructible() const {
return (_type != T_void);
}
////////////////////////////////////////////////////////////////////
// Function: CPPSimpleType::is_parameter_expr
// Access: Public, Virtual

View File

@ -79,6 +79,8 @@ public:
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_parameter_expr() const;
virtual string get_preferred_name() const;

View File

@ -190,6 +190,11 @@ is_trivial() const {
return false;
}
// The following checks don't apply for defaulted functions.
if (inst->_storage_class & CPPInstance::SC_defaulted) {
continue;
}
assert(inst->_type != (CPPType *)NULL);
CPPFunctionType *ftype = inst->_type->as_function_type();
assert(ftype != (CPPFunctionType *)NULL);
@ -197,7 +202,8 @@ is_trivial() const {
if (ftype->_flags & (CPPFunctionType::F_destructor |
CPPFunctionType::F_move_constructor |
CPPFunctionType::F_copy_constructor)) {
// User-provided destructors and copy/move constructors are not trivial.
// User-provided destructors and copy/move constructors are not
// trivial unless they are defaulted (and not virtual).
return false;
}
@ -223,6 +229,193 @@ is_trivial() const {
return is_default_constructible;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPStructType::
is_default_constructible() const {
return is_default_constructible(V_public);
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPStructType::
is_copy_constructible() const {
return is_copy_constructible(V_public);
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::is_default_constructible
// Access: Public
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPStructType::
is_default_constructible(CPPVisibility min_vis) const {
CPPInstance *constructor = get_default_constructor();
if (constructor != (CPPInstance *)NULL) {
// It has a default constructor.
if (constructor->_vis > min_vis) {
// Inaccessible default constructor.
return false;
}
if (constructor->_storage_class & CPPInstance::SC_deleted) {
// Deleted default constructor.
return false;
}
return true;
}
// Does it have constructors at all? If so, no implicit one is generated.
if (get_constructor() != (CPPFunctionGroup *)NULL) {
return false;
}
// Implicit default constructor. Check if the implicit default
// constructor is deleted.
Derivation::const_iterator di;
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
CPPStructType *base = (*di)._base->as_struct_type();
if (base != NULL) {
if (!base->is_default_constructible(V_protected)) {
return false;
}
}
}
// Make sure all members are default-constructible or have default values.
CPPScope::Variables::const_iterator vi;
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
CPPInstance *instance = (*vi).second;
assert(instance != NULL);
if (instance->_storage_class & CPPInstance::SC_static) {
// Static members don't count.
continue;
}
if (instance->_initializer != (CPPExpression *)NULL) {
// It has a default value.
continue;
}
if (!instance->_type->is_default_constructible()) {
return false;
}
}
// Check that we don't have pure virtual methods.
CPPScope::Functions::const_iterator fi;
for (fi = _scope->_functions.begin();
fi != _scope->_functions.end();
++fi) {
CPPFunctionGroup *fgroup = (*fi).second;
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
// Here's a pure virtual function.
return false;
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::is_copy_constructible
// Access: Public
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPStructType::
is_copy_constructible(CPPVisibility min_vis) const {
CPPInstance *constructor = get_copy_constructor();
if (constructor != (CPPInstance *)NULL) {
// It has a copy constructor.
if (constructor->_vis > min_vis) {
// Inaccessible copy constructor.
return false;
}
if (constructor->_storage_class & CPPInstance::SC_deleted) {
// Deleted copy constructor.
return false;
}
return true;
}
CPPInstance *destructor = get_destructor();
if (destructor != (CPPInstance *)NULL) {
if (destructor->_vis > min_vis) {
// Inaccessible destructor.
return false;
}
if (destructor->_storage_class & CPPInstance::SC_deleted) {
// Deleted destructor.
return false;
}
}
// Implicit copy constructor. Check if the implicit copy
// constructor is deleted.
Derivation::const_iterator di;
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
CPPStructType *base = (*di)._base->as_struct_type();
if (base != NULL) {
if (!base->is_copy_constructible(V_protected)) {
return false;
}
}
}
// Make sure all members are copy-constructible.
CPPScope::Variables::const_iterator vi;
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
CPPInstance *instance = (*vi).second;
assert(instance != NULL);
if (instance->_storage_class & CPPInstance::SC_static) {
// Static members don't count.
continue;
}
if (!instance->_type->is_copy_constructible()) {
return false;
}
}
// Check that we don't have pure virtual methods.
CPPScope::Functions::const_iterator fi;
for (fi = _scope->_functions.begin();
fi != _scope->_functions.end();
++fi) {
CPPFunctionGroup *fgroup = (*fi).second;
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
// Here's a pure virtual function.
return false;
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::check_virtual
// Access: Public
@ -244,7 +437,7 @@ is_trivial() const {
// virtual function pointer), or false otherwise.
////////////////////////////////////////////////////////////////////
bool CPPStructType::
check_virtual() {
check_virtual() const {
VFunctions funcs;
get_virtual_funcs(funcs);
return !funcs.empty();
@ -285,9 +478,7 @@ is_incomplete() const {
////////////////////////////////////////////////////////////////////
CPPFunctionGroup *CPPStructType::
get_constructor() const {
// Iterate through all the functions that begin with '~' until we
// find one that claims to be a destructor. In theory, there should
// only be one such function.
// Just look for the function with the same name as the class.
CPPScope::Functions::const_iterator fi;
fi = _scope->_functions.find(get_simple_name());
if (fi != _scope->_functions.end()) {
@ -297,6 +488,101 @@ get_constructor() const {
}
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::get_default_constructor
// Access: Public
// Description: Returns the default constructor defined for the
// struct type, or NULL if there is none.
////////////////////////////////////////////////////////////////////
CPPInstance *CPPStructType::
get_default_constructor() const {
CPPFunctionGroup *fgroup = get_constructor();
if (fgroup == (CPPFunctionGroup *)NULL) {
return (CPPInstance *)NULL;
}
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
assert(inst->_type != (CPPType *)NULL);
CPPFunctionType *ftype = inst->_type->as_function_type();
assert(ftype != (CPPFunctionType *)NULL);
if (ftype->_parameters->_parameters.size() == 0 ||
ftype->_parameters->_parameters.front()->_initializer != NULL) {
// It takes 0 parameters (or all parameters have default values).
return inst;
}
}
return (CPPInstance *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::get_copy_constructor
// Access: Public
// Description: Returns the copy constructor defined for the struct
// type, or NULL if no copy constructor exists.
////////////////////////////////////////////////////////////////////
CPPInstance *CPPStructType::
get_copy_constructor() const {
CPPFunctionGroup *fgroup = get_constructor();
if (fgroup == (CPPFunctionGroup *)NULL) {
return (CPPInstance *)NULL;
}
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
assert(inst->_type != (CPPType *)NULL);
CPPFunctionType *ftype = inst->_type->as_function_type();
assert(ftype != (CPPFunctionType *)NULL);
if ((ftype->_flags & CPPFunctionType::F_copy_constructor) != 0) {
return inst;
}
}
return (CPPInstance *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::get_move_constructor
// Access: Public
// Description: Returns the move constructor defined for the struct
// type, or NULL if no move constructor exists.
////////////////////////////////////////////////////////////////////
CPPInstance *CPPStructType::
get_move_constructor() const {
CPPFunctionGroup *fgroup = get_constructor();
if (fgroup == (CPPFunctionGroup *)NULL) {
return (CPPInstance *)NULL;
}
CPPFunctionGroup::Instances::const_iterator ii;
for (ii = fgroup->_instances.begin();
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
assert(inst->_type != (CPPType *)NULL);
CPPFunctionType *ftype = inst->_type->as_function_type();
assert(ftype != (CPPFunctionType *)NULL);
if ((ftype->_flags & CPPFunctionType::F_move_constructor) != 0) {
return inst;
}
}
return (CPPInstance *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CPPStructType::get_destructor
// Access: Public
@ -584,7 +870,10 @@ get_virtual_funcs(VFunctions &funcs) const {
CPPFunctionType *base_ftype = inst->_type->as_function_type();
assert(base_ftype != (CPPFunctionType *)NULL);
if ((base_ftype->_flags & CPPFunctionType::F_destructor) != 0) {
if (inst->_storage_class & CPPInstance::SC_deleted) {
// Ignore deleted functions.
} else if ((base_ftype->_flags & CPPFunctionType::F_destructor) != 0) {
// Match destructor-for-destructor; don't try to match
// destructors up by name.
CPPInstance *destructor = get_destructor();
@ -646,7 +935,8 @@ get_virtual_funcs(VFunctions &funcs) const {
ii != fgroup->_instances.end();
++ii) {
CPPInstance *inst = (*ii);
if ((inst->_storage_class & CPPInstance::SC_virtual) != 0) {
if ((inst->_storage_class & CPPInstance::SC_virtual) != 0 &&
(inst->_storage_class & CPPInstance::SC_deleted) == 0) {
// Here's a virtual function.
funcs.push_back(inst);
}

View File

@ -46,12 +46,19 @@ public:
CPPScope *get_scope() const;
bool is_abstract() const;
bool check_virtual();
bool check_virtual() const;
virtual bool is_fully_specified() const;
virtual bool is_incomplete() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
bool is_default_constructible(CPPVisibility min_vis) const;
bool is_copy_constructible(CPPVisibility min_vis) const;
CPPFunctionGroup *get_constructor() const;
CPPInstance *get_default_constructor() const;
CPPInstance *get_copy_constructor() const;
CPPInstance *get_move_constructor() const;
CPPInstance *get_destructor() const;
virtual CPPDeclaration *

View File

@ -79,6 +79,26 @@ is_trivial() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPType::
is_default_constructible() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPType::
is_copy_constructible() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CPPType::is_parameter_expr
// Access: Public, Virtual

View File

@ -49,6 +49,8 @@ public:
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_parameter_expr() const;
bool has_typedef_name() const;

View File

@ -189,6 +189,26 @@ is_trivial() const {
return _type->is_trivial();
}
////////////////////////////////////////////////////////////////////
// Function: CPPTypedefType::is_default_constructible
// Access: Public, Virtual
// Description: Returns true if the type is default-constructible.
////////////////////////////////////////////////////////////////////
bool CPPTypedefType::
is_default_constructible() const {
return _type->is_default_constructible();
}
////////////////////////////////////////////////////////////////////
// Function: CPPTypedefType::is_copy_constructible
// Access: Public, Virtual
// Description: Returns true if the type is copy-constructible.
////////////////////////////////////////////////////////////////////
bool CPPTypedefType::
is_copy_constructible() const {
return _type->is_copy_constructible();
}
////////////////////////////////////////////////////////////////////
// Function: CPPTypedefType::is_fully_specified
// Access: Public, Virtual

View File

@ -43,6 +43,8 @@ public:
virtual bool is_incomplete() const;
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_fully_specified() const;

View File

@ -39,6 +39,7 @@ using namespace std;
#define FINAL
#define OVERRIDE
#define MOVE(x) x
#define DEFAULT_CTOR = default
#define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
@ -136,59 +137,83 @@ typedef ios::seekdir ios_seekdir;
#if defined(__has_extension) // Clang magic.
# if __has_extension(cxx_constexpr)
# define CONSTEXPR constexpr
# else
# define CONSTEXPR INLINE
# endif
# if __has_extension(cxx_noexcept)
# define NOEXCEPT noexcept
# else
# define NOEXCEPT
# endif
# if __has_extension(cxx_rvalue_references) && (__cplusplus >= 201103L)
# define USE_MOVE_SEMANTICS
# define MOVE(x) move(x)
# else
# define MOVE(x) x
# endif
# if __has_extension(cxx_override_control) && (__cplusplus >= 201103L)
# define FINAL final
# define OVERRIDE override
# else
# define FINAL
# define OVERRIDE
# endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && (__cplusplus >= 201103L)
// noexcept was introduced in GCC 4.6, constexpr in GCC 4.7, rvalue refs in
// GCC 4.3. However, GCC only started defining __cplusplus properly in 4.7.
# if __has_extension(cxx_defaulted_functions)
# define DEFAULT_CTOR = default
# endif
#elif defined(__GNUC__) && (__cplusplus >= 201103L) // GCC
// GCC defines several macros which we can query.
// List of all supported builtin macros: https://gcc.gnu.org/projects/cxx0x.html
# if __cpp_constexpr >= 200704
# define CONSTEXPR constexpr
# endif
// Starting at GCC 4.4
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
# define DEFAULT_CTOR = default
# endif
// Starting at GCC 4.6
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# define NOEXCEPT noexcept
# define USE_MOVE_SEMANTICS
# define FINAL final
# define MOVE(x) move(x)
# endif
// Starting at GCC 4.7
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
# define OVERRIDE override
# endif
#elif defined(_MSC_VER) && _MSC_VER >= 1900 // Visual Studio 2015
# define CONSTEXPR constexpr
# define NOEXCEPT noexcept
# define USE_MOVE_SEMANTICS
# define FINAL final
# define OVERRIDE override
# define MOVE(x) move(x)
#elif defined(_MSC_VER) && _MSC_VER >= 1900
// MSVC 2015 supports all of this goodness.
# define CONSTEXPR constexpr
# define NOEXCEPT noexcept
# define USE_MOVE_SEMANTICS
# define FINAL final
# define OVERRIDE override
# define MOVE(x) move(x)
#elif defined(_MSC_VER) && _MSC_VER >= 1600
// MSVC 2010 has move semantics. Not much else.
# define CONSTEXPR INLINE
# define DEFAULT_CTOR = default
#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Visual Studio 2010
# define NOEXCEPT throw()
# define OVERRIDE override
# define USE_MOVE_SEMANTICS
# define FINAL
# define OVERRIDE
# define FINAL sealed
# define MOVE(x) move(x)
#else
#endif
// Fallbacks if features are not supported
#ifndef CONSTEXPR
# define CONSTEXPR INLINE
#endif
#ifndef NOEXCEPT
# define NOEXCEPT
# define FINAL
# define OVERRIDE
#endif
#ifndef MOVE
# define MOVE(x) x
#endif
#ifndef FINAL
# define FINAL
#endif
#ifndef OVERRIDE
# define OVERRIDE
#endif
#ifndef DEFAULT_CTOR
# define DEFAULT_CTOR {}
#endif
#if !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
// This macro must be used to export an instantiated template class

View File

@ -1306,6 +1306,74 @@ static const UnicodeLatinMap::Entry latin_map[] = {
static const size_t latin_map_length = sizeof(latin_map) / sizeof(UnicodeLatinMap::Entry);
#endif
static const wchar_t combining_accent_map[] = {
0x0000, // none
0x0301, // acute
0x0000, // acute_and_dot_above
0x0306, // breve
0x0000, // breve_and_acute
0x0000, // breve_and_dot_below
0x0000, // breve_and_grave
0x0000, // breve_and_hook_above
0x0000, // breve_and_tilde
0x032e, // breve_below
0x030c, // caron
0x0000, // caron_and_dot_above
0x0327, // cedilla
0x0000, // cedilla_and_acute
0x0000, // cedilla_and_breve
0x0302, // circumflex
0x0000, // circumflex_and_acute
0x0000, // circumflex_and_dot_below
0x0000, // circumflex_and_grave
0x0000, // circumflex_and_hook_above
0x0000, // circumflex_and_tilde
0x032d, // circumflex_below
0x0326, // comma_below
0x0000, // curl
0x0308, // diaeresis
0x0000, // diaeresis_and_acute
0x0000, // diaeresis_and_caron
0x0000, // diaeresis_and_grave
0x0000, // diaeresis_and_macron
0x0324, // diaeresis_below
0x0307, // dot_above
0x0000, // dot_above_and_macron
0x0323, // dot_below
0x0000, // dot_below_and_dot_above
0x0000, // dot_below_and_macron
0x030b, // double_acute
0x030f, // double_grave
0x0300, // grave
0x0328, // hook
0x0309, // hook_above
0x031b, // horn
0x0000, // horn_and_acute
0x0000, // horn_and_dot_below
0x0000, // horn_and_grave
0x0000, // horn_and_hook_above
0x0000, // horn_and_tilde
0x0311, // inverted_breve
0x0000, // line_below
0x0304, // macron
0x0000, // macron_and_acute
0x0000, // macron_and_diaeresis
0x0000, // macron_and_grave
0x0328, // ogonek
0x0000, // ogonek_and_macron
0x030a, // ring_above
0x0000, // ring_above_and_acute
0x0325, // ring_below
0x0000, // stroke
0x0000, // stroke_and_acute
0x0000, // stroke_and_hook
0x0303, // tilde
0x0000, // tilde_and_acute
0x0000, // tilde_and_diaeresis
0x0000, // tilde_and_macron
0x0330, // tilde_below
0x0000, // topbar
};
////////////////////////////////////////////////////////////////////
// Function: UnicodeLatinMap::look_up
@ -1332,6 +1400,18 @@ look_up(wchar_t character) {
}
}
////////////////////////////////////////////////////////////////////
// Function: UnicodeLatinMap::get_combining_accent
// Access: Public, Static
// Description: Returns the unicode code point for the combining
// character corresponding with the given accent type,
// or 0 if none is recorded.
////////////////////////////////////////////////////////////////////
wchar_t UnicodeLatinMap::
get_combining_accent(AccentType accent) {
return combining_accent_map[(size_t)accent];
}
////////////////////////////////////////////////////////////////////
// Function: UnicodeLatinMap::init
// Access: Private, Static

View File

@ -129,6 +129,8 @@ public:
static const Entry *look_up(wchar_t character);
static wchar_t get_combining_accent(AccentType accent);
private:
static void init();
static bool _initialized;

View File

@ -5925,6 +5925,10 @@ write_function_instance(ostream &out, FunctionRemap *remap,
indent(out, indent_level)
<< "return DTool_PyInit_Finalize(self, (void *)" << return_expr << ", &" << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", true, false);\n";
} else if (TypeManager::is_bool(orig_type)) {
// It's an error return boolean, I guess. Return 0 on success.
indent(out, indent_level) << "return (" << return_expr << ") ? 0 : -1;\n";
} else if (TypeManager::is_integer(orig_type)) {
if ((return_flags & RF_compare) == RF_compare) {
// Make sure it returns -1, 0, or 1, or Python complains with:

View File

@ -1134,8 +1134,8 @@ scan_function(CPPInstance *function) {
return;
}
if ((function->_storage_class & CPPInstance::SC_static) != 0) {
// The function is static, so can't be exported.
if ((function->_storage_class & (CPPInstance::SC_static | CPPInstance::SC_deleted)) != 0) {
// The function is static or deleted, so can't be exported.
return;
}
@ -2684,6 +2684,52 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
}
}
// See if we need to generate an implicit default constructor.
CPPFunctionGroup *constructor = cpptype->get_constructor();
if (constructor == (CPPFunctionGroup *)NULL && cpptype->is_default_constructible()) {
// Make a default constructor.
CPPType *void_type = TypeManager::get_void_type();
CPPParameterList *params = new CPPParameterList;
CPPFunctionType *ftype = new CPPFunctionType(void_type, params, CPPFunctionType::F_constructor);
// Now make up an instance for the default constructor.
CPPInstance *function = new CPPInstance(ftype, cpptype->get_simple_name());
function->_storage_class |= CPPInstance::SC_inline | CPPInstance::SC_defaulted;
function->_vis = V_published;
FunctionIndex index = get_function(function, "", cpptype, cpptype->get_scope(), 0);
if (find(itype._constructors.begin(), itype._constructors.end(),
index) == itype._constructors.end()) {
itype._constructors.push_back(index);
}
}
// See if we need to generate an implicit copy constructor.
CPPInstance *copy_constructor = cpptype->get_copy_constructor();
if (copy_constructor == (CPPInstance *)NULL &&
cpptype->is_copy_constructible()) {
// Make an implicit copy constructor.
CPPType *const_ref_type = TypeManager::wrap_const_reference(cpptype);
CPPInstance *param = new CPPInstance(const_ref_type, NULL);
CPPType *void_type = TypeManager::get_void_type();
CPPParameterList *params = new CPPParameterList;
params->_parameters.push_back(param);
const int flags = CPPFunctionType::F_constructor | CPPFunctionType::F_copy_constructor;
CPPFunctionType *ftype = new CPPFunctionType(void_type, params, flags);
// Now make up an instance for the copy constructor.
CPPInstance *function = new CPPInstance(ftype, cpptype->get_simple_name());
function->_storage_class |= CPPInstance::SC_inline | CPPInstance::SC_defaulted;
function->_vis = V_published;
FunctionIndex index = get_function(function, "", cpptype, cpptype->get_scope(), 0);
if (find(itype._constructors.begin(), itype._constructors.end(),
index) == itype._constructors.end()) {
itype._constructors.push_back(index);
}
}
if ((itype._flags & InterrogateType::F_inherited_destructor) != 0) {
// If we have inherited our virtual destructor from our base
// class, go ahead and assign the same function index.
@ -2821,6 +2867,11 @@ define_method(CPPInstance *function, InterrogateType &itype,
return;
}
if (function->_storage_class & CPPInstance::SC_deleted) {
// It was explicitly marked as deleted.
return;
}
// As a special kludgey extension, we consider a public static
// method called "get_class_type()" to be marked published, even if
// it is not. This allows us to export all of the TypeHandle system

View File

@ -1,4 +1,5 @@
namespace Eigen {
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Matrix;
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Matrix {
};
};

View File

@ -59,6 +59,8 @@ __published:
protected:
// Force this to be a non-trivial type.
ios_base() {};
private:
ios_base(const ios_base &);
};
class ios : public ios_base {
__published:
@ -69,6 +71,9 @@ __published:
bool fail() const;
bool bad() const;
void clear();
protected:
ios();
};
// We actually want to wrap streampos as streamoff.
@ -76,6 +81,8 @@ __published:
class ostream : virtual public ios {
__published:
ostream(const ostream&) = delete;
void put(char c);
void flush();
streampos tellp();
@ -84,6 +91,8 @@ __published:
};
class istream : virtual public ios {
__published:
istream(const istream&) = delete;
int get();
streampos tellg();
void seekg(streampos pos);
@ -91,6 +100,8 @@ __published:
};
class iostream : public istream, public ostream {
__published:
iostream(const iostream&) = delete;
void flush();
};

View File

@ -644,7 +644,7 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
// CollisionBox
else if (CollisionBox::get_class_type() == type) {
CPT(CollisionBox) box = DCAST(CollisionBox, solid);
CPT(TransformState) ts = TransformState::make_pos(box->get_approx_center());
CPT(TransformState) ts = TransformState::make_pos(box->get_center());
add_shape(BulletBoxShape::make_from_solid(box), ts);
}

View File

@ -130,6 +130,26 @@ get_center() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_min
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LPoint3 &CollisionBox::
get_min() const {
return _min;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_max
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LPoint3 &CollisionBox::
get_max() const {
return _max;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_dimensions
// Access: Published
@ -140,22 +160,12 @@ get_dimensions() const {
return _max - _min;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_radius
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat CollisionBox::
get_radius() const {
return _radius;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_num_points
// Access: Published
// Description: Returns 8: the number of vertices of a rectangular solid.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL int CollisionBox::
INLINE int CollisionBox::
get_num_points() const {
return 8;
}
@ -165,7 +175,7 @@ get_num_points() const {
// Access: Published
// Description: Returns the nth vertex of the OBB.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL LPoint3 CollisionBox::
INLINE LPoint3 CollisionBox::
get_point(int n) const {
nassertr(n >= 0 && n < 8, LPoint3::zero());
return _vertex[n];
@ -177,7 +187,7 @@ get_point(int n) const {
// Access: Published
// Description: Returns the nth vertex of the Axis Aligned Bounding Box.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL LPoint3 CollisionBox::
INLINE LPoint3 CollisionBox::
get_point_aabb(int n) const {
nassertr(n >= 0 && n < 8, LPoint3::zero());
@ -192,7 +202,7 @@ get_point_aabb(int n) const {
// Access: Published
// Description: Returns 6: the number of faces of a rectangular solid.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL int CollisionBox::
INLINE int CollisionBox::
get_num_planes() const {
return 6;
}
@ -202,7 +212,7 @@ get_num_planes() const {
// Access: Published
// Description: Returns the nth face of the rectangular solid.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL LPlane CollisionBox::
INLINE LPlane CollisionBox::
get_plane(int n) const {
nassertr(n >= 0 && n < 6, LPlane());
return _planes[n];
@ -213,7 +223,7 @@ get_plane(int n) const {
// Access: Published
// Description: Creates the nth face of the rectangular solid.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL LPlane CollisionBox::
INLINE LPlane CollisionBox::
set_plane(int n) const {
nassertr(n >= 0 && n < 6, LPlane());
return LPlane(get_point(plane_def[n][0]),

View File

@ -175,36 +175,6 @@ get_collision_origin() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_min
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LPoint3 CollisionBox::
get_min() const {
return _min;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_max
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LPoint3 CollisionBox::
get_max() const {
return _max;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_approx_center
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LPoint3 CollisionBox::
get_approx_center() const {
return (_min + _max) * 0.5f;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionBox::get_volume_pcollector
// Access: Public, Virtual
@ -442,9 +412,14 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
into_depth = max_dist - orig_dist;
}
// Clamp the surface point to the box bounds.
LPoint3 surface = from_center - normal * dist;
surface = surface.fmax(_min);
surface = surface.fmin(_max);
new_entry->set_surface_normal(normal);
new_entry->set_surface_point(from_center - normal * dist);
new_entry->set_interior_point(from_center - normal * (dist + into_depth));
new_entry->set_surface_point(surface);
new_entry->set_interior_point(surface - normal * into_depth);
new_entry->set_contact_pos(contact_point);
new_entry->set_contact_normal(plane.get_normal());
new_entry->set_t(actual_t);
@ -655,56 +630,83 @@ test_intersection_from_box(const CollisionEntry &entry) const {
box_z /= l;
PN_stdfloat r1, r2;
PN_stdfloat min_pen = 0;
PN_stdfloat pen;
int axis = 0;
// SAT test for the three axes of the into cube.
r1 = into_extents[0];
r2 = cabs(box_x[0] * from_extents[0]) +
cabs(box_y[0] * from_extents[1]) +
cabs(box_z[0] * from_extents[2]);
if (cabs(diff[0]) > r1 + r2) {
pen = r1 + r2 - cabs(diff[0]);
if (pen < 0) {
return NULL;
}
min_pen = pen;
r1 = into_extents[1];
r2 = cabs(box_x[1] * from_extents[0]) +
cabs(box_y[1] * from_extents[1]) +
cabs(box_z[1] * from_extents[2]);
if (cabs(diff[1]) > r1 + r2) {
pen = r1 + r2 - cabs(diff[1]);
if (pen < 0) {
return NULL;
}
if (pen < min_pen) {
min_pen = pen;
axis = 1;
}
r1 = into_extents[2];
r2 = cabs(box_x[2] * from_extents[0]) +
cabs(box_y[2] * from_extents[1]) +
cabs(box_z[2] * from_extents[2]);
if (cabs(diff[2]) > r1 + r2) {
pen = r1 + r2 - cabs(diff[2]);
if (pen < 0) {
return NULL;
}
if (pen < min_pen) {
min_pen = pen;
axis = 2;
}
// SAT test for the three axes of the from cube.
r1 = cabs(box_x[0] * into_extents[0]) +
cabs(box_x[1] * into_extents[1]) +
cabs(box_x[2] * into_extents[2]);
r2 = from_extents[0];
if (cabs(diff.dot(box_x)) > r1 + r2) {
pen = r1 + r2 - cabs(diff.dot(box_x));
if (pen < 0) {
return NULL;
}
if (pen < min_pen) {
min_pen = pen;
}
r1 = cabs(box_y[0] * into_extents[0]) +
cabs(box_y[1] * into_extents[1]) +
cabs(box_y[2] * into_extents[2]);
r2 = from_extents[1];
if (cabs(diff.dot(box_y)) > r1 + r2) {
pen = r1 + r2 - cabs(diff.dot(box_y));
if (pen < 0) {
return NULL;
}
if (pen < min_pen) {
min_pen = pen;
}
r1 = cabs(box_z[0] * into_extents[0]) +
cabs(box_z[1] * into_extents[1]) +
cabs(box_z[2] * into_extents[2]);
r2 = from_extents[2];
if (cabs(diff.dot(box_z)) > r1 + r2) {
pen = r1 + r2 - cabs(diff.dot(box_z));
if (pen < 0) {
return NULL;
}
if (pen < min_pen) {
min_pen = pen;
}
// SAT test of the nine cross products.
r1 = into_extents[1] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[1]);
@ -768,8 +770,29 @@ test_intersection_from_box(const CollisionEntry &entry) const {
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
// This isn't always the correct surface point. However, it seems to
// be enough to let the pusher do the right thing.
LPoint3 surface(
min(max(diff[0], -into_extents[0]), into_extents[0]),
min(max(diff[1], -into_extents[1]), into_extents[1]),
min(max(diff[2], -into_extents[2]), into_extents[2]));
// Create the normal along the axis of least penetration.
LVector3 normal(0);
PN_stdfloat diff_axis = diff[axis];
int sign = (diff_axis >= 0) ? 1 : -1;
normal[axis] = sign;
surface[axis] = into_extents[axis] * sign;
new_entry->set_surface_point(surface + _center);
// Does not generate the correct depth. Needs fixing.
new_entry->set_interior_point(surface + _center + normal * -min_pen);
if (has_effective_normal() && box->get_respect_effective_normal()) {
new_entry->set_surface_normal(get_effective_normal());
} else {
new_entry->set_surface_normal(normal);
}
return new_entry;

View File

@ -50,26 +50,29 @@ public:
virtual PStatCollector &get_test_pcollector();
virtual void output(ostream &out) const;
virtual LPoint3 get_approx_center() const;
virtual LPoint3 get_min() const;
virtual LPoint3 get_max() const;
INLINE static void flush_level();
void setup_box();
PUBLISHED:
INLINE_MATHUTIL int get_num_points() const;
INLINE_MATHUTIL LPoint3 get_point_aabb(int n) const;
INLINE_MATHUTIL LPoint3 get_point(int n) const;
INLINE_MATHUTIL int get_num_planes() const;
INLINE_MATHUTIL LPlane set_plane(int n) const;
INLINE_MATHUTIL LPlane get_plane(int n) const;
INLINE int get_num_points() const;
INLINE LPoint3 get_point_aabb(int n) const;
INLINE LPoint3 get_point(int n) const;
INLINE int get_num_planes() const;
INLINE LPlane set_plane(int n) const;
INLINE LPlane get_plane(int n) const;
INLINE void set_center(const LPoint3 &center);
INLINE void set_center(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
INLINE const LPoint3 &get_center() const;
INLINE const LPoint3 &get_min() const;
INLINE const LPoint3 &get_max() const;
INLINE LVector3 get_dimensions() const;
INLINE PN_stdfloat get_radius() const;
PUBLISHED:
MAKE_PROPERTY(center, get_center);
MAKE_PROPERTY(min, get_min);
MAKE_PROPERTY(max, get_max);
MAKE_PROPERTY(dimensions, get_dimensions);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -97,6 +97,17 @@ PUBLISHED:
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
PUBLISHED:
MAKE_PROPERTY(from, get_from);
MAKE_PROPERTY(into, get_into);
MAKE_PROPERTY(from_node, get_from_node);
MAKE_PROPERTY(into_node, get_into_node);
MAKE_PROPERTY(from_node_path, get_from_node_path);
MAKE_PROPERTY(into_node_path, get_into_node_path);
MAKE_PROPERTY(t, get_t, set_t);
MAKE_PROPERTY(respect_prev_transform, get_respect_prev_transform);
public:
INLINE CPT(TransformState) get_wrt_space() const;
INLINE CPT(TransformState) get_inv_wrt_space() const;

View File

@ -42,6 +42,11 @@ PUBLISHED:
INLINE void set_max_velocity(PN_stdfloat max_vel);
INLINE PN_stdfloat get_max_velocity() const;
PUBLISHED:
MAKE_PROPERTY(offset, get_offset, set_offset);
MAKE_PROPERTY(reach, get_reach, set_reach);
MAKE_PROPERTY(max_velocity, get_max_velocity, set_max_velocity);
protected:
PN_stdfloat set_highest_collision(const NodePath &target_node_path, const NodePath &from_node_path, const Entries &entries);
virtual bool handle_entries();

View File

@ -57,6 +57,17 @@ PUBLISHED:
INLINE void set_legacy_mode(bool legacy_mode);
INLINE bool get_legacy_mode() const;
PUBLISHED:
MAKE_PROPERTY(offset, get_offset, set_offset);
MAKE_PROPERTY(reach, get_reach, set_reach);
MAKE_PROPERTY(airborne_height, get_airborne_height);
MAKE_PROPERTY(on_ground, is_on_ground);
MAKE_PROPERTY(impact_velocity, get_impact_velocity);
MAKE_PROPERTY(contact_normal, get_contact_normal);
MAKE_PROPERTY(velocity, get_velocity, set_velocity);
MAKE_PROPERTY(gravity, get_gravity, set_gravity);
MAKE_PROPERTY(max_velocity, get_max_velocity, set_max_velocity);
protected:
PN_stdfloat set_highest_collision(const NodePath &target_node_path, const NodePath &from_node_path, const Entries &entries);
virtual bool handle_entries();

View File

@ -54,6 +54,9 @@ PUBLISHED:
INLINE bool has_center() const;
INLINE bool has_contact() const;
PUBLISHED:
MAKE_PROPERTY2(center, has_center, get_center, set_center, clear_center);
protected:
bool _has_contact; // Are we in contact with anything?

View File

@ -34,6 +34,9 @@ PUBLISHED:
INLINE void set_horizontal(bool flag);
INLINE bool get_horizontal() const;
PUBLISHED:
MAKE_PROPERTY(horizontal, get_horizontal, set_horizontal);
protected:
virtual bool handle_entries();
virtual void apply_net_shove(

View File

@ -63,6 +63,11 @@ PUBLISHED:
INLINE void set_t2(PN_stdfloat t2);
INLINE PN_stdfloat get_t2() const;
PUBLISHED:
MAKE_PROPERTY(parabola, get_parabola, set_parabola);
MAKE_PROPERTY(t1, get_t1, set_t1);
MAKE_PROPERTY(t2, get_t2, set_t2);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -57,6 +57,10 @@ PUBLISHED:
INLINE void flip();
PUBLISHED:
MAKE_PROPERTY(normal, get_normal);
MAKE_PROPERTY(plane, get_plane, set_plane);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -61,6 +61,10 @@ PUBLISHED:
bool is_valid() const;
bool is_concave() const;
PUBLISHED:
MAKE_PROPERTY(valid, is_valid);
MAKE_PROPERTY(concave, is_concave);
public:
virtual void xform(const LMatrix4 &mat);

View File

@ -64,6 +64,10 @@ PUBLISHED:
bool set_from_lens(LensNode *camera, const LPoint2 &point);
INLINE bool set_from_lens(LensNode *camera, PN_stdfloat px, PN_stdfloat py);
PUBLISHED:
MAKE_PROPERTY(point_a, get_point_a, set_point_a);
MAKE_PROPERTY(point_b, get_point_b, set_point_b);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -298,100 +298,50 @@ test_intersection_from_box(const CollisionEntry &entry) const {
const CollisionBox *box;
DCAST_INTO_R(box, entry.get_from(), 0);
CPT(TransformState) wrt_space = entry.get_wrt_space();
CPT(TransformState) wrt_prev_space = entry.get_wrt_prev_space();
// Instead of transforming the box into the sphere's coordinate space,
// we do it the other way around. It's easier that way.
const LMatrix4 &wrt_mat = entry.get_inv_wrt_mat();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 center = wrt_mat.xform_point(_center);
PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared();
CollisionBox local_b( *box );
local_b.xform( wrt_mat );
LPoint3 box_min = box->get_min();
LPoint3 box_max = box->get_max();
LPoint3 from_center = local_b.get_center();
// Arvo's algorithm.
PN_stdfloat d = 0;
PN_stdfloat s;
LPoint3 orig_center = get_center();
LPoint3 to_center = orig_center;
LPoint3 contact_point(from_center);
PN_stdfloat actual_t = 1.0f;
if (center[0] < box_min[0]) {
s = center[0] - box_min[0];
d += s * s;
PN_stdfloat to_radius = get_radius();
PN_stdfloat to_radius_2 = to_radius * to_radius;
int ip;
PN_stdfloat max_dist = 0.0f;
PN_stdfloat dist = 0.0f; // initial assignment to squelch silly compiler warning
bool intersect;
LPlane plane;
LVector3 normal;
for (ip = 0, intersect=false; ip < 6 && !intersect; ip++) {
plane = local_b.get_plane( ip );
if (local_b.get_plane_points(ip).size() < 3) {
continue;
}
normal = (has_effective_normal() && box->get_respect_effective_normal()) ? get_effective_normal() : plane.get_normal();
#ifndef NDEBUG
/*
if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001), NULL) {
collide_cat.info()
<< "polygon being collided with " << entry.get_into_node_path()
<< " has normal " << normal << " of length " << normal.length()
<< "\n";
normal.normalize();
}
*/
#endif
// The nearest point within the plane to our center is the
// intersection of the line (center, center - normal) with the plane.
if (!plane.intersects_line(dist, to_center, -(plane.get_normal()))) {
// No intersection with plane? This means the plane's effective
// normal was within the plane itself. A useless polygon.
continue;
}
if (dist > to_radius || dist < -to_radius) {
// No intersection with the plane.
continue;
}
LPoint2 p = local_b.to_2d(to_center - dist * plane.get_normal(), ip);
PN_stdfloat edge_dist = 0.0f;
edge_dist = local_b.dist_to_polygon(p, local_b.get_plane_points(ip));
if(edge_dist < 0) {
intersect = true;
continue;
}
if((edge_dist > 0) &&
((edge_dist * edge_dist + dist * dist) > to_radius_2)) {
// No intersection; the circle is outside the polygon.
continue;
}
// The sphere appears to intersect the polygon. If the edge is less
// than to_radius away, the sphere may be resting on an edge of
// the polygon. Determine how far the center of the sphere must
// remain from the plane, based on its distance from the nearest
// edge.
max_dist = to_radius;
if (edge_dist >= 0.0f) {
PN_stdfloat max_dist_2 = max(to_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
max_dist = csqrt(max_dist_2);
}
if (dist > max_dist) {
// There's no intersection: the sphere is hanging off the edge.
continue;
}
intersect = true;
} else if (center[0] > box_max[0]) {
s = center[0] - box_max[0];
d += s * s;
}
if( !intersect )
if (center[1] < box_min[1]) {
s = center[1] - box_min[1];
d += s * s;
} else if (center[1] > box_max[1]) {
s = center[1] - box_max[1];
d += s * s;
}
if (center[2] < box_min[2]) {
s = center[2] - box_min[2];
d += s * s;
} else if (center[2] > box_max[2]) {
s = center[2] - box_max[2];
d += s * s;
}
if (d > radius_sq) {
return NULL;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
@ -401,14 +351,17 @@ test_intersection_from_box(const CollisionEntry &entry) const {
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
PN_stdfloat into_depth = max_dist - dist;
// To get the interior point, clamp the sphere center to the AABB.
LPoint3 interior = entry.get_wrt_mat().xform_point(center.fmax(box_min).fmin(box_max));
new_entry->set_interior_point(interior);
new_entry->set_surface_normal(normal);
new_entry->set_surface_point(to_center - normal * dist);
new_entry->set_interior_point(to_center - normal * (dist + into_depth));
new_entry->set_contact_pos(contact_point);
new_entry->set_contact_normal(plane.get_normal());
new_entry->set_t(actual_t);
// Now extrapolate the surface point and normal from that.
LVector3 normal = interior - _center;
normal.normalize();
new_entry->set_surface_point(_center + normal * _radius);
new_entry->set_surface_normal(
(has_effective_normal() && box->get_respect_effective_normal())
? get_effective_normal() : normal);
return new_entry;
}

View File

@ -58,6 +58,10 @@ PUBLISHED:
INLINE void set_radius(PN_stdfloat radius);
INLINE PN_stdfloat get_radius() const;
PUBLISHED:
MAKE_PROPERTY(center, get_center, set_center);
MAKE_PROPERTY(radius, get_radius, set_radius);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -53,6 +53,8 @@ PUBLISHED:
INLINE void set_respect_prev_transform(bool flag);
INLINE bool get_respect_prev_transform() const;
MAKE_PROPERTY(respect_preV_transform, get_respect_prev_transform,
set_respect_prev_transform);
void add_collider(const NodePath &collider, CollisionHandler *handler);
bool remove_collider(const NodePath &collider);
@ -70,6 +72,8 @@ PUBLISHED:
INLINE bool has_recorder() const;
INLINE CollisionRecorder *get_recorder() const;
INLINE void clear_recorder();
MAKE_PROPERTY2(recorder, has_recorder, get_recorder,
set_recorder, clear_recorder);
CollisionVisualizer *show_collisions(const NodePath &root);
void hide_collisions();

View File

@ -65,6 +65,11 @@ PUBLISHED:
INLINE void set_radius(PN_stdfloat radius);
INLINE PN_stdfloat get_radius() const;
PUBLISHED:
MAKE_PROPERTY(point_a, get_point_a, set_point_a);
MAKE_PROPERTY(point_b, get_point_b, set_point_b);
MAKE_PROPERTY(radius, get_radius, set_radius);
protected:
virtual PT(BoundingVolume) compute_internal_bounds() const;

View File

@ -47,6 +47,10 @@ PUBLISHED:
void clear();
PUBLISHED:
MAKE_PROPERTY(point_scale, get_point_scale, set_point_scale);
MAKE_PROPERTY(normal_scale, get_normal_scale, set_normal_scale);
public:
// from parent class PandaNode.
virtual PandaNode *make_copy() const;

View File

@ -33,9 +33,13 @@ CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg,
////////////////////////////////////////////////////////////////////
INLINE CullBinStateSorted::ObjectData::
ObjectData(CullableObject *object) :
_object(object),
_format(object->_munged_data->get_format())
_object(object)
{
if (object->_munged_data == NULL) {
_format = NULL;
} else {
_format = object->_munged_data->get_format();
}
}
////////////////////////////////////////////////////////////////////

View File

@ -1067,6 +1067,18 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
spc[0],spc[1],spc[2],spc[3]);
return &t;
}
case Shader::SMO_attr_material2: {
const MaterialAttrib *target_material = (const MaterialAttrib *)
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
if (target_material->is_off()) {
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
return &t;
}
Material *m = target_material->get_material();
t.set_row(0, m->get_base_color());
t.set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness()));
return &t;
}
case Shader::SMO_attr_color: {
const ColorAttrib *target_color = (const ColorAttrib *)
_target_rs->get_attrib_def(ColorAttrib::get_class_slot());
@ -1483,6 +1495,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
const LMatrix4 *GraphicsStateGuardian::
fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) {
// This system is not ideal. It will be improved in the future.
static const CPT_InternalName IN_color("color");
static const CPT_InternalName IN_ambient("ambient");
static const CPT_InternalName IN_diffuse("diffuse");
static const CPT_InternalName IN_specular("specular");
@ -1498,7 +1511,15 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
if (attrib == IN_ambient) {
if (attrib == IN_color) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
LColor c = light->get_color();
c.componentwise_mult(_light_color_scale);
t.set_row(3, c);
return &t;
} else if (attrib == IN_ambient) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
if (np.node()->is_of_type(AmbientLight::get_class_type())) {

View File

@ -13,6 +13,53 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::set_base
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggMaterial::
set_base(const LColor &base) {
_base = base;
_flags |= F_base;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::clear_base
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggMaterial::
clear_base() {
_flags &= ~F_base;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::has_base
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggMaterial::
has_base() const {
return (_flags & F_base) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::get_base
// Access: Public
// Description: It is legal to call this even if has_base() returns
// false. If so, it simply returns the default base
// color.
////////////////////////////////////////////////////////////////////
INLINE LColor EggMaterial::
get_base() const {
if (has_base()) {
return _base;
} else {
return LColor(1.0, 1.0, 1.0, 1.0);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::set_diff
// Access: Public
@ -336,6 +383,51 @@ get_metallic() const {
}
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::set_ior
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggMaterial::
set_ior(double ior) {
_ior = ior;
_flags |= F_ior;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::clear_ior
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggMaterial::
clear_ior() {
_flags &= ~F_ior;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::has_ior
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggMaterial::
has_ior() const {
return (_flags & F_ior) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::get_ior
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE double EggMaterial::
get_ior() const {
if (has_ior()) {
return _ior;
} else {
return 1.0;
}
}
////////////////////////////////////////////////////////////////////
// Function: EggMaterial::set_local
// Access: Public

View File

@ -39,6 +39,7 @@ EggMaterial(const string &mref_name)
EggMaterial::
EggMaterial(const EggMaterial &copy)
: EggNode(copy),
_base(copy._base),
_diff(copy._diff),
_amb(copy._amb),
_emit(copy._emit),
@ -46,6 +47,7 @@ EggMaterial(const EggMaterial &copy)
_shininess(copy._shininess),
_roughness(copy._roughness),
_metallic(copy._metallic),
_ior(copy._ior),
_local(copy._local),
_flags(copy._flags)
{
@ -62,6 +64,19 @@ void EggMaterial::
write(ostream &out, int indent_level) const {
write_header(out, indent_level, "<Material>");
if (has_base()) {
indent(out, indent_level + 2)
<< "<Scalar> baser { " << get_base()[0] << " }\n";
indent(out, indent_level + 2)
<< "<Scalar> baseg { " << get_base()[1] << " }\n";
indent(out, indent_level + 2)
<< "<Scalar> baseb { " << get_base()[2] << " }\n";
if (get_base()[3] != 1.0) {
indent(out, indent_level + 2)
<< "<Scalar> basea { " << get_base()[3] << " }\n";
}
}
if (has_diff()) {
indent(out, indent_level + 2)
<< "<Scalar> diffr { " << get_diff()[0] << " }\n";
@ -129,6 +144,11 @@ write(ostream &out, int indent_level) const {
<< "<Scalar> metallic { " << get_metallic() << " }\n";
}
if (has_ior()) {
indent(out, indent_level + 2)
<< "<Scalar> ior { " << get_ior() << " }\n";
}
if (has_local()) {
indent(out, indent_level + 2)
<< "<Scalar> local { " << get_local() << " }\n";
@ -159,6 +179,7 @@ bool EggMaterial::
is_equivalent_to(const EggMaterial &other, int eq) const {
if (eq & E_attributes) {
if (_flags != other._flags ||
(has_base() && get_base() != other.get_base()) ||
(has_diff() && get_diff() != other.get_diff()) ||
(has_amb() && get_amb() != other.get_amb()) ||
(has_emit() && get_emit() != other.get_emit()) ||
@ -166,6 +187,7 @@ is_equivalent_to(const EggMaterial &other, int eq) const {
(has_shininess() && get_shininess() != other.get_shininess()) ||
(has_roughness() && get_roughness() != other.get_roughness()) ||
(has_metallic() && get_metallic() != other.get_metallic()) ||
(has_ior() && get_ior() != other.get_ior()) ||
(has_local() && get_local() != other.get_local())) {
return false;
}
@ -216,6 +238,9 @@ sorts_less_than(const EggMaterial &other, int eq) const {
if (has_metallic() && get_metallic() != other.get_metallic()) {
return get_metallic() < other.get_metallic();
}
if (has_ior() && get_ior() != other.get_ior()) {
return get_ior() < other.get_ior();
}
if (has_local() && get_local() != other.get_local()) {
return get_local() < other.get_local();
}

View File

@ -40,6 +40,11 @@ PUBLISHED:
bool is_equivalent_to(const EggMaterial &other, int eq) const;
bool sorts_less_than(const EggMaterial &other, int eq) const;
INLINE void set_base(const LColor &base);
INLINE void clear_base();
INLINE bool has_base() const;
INLINE LColor get_base() const;
INLINE void set_diff(const LColor &diff);
INLINE void clear_diff();
INLINE bool has_diff() const;
@ -75,12 +80,18 @@ PUBLISHED:
INLINE bool has_metallic() const;
INLINE double get_metallic() const;
INLINE void set_ior(double ior);
INLINE void clear_ior();
INLINE bool has_ior() const;
INLINE double get_ior() const;
INLINE void set_local(bool local);
INLINE void clear_local();
INLINE bool has_local() const;
INLINE bool get_local() const;
PUBLISHED:
MAKE_PROPERTY2(base, has_base, get_base, set_base, clear_base);
MAKE_PROPERTY2(diff, has_diff, get_diff, set_diff, clear_diff);
MAKE_PROPERTY2(amb, has_amb, get_amb, set_amb, clear_amb);
MAKE_PROPERTY2(emit, has_emit, get_emit, set_emit, clear_emit);
@ -88,21 +99,25 @@ PUBLISHED:
MAKE_PROPERTY2(shininess, has_shininess, get_shininess, set_shininess, clear_shininess);
MAKE_PROPERTY2(roughness, has_roughness, get_roughness, set_roughness, clear_roughness);
MAKE_PROPERTY2(metallic, has_metallic, get_metallic, set_metallic, clear_metallic);
MAKE_PROPERTY2(ior, has_ior, get_ior, set_ior, clear_ior);
MAKE_PROPERTY2(local, has_local, get_local, set_local, clear_local);
private:
enum Flags {
F_diff = 0x001,
F_amb = 0x002,
F_emit = 0x004,
F_spec = 0x008,
F_shininess = 0x010,
F_roughness = 0x020,
F_metallic = 0x040,
F_local = 0x080
F_base = 0x001,
F_diff = 0x002,
F_amb = 0x004,
F_emit = 0x008,
F_spec = 0x010,
F_shininess = 0x020,
F_roughness = 0x040,
F_metallic = 0x080,
F_ior = 0x100,
F_local = 0x200
};
LColor _base;
LColor _diff;
LColor _amb;
LColor _emit;
@ -110,6 +125,7 @@ private:
double _shininess;
double _roughness;
double _metallic;
double _ior;
bool _local;
int _flags;

View File

@ -2933,7 +2933,24 @@ yyreduce:
string name = (yyvsp[(3) - (6)]._string);
double value = (yyvsp[(5) - (6)]._number);
if (cmp_nocase_uh(name, "diffr") == 0) {
if (cmp_nocase_uh(name, "baser") == 0) {
LColor base = material->get_base();
base[0] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "baseg") == 0) {
LColor base = material->get_base();
base[1] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "baseb") == 0) {
LColor base = material->get_base();
base[2] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "basea") == 0) {
LColor base = material->get_base();
base[3] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "diffr") == 0) {
LColor diff = material->get_diff();
diff[0] = value;
material->set_diff(diff);
@ -3010,6 +3027,9 @@ yyreduce:
} else if (cmp_nocase_uh(name, "metallic") == 0) {
material->set_metallic(value);
} else if (cmp_nocase_uh(name, "ior") == 0) {
material->set_ior(value);
} else if (cmp_nocase_uh(name, "local") == 0) {
material->set_local(value != 0.0);

View File

@ -757,7 +757,24 @@ material_body:
string name = $3;
double value = $<_number>5;
if (cmp_nocase_uh(name, "diffr") == 0) {
if (cmp_nocase_uh(name, "baser") == 0) {
LColor base = material->get_base();
base[0] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "baseg") == 0) {
LColor base = material->get_base();
base[1] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "baseb") == 0) {
LColor base = material->get_base();
base[2] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "basea") == 0) {
LColor base = material->get_base();
base[3] = value;
material->set_base(base);
} else if (cmp_nocase_uh(name, "diffr") == 0) {
LColor diff = material->get_diff();
diff[0] = value;
material->set_diff(diff);
@ -834,6 +851,9 @@ material_body:
} else if (cmp_nocase_uh(name, "metallic") == 0) {
material->set_metallic(value);
} else if (cmp_nocase_uh(name, "ior") == 0) {
material->set_ior(value);
} else if (cmp_nocase_uh(name, "local") == 0) {
material->set_local(value != 0.0);

View File

@ -495,6 +495,9 @@ get_material_attrib(const EggMaterial *egg_mat, bool bface) {
// Ok, this is the first time we've seen this particular
// EggMaterial. Create a new Material that matches it.
PT(Material) mat = new Material(egg_mat->get_name());
if (egg_mat->has_base()) {
mat->set_base_color(egg_mat->get_base());
}
if (egg_mat->has_diff()) {
mat->set_diffuse(egg_mat->get_diff());
// By default, ambient is the same as diffuse, if diffuse is
@ -519,6 +522,9 @@ get_material_attrib(const EggMaterial *egg_mat, bool bface) {
if (egg_mat->has_metallic()) {
mat->set_metallic(egg_mat->get_metallic());
}
if (egg_mat->has_ior()) {
mat->set_refractive_index(egg_mat->get_ior());
}
if (egg_mat->has_local()) {
mat->set_local(egg_mat->get_local());
}

View File

@ -1031,6 +1031,10 @@ EggMaterial *EggSaver::
get_egg_material(Material *mat) {
if (mat != (Material *)NULL) {
EggMaterial temp(mat->get_name());
if (mat->has_base_color()) {
temp.set_base(mat->get_base_color());
}
if (mat->has_ambient()) {
temp.set_amb(mat->get_ambient());
}
@ -1057,6 +1061,10 @@ get_egg_material(Material *mat) {
temp.set_metallic(mat->get_metallic());
}
if (mat->has_refractive_index()) {
temp.set_ior(mat->get_refractive_index());
}
temp.set_local(mat->get_local());
return _materials.create_unique_material(temp, ~EggMaterial::E_mref_name);

View File

@ -694,6 +694,34 @@ pop_back() {
_vector.pop_back();
}
////////////////////////////////////////////////////////////////////
// Function: ordered_vector::resize
// Access: Public
// Description: Resizes the vector to contain n elements. This
// should not be used except to populate the vector
// for the first time.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare, class Vector>
INLINE void ordered_vector<Key, Compare, Vector>::
resize(SIZE_TYPE n) {
TAU_PROFILE("ordered_vector::resize()", " ", TAU_USER);
_vector.resize(n);
}
////////////////////////////////////////////////////////////////////
// Function: ordered_vector::resize
// Access: Public
// Description: Resizes the vector to contain n elements. This
// should not be used except to populate the vector
// for the first time.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare, class Vector>
INLINE void ordered_vector<Key, Compare, Vector>::
resize(SIZE_TYPE n, const VALUE_TYPE &value) {
TAU_PROFILE("ordered_vector::resize()", " ", TAU_USER);
_vector.resize(n, value);
}
////////////////////////////////////////////////////////////////////
// Function: ordered_vector::nci
// Access: Private

View File

@ -219,6 +219,8 @@ public:
INLINE void push_back(const VALUE_TYPE &key);
INLINE void pop_back();
INLINE void resize(SIZE_TYPE n);
INLINE void resize(SIZE_TYPE n, const VALUE_TYPE &value);
private:
INLINE ITERATOR nci(CONST_ITERATOR i);

View File

@ -6749,7 +6749,7 @@ do_issue_material() {
call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
call_glMaterialfv(face, GL_EMISSION, material->get_emission());
glMaterialf(face, GL_SHININESS, min(material->get_shininess(), (PN_stdfloat)128.0));
glMaterialf(face, GL_SHININESS, max(min(material->get_shininess(), (PN_stdfloat)128), (PN_stdfloat)0));
if (material->has_ambient() && material->has_diffuse()) {
// The material has both an ambient and diffuse specified. This
@ -11419,7 +11419,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
}
#ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL.
if (_supports_texture_lod) {
if (is_at_least_gl_version(1, 2)) {
// By the time we get here, we have a pretty good prediction for
// the number of mipmaps we're going to have, so tell the GL that's
// all it's going to get.
@ -11934,7 +11934,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
<< "No mipmap level " << n << " defined for " << tex->get_name()
<< "\n";
#ifndef OPENGLES
if (_supports_texture_lod) {
if (is_at_least_gl_version(1, 2)) {
// Tell the GL we have no more mipmaps for it to use.
glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
}
@ -12154,7 +12154,7 @@ upload_simple_texture(CLP(TextureContext) *gtc) {
#ifndef OPENGLES
// Turn off mipmaps for the simple texture.
if (tex->uses_mipmaps() && _supports_texture_lod) {
if (tex->uses_mipmaps() && is_at_least_gl_version(1, 2)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
#endif
@ -12820,7 +12820,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
GLint highest_level = num_expected_levels;
#ifndef OPENGLES
if (_supports_texture_lod) {
if (is_at_least_gl_version(1, 2)) {
glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
highest_level = min(highest_level, num_expected_levels);
}

View File

@ -687,6 +687,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
_glgsg->_glGetActiveUniform(_glsl_program, i, name_buflen, NULL, &param_size, &param_type, name_buffer);
GLint p = _glgsg->_glGetUniformLocation(_glsl_program, name_buffer);
// Some NVidia drivers (361.43 for example) (incorrectly) include "internal" uniforms in
// the list starting with "_main_" (for example, "_main_0_gp5fp[0]")
// we need to skip those, because we don't know anything about them
if (strncmp(name_buffer, "_main_", 6) == 0) {
GLCAT.warning() << "Ignoring uniform " << name_buffer << " which may be generated by buggy Nvidia driver.\n";
return;
}
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Active uniform " << name_buffer << " with size " << param_size
@ -905,7 +914,19 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
if (noprefix == "Material.ambient") {
if (noprefix == "Material.baseColor") {
if (param_type != GL_FLOAT_VEC4) {
GLCAT.error()
<< "p3d_Material.baseColor should be vec4\n";
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_row0;
bind._dep[0] |= Shader::SSD_color;
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
} else if (noprefix == "Material.ambient") {
if (param_type != GL_FLOAT_VEC4) {
GLCAT.error()
<< "p3d_Material.ambient should be vec4\n";
@ -954,6 +975,39 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
} else if (noprefix == "Material.roughness") {
if (param_type != GL_FLOAT) {
GLCAT.error()
<< "p3d_Material.roughness should be float\n";
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_cell15;
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
} else if (noprefix == "Material.metallic") {
if (param_type != GL_FLOAT && param_type != GL_BOOL) {
GLCAT.error()
<< "p3d_Material.metallic should be bool or float\n";
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_row3x1;
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
} else if (noprefix == "Material.refractiveIndex") {
if (param_type != GL_FLOAT) {
GLCAT.error()
<< "p3d_Material.refractiveIndex should be float\n";
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_cell13;
_shader->_mat_spec.push_back(bind);
_shader->_mat_deps |= bind._dep[0];
return;
}
}
if (noprefix == "ColorScale") {
@ -1982,6 +2036,12 @@ issue_parameters(int altered) {
case Shader::SMP_cell15:
_glgsg->_glUniform1fv(p, 1, data+15);
continue;
case Shader::SMP_cell14:
_glgsg->_glUniform1fv(p, 1, data+14);
continue;
case Shader::SMP_cell13:
_glgsg->_glUniform1fv(p, 1, data+13);
continue;
}
}
}

View File

@ -20,6 +20,7 @@
////////////////////////////////////////////////////////////////////
INLINE Material::
Material(const string &name) : Namable(name) {
_base_color.set(1.0f, 1.0f, 1.0f, 1.0f);
_ambient.set(1.0f, 1.0f, 1.0f, 1.0f);
_diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
_specular.set(0.0f, 0.0f, 0.0f, 1.0f);
@ -27,6 +28,7 @@ Material(const string &name) : Namable(name) {
_shininess = 0;
_roughness = 1;
_metallic = 0;
_refractive_index = 1;
_flags = 0;
}
@ -62,6 +64,33 @@ get_default() {
return _default;
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_base_color
// Access: Published
// Description: Returns true if the base color has been explicitly
// set for this material, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool Material::
has_base_color() const {
return (_flags & F_base_color) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: Material::get_base_color
// Access: Published
// Description: Returns the base_color color setting, if it has been
// set. If neither the base color nor the metallic
// have been set, this returns the diffuse color.
////////////////////////////////////////////////////////////////////
INLINE const LColor &Material::
get_base_color() const {
if (!has_base_color() && !has_metallic()) {
return _diffuse;
} else {
return _base_color;
}
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_ambient
// Access: Published
@ -96,7 +125,7 @@ clear_ambient() {
nassertv(!is_attrib_locked());
}
_flags &= ~F_ambient;
_ambient.set(0.0f, 0.0f, 0.0f, 0.0f);
_ambient = _base_color;
}
////////////////////////////////////////////////////////////////////
@ -133,7 +162,7 @@ clear_diffuse() {
nassertv(!is_attrib_locked());
}
_flags &= ~F_diffuse;
_diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
_diffuse = _base_color * (1 - _metallic);
}
////////////////////////////////////////////////////////////////////
@ -159,20 +188,6 @@ get_specular() const {
return _specular;
}
////////////////////////////////////////////////////////////////////
// Function: Material::clear_specular
// Access: Published
// Description: Removes the explicit specular color from the material.
////////////////////////////////////////////////////////////////////
INLINE void Material::
clear_specular() {
if (enforce_attrib_lock) {
nassertv(!is_attrib_locked());
}
_flags &= ~F_specular;
_specular.set(0.0f, 0.0f, 0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_emission
// Access: Published
@ -220,6 +235,17 @@ get_shininess() const {
return _shininess;
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_roughness
// Access: Published
// Description: Returns true if the roughness has been explicitly
// set for this material, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool Material::
has_roughness() const {
return (_flags & F_roughness) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_metallic
// Access: Published
@ -243,28 +269,25 @@ get_metallic() const {
}
////////////////////////////////////////////////////////////////////
// Function: Material::clear_metallic
// Function: Material::has_refractive_index
// Access: Published
// Description: Removes the explicit metallic setting from the material.
// Description: Returns true if a refractive index has explicitly
// been specified for this material.
////////////////////////////////////////////////////////////////////
INLINE void Material::
clear_metallic() {
if (enforce_attrib_lock) {
nassertv(!is_attrib_locked());
}
_flags &= ~F_metallic;
_metallic = 0;
INLINE bool Material::
has_refractive_index() const {
return (_flags & F_refractive_index) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: Material::has_roughness
// Function: Material::get_refractive_index
// Access: Published
// Description: Returns true if the roughness has been explicitly
// set for this material, false otherwise.
// Description: Returns the index of refraction, or 1 if none has
// been set for this material.
////////////////////////////////////////////////////////////////////
INLINE bool Material::
has_roughness() const {
return (_flags & F_roughness) != 0;
INLINE PN_stdfloat Material::
get_refractive_index() const {
return _refractive_index;
}
////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,7 @@ PT(Material) Material::_default;
void Material::
operator = (const Material &copy) {
Namable::operator = (copy);
_base_color = copy._base_color;
_ambient = copy._ambient;
_diffuse = copy._diffuse;
_specular = copy._specular;
@ -38,9 +39,80 @@ operator = (const Material &copy) {
_shininess = copy._shininess;
_roughness = copy._roughness;
_metallic = copy._metallic;
_refractive_index = copy._refractive_index;
_flags = copy._flags & (~F_attrib_lock);
}
////////////////////////////////////////////////////////////////////
// Function: Material::set_base_color
// Access: Published
// Description: Specifies the base color of the material. In
// conjunction with set_metallic, this is an alternate
// way to specify the color of a material. For
// dielectrics, this will determine the value of the
// diffuse color, and for metals, this will determine
// the value of the specular color.
//
// Setting this will clear an explicit specular,
// diffuse or ambient color assignment.
//
// If this is not set, the object color will be used.
////////////////////////////////////////////////////////////////////
void Material::
set_base_color(const LColor &color) {
if (enforce_attrib_lock) {
if ((_flags & F_base_color) == 0) {
nassertv(!is_attrib_locked());
}
}
_base_color = color;
_flags |= F_base_color | F_metallic;
_flags &= ~(F_ambient | F_diffuse | F_specular);
// Recalculate the diffuse and specular colors.
_ambient = _base_color;
_diffuse = _base_color * (1 - _metallic);
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
f0 *= (1 - _metallic);
}
_specular.set(f0, f0, f0, 0);
_specular += _base_color * _metallic;
}
////////////////////////////////////////////////////////////////////
// Function: Material::clear_base_color
// Access: Published
// Description: Removes the explicit base_color color from the material.
////////////////////////////////////////////////////////////////////
void Material::
clear_base_color() {
if (enforce_attrib_lock) {
nassertv(!is_attrib_locked());
}
_flags &= ~F_base_color;
_base_color.set(0.0f, 0.0f, 0.0f, 0.0f);
if ((_flags & F_ambient) == 0) {
_ambient.set(0, 0, 0, 0);
}
if ((_flags & F_diffuse) == 0) {
_diffuse.set(0, 0, 0, 0);
}
if ((_flags & F_specular) == 0) {
// Recalculate the specular color.
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
}
_specular.set(f0, f0, f0, 0);
}
}
////////////////////////////////////////////////////////////////////
// Function: Material::set_ambient
// Access: Published
@ -92,7 +164,7 @@ set_diffuse(const LColor &color) {
////////////////////////////////////////////////////////////////////
// Function: Material::set_specular
// Access: Published
// Description: Specifies the diffuse color setting of the material.
// Description: Specifies the specular color setting of the material.
// This will be multiplied by any lights in effect on
// the material to compute the color of specular
// highlights on the object.
@ -100,7 +172,9 @@ set_diffuse(const LColor &color) {
// This is the highlight color of an object: the color
// of small highlight reflections.
//
// If this is not set, highlights will not appear.
// If this is not set, the specular color is taken from
// the index of refraction, which is 1 by default
// (meaning no specular reflections are generated).
////////////////////////////////////////////////////////////////////
void Material::
set_specular(const LColor &color) {
@ -113,6 +187,29 @@ set_specular(const LColor &color) {
_flags |= F_specular;
}
////////////////////////////////////////////////////////////////////
// Function: Material::clear_specular
// Access: Published
// Description: Removes the explicit specular color from the material.
////////////////////////////////////////////////////////////////////
void Material::
clear_specular() {
if (enforce_attrib_lock) {
nassertv(!is_attrib_locked());
}
_flags &= ~F_specular;
// Recalculate the specular color from the refractive index.
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
f0 *= (1 - _metallic);
}
_specular.set(f0, f0, f0, 0);
_specular += _base_color * _metallic;
}
////////////////////////////////////////////////////////////////////
// Function: Material::set_emission
// Access: Published
@ -211,8 +308,10 @@ set_roughness(PN_stdfloat roughness) {
// Description: Sets the metallic setting of the material, which is
// is used for physically-based rendering models.
// This is usually 0 for dielectric materials and 1
// for metals. It usually does not make sense to set
// this to a value other than 0 or 1.
// for metals. It really does not make sense to set
// this to a value other than 0 or 1, but it is
// nonetheless a float for compatibility with tools
// that allow setting this to values other than 0 or 1.
////////////////////////////////////////////////////////////////////
void Material::
set_metallic(PN_stdfloat metallic) {
@ -223,6 +322,80 @@ set_metallic(PN_stdfloat metallic) {
}
_metallic = metallic;
_flags |= F_metallic;
// Recalculate the diffuse and specular.
if ((_flags & F_diffuse) == 0) {
_diffuse = _base_color * (1 - _metallic);
}
if ((_flags & F_specular) == 0) {
// Recalculate the specular color.
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
f0 *= (1 - _metallic);
}
_specular.set(f0, f0, f0, 0);
_specular += _base_color * _metallic;
}
}
////////////////////////////////////////////////////////////////////
// Function: Material::clear_metallic
// Access: Published
// Description: Removes the explicit metallic setting from the material.
////////////////////////////////////////////////////////////////////
void Material::
clear_metallic() {
if (enforce_attrib_lock) {
nassertv(!is_attrib_locked());
}
_flags &= ~F_metallic;
_metallic = 0;
// If we had a base color, recalculate the diffuse and specular.
if (_flags & F_base_color) {
if ((_flags & F_diffuse) == 0) {
_diffuse = _base_color;
}
if ((_flags & F_specular) == 0) {
// Recalculate the specular color.
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
}
_specular.set(f0, f0, f0, 0);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: Material::set_refractive_index
// Access: Published
// Description: Sets the index of refraction of the material, which
// is used to determine the specular color in absence
// of an explicit specular color assignment.
// This is usually 1.5 for dielectric materials. It
// is not very useful for metals, since they cannot
// be described as easily with a single number.
//
// Should be 1 or higher. The default is 1.
////////////////////////////////////////////////////////////////////
void Material::
set_refractive_index(PN_stdfloat refractive_index) {
_refractive_index = refractive_index;
_flags |= F_refractive_index;
if ((_flags & F_specular) == 0) {
// Recalculate the specular color.
PN_stdfloat f0 = 0;
if (_refractive_index >= 1) {
f0 = (_refractive_index - 1) / (_refractive_index + 1);
f0 *= f0;
}
_specular.set(f0, f0, f0, 0);
}
}
////////////////////////////////////////////////////////////////////
@ -239,6 +412,9 @@ compare_to(const Material &other) const {
if (_flags != other._flags) {
return _flags - other._flags;
}
if (has_base_color() && get_base_color() != other.get_base_color()) {
return get_base_color().compare_to(other.get_base_color());
}
if (has_ambient() && get_ambient() != other.get_ambient()) {
return get_ambient().compare_to(other.get_ambient());
}
@ -254,6 +430,12 @@ compare_to(const Material &other) const {
if (get_shininess() != other.get_shininess()) {
return get_shininess() < other.get_shininess() ? -1 : 1;
}
if (get_metallic() != other.get_metallic()) {
return get_metallic() < other.get_metallic() ? -1 : 1;
}
if (get_refractive_index() != other.get_refractive_index()) {
return get_refractive_index() < other.get_refractive_index() ? -1 : 1;
}
return strcmp(get_name().c_str(), other.get_name().c_str());
}
@ -266,14 +448,21 @@ compare_to(const Material &other) const {
void Material::
output(ostream &out) const {
out << "Material " << get_name();
if (has_ambient()) {
out << " a(" << get_ambient() << ")";
if (has_base_color()) {
out << " c(" << get_base_color() << ")";
} else {
if (has_ambient()) {
out << " a(" << get_ambient() << ")";
}
if (has_diffuse()) {
out << " d(" << get_diffuse() << ")";
}
if (has_specular()) {
out << " s(" << get_specular() << ")";
}
}
if (has_diffuse()) {
out << " d(" << get_diffuse() << ")";
}
if (has_specular()) {
out << " s(" << get_specular() << ")";
if (has_refractive_index()) {
out << " ior" << get_refractive_index();
}
if (has_emission()) {
out << " e(" << get_emission() << ")";
@ -283,7 +472,7 @@ output(ostream &out) const {
} else {
out << " s" << get_shininess();
}
if (has_metallic()) {
if (_flags & F_metallic) {
out << " m" << _metallic;
}
out << " l" << get_local()
@ -298,6 +487,9 @@ output(ostream &out) const {
void Material::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << "Material " << get_name() << "\n";
if (has_base_color()) {
indent(out, indent_level + 2) << "base_color = " << get_ambient() << "\n";
}
if (has_ambient()) {
indent(out, indent_level + 2) << "ambient = " << get_ambient() << "\n";
}
@ -306,6 +498,8 @@ write(ostream &out, int indent_level) const {
}
if (has_specular()) {
indent(out, indent_level + 2) << "specular = " << get_specular() << "\n";
} else {
indent(out, indent_level + 2) << "refractive_index = " << get_refractive_index() << "\n";
}
if (has_emission()) {
indent(out, indent_level + 2) << "emission = " << get_emission() << "\n";
@ -343,11 +537,19 @@ register_with_read_factory() {
void Material::
write_datagram(BamWriter *manager, Datagram &me) {
me.add_string(get_name());
_ambient.write_datagram(me);
_diffuse.write_datagram(me);
_specular.write_datagram(me);
me.add_int32(_flags);
if (_flags & F_metallic) {
// Metalness workflow.
_base_color.write_datagram(me);
me.add_stdfloat(_metallic);
} else {
_ambient.write_datagram(me);
_diffuse.write_datagram(me);
_specular.write_datagram(me);
}
_emission.write_datagram(me);
me.add_stdfloat(_shininess);
if (_flags & F_roughness) {
me.add_stdfloat(_roughness);
@ -355,11 +557,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
me.add_stdfloat(_shininess);
}
me.add_int32(_flags);
if (_flags & F_metallic) {
me.add_stdfloat(_metallic);
}
me.add_stdfloat(_refractive_index);
}
////////////////////////////////////////////////////////////////////
@ -389,19 +587,40 @@ make_Material(const FactoryParams &params) {
void Material::
fillin(DatagramIterator &scan, BamReader *manager) {
set_name(scan.get_string());
_ambient.read_datagram(scan);
_diffuse.read_datagram(scan);
_specular.read_datagram(scan);
_emission.read_datagram(scan);
_shininess = scan.get_stdfloat();
_flags = scan.get_int32();
if (_flags & F_roughness) {
// The shininess we read is actually a roughness value.
set_roughness(_shininess);
}
if (manager->get_file_minor_ver() >= 39) {
_flags = scan.get_int32();
if (_flags & F_metallic) {
_metallic = scan.get_stdfloat();
if (_flags & F_metallic) {
// Metalness workflow: read base color and metallic
_base_color.read_datagram(scan);
set_metallic(scan.get_stdfloat());
} else {
_ambient.read_datagram(scan);
_diffuse.read_datagram(scan);
_specular.read_datagram(scan);
}
_emission.read_datagram(scan);
if (_flags & F_roughness) {
set_roughness(scan.get_stdfloat());
} else {
_shininess = scan.get_stdfloat();
}
_refractive_index = scan.get_stdfloat();
} else {
_ambient.read_datagram(scan);
_diffuse.read_datagram(scan);
_specular.read_datagram(scan);
_emission.read_datagram(scan);
_shininess = scan.get_stdfloat();
_flags = scan.get_int32();
if (_flags & F_roughness) {
// The shininess we read is actually a roughness value.
set_roughness(_shininess);
}
}
}

View File

@ -30,6 +30,18 @@ class FactoryParams;
// Description : Defines the way an object appears in the presence of
// lighting. A material is only necessary if lighting
// is to be enabled; otherwise, the material isn't used.
//
// There are two workflows that are supported: the
// "classic" workflow of providing separate ambient,
// diffuse and specular colors, and the "metalness"
// workflow, in which a base color is specified along
// with a "metallic" value that indicates whether the
// material is a metal or a dielectric.
//
// The size of the specular highlight can be specified
// by either specifying the specular exponent (shininess)
// or by specifying a roughness value that in perceptually
// linear in the range of 0-1.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ Material : public TypedWritableReferenceCount, public Namable {
PUBLISHED:
@ -40,6 +52,11 @@ PUBLISHED:
INLINE static Material *get_default();
INLINE bool has_base_color() const;
INLINE const LColor &get_base_color() const;
void set_base_color(const LColor &color);
void clear_base_color();
INLINE bool has_ambient() const;
INLINE const LColor &get_ambient() const;
void set_ambient(const LColor &color);
@ -53,7 +70,7 @@ PUBLISHED:
INLINE bool has_specular() const;
INLINE const LColor &get_specular() const;
void set_specular(const LColor &color);
INLINE void clear_specular();
void clear_specular();
INLINE bool has_emission() const;
INLINE const LColor &get_emission() const;
@ -70,7 +87,11 @@ PUBLISHED:
INLINE bool has_metallic() const;
INLINE PN_stdfloat get_metallic() const;
void set_metallic(PN_stdfloat metallic);
INLINE void clear_metallic();
void clear_metallic();
INLINE bool has_refractive_index() const;
INLINE PN_stdfloat get_refractive_index() const;
void set_refractive_index(PN_stdfloat refractive_index);
INLINE bool get_local() const;
INLINE void set_local(bool local);
@ -90,6 +111,8 @@ PUBLISHED:
INLINE void set_attrib_lock();
PUBLISHED:
MAKE_PROPERTY2(base_color, has_base_color, get_base_color,
set_base_color, clear_base_color);
MAKE_PROPERTY2(ambient, has_ambient, get_ambient,
set_ambient, clear_ambient);
MAKE_PROPERTY2(diffuse, has_diffuse, get_diffuse,
@ -102,11 +125,14 @@ PUBLISHED:
MAKE_PROPERTY(shininess, get_shininess, set_shininess);
MAKE_PROPERTY(roughness, get_roughness, set_roughness);
MAKE_PROPERTY(metallic, get_metallic, set_metallic);
MAKE_PROPERTY(refractive_index, get_refractive_index,
set_refractive_index);
MAKE_PROPERTY(local, get_local, set_local);
MAKE_PROPERTY(twoside, get_twoside, set_twoside);
private:
LColor _base_color;
LColor _ambient;
LColor _diffuse;
LColor _specular;
@ -114,6 +140,7 @@ private:
PN_stdfloat _shininess;
PN_stdfloat _roughness;
PN_stdfloat _metallic;
PN_stdfloat _refractive_index;
static PT(Material) _default;
@ -127,6 +154,8 @@ private:
F_attrib_lock = 0x040,
F_roughness = 0x080,
F_metallic = 0x100,
F_base_color = 0x200,
F_refractive_index = 0x400,
};
int _flags;

View File

@ -405,7 +405,7 @@ cp_dependency(ShaderMatInput inp) {
if (inp == SMO_INVALID) {
return SSD_NONE;
}
if (inp == SMO_attr_material) {
if (inp == SMO_attr_material || inp == SMO_attr_material2) {
dep |= SSD_material;
}
if (inp == SMO_attr_color) {

View File

@ -194,6 +194,9 @@ public:
SMO_inv_texmat_i,
// Additional properties for PBR materials
SMO_attr_material2,
SMO_INVALID
};
@ -272,6 +275,8 @@ public:
SMP_upper3x3,
SMP_transpose3x3,
SMP_cell15,
SMP_cell14,
SMP_cell13,
};
enum ShaderStateDep {

View File

@ -489,7 +489,7 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
size_t Texture::
estimate_texture_memory() const {
CDReader cdata(_cycler);
size_t pixels = cdata->_x_size * cdata->_y_size;
size_t pixels = cdata->_x_size * cdata->_y_size * cdata->_z_size;
size_t bpp = 4;
switch (cdata->_format) {
@ -503,6 +503,7 @@ estimate_texture_memory() const {
case Texture::F_blue:
case Texture::F_luminance:
case Texture::F_sluminance:
case Texture::F_r8i:
bpp = 1;
break;
@ -519,6 +520,8 @@ estimate_texture_memory() const {
case Texture::F_rgb5:
case Texture::F_rgba5:
case Texture::F_srgb:
// Most of the above formats have only 3 bytes, but they are most likely to
// get padded by the driver
bpp = 4;
break;
@ -536,9 +539,15 @@ estimate_texture_memory() const {
break;
case Texture::F_depth_component:
case Texture::F_depth_component16:
bpp = 2;
break;
case Texture::F_depth_component24: // Gets padded
case Texture::F_depth_component32:
bpp = 4;
break;
case Texture::F_rgba12:
case Texture::F_rgb12:
bpp = 8;
@ -552,7 +561,6 @@ estimate_texture_memory() const {
break;
case Texture::F_r16:
case Texture::F_r8i:
case Texture::F_rg8i:
bpp = 2;
break;
@ -564,17 +572,16 @@ estimate_texture_memory() const {
break;
case Texture::F_r32i:
bpp = 4;
break;
case Texture::F_r32:
bpp = 4;
break;
case Texture::F_rg32:
bpp = 8;
break;
case Texture::F_rgb32:
bpp = 12;
bpp = 16;
break;
case Texture::F_r11_g11_b10:
@ -582,6 +589,8 @@ estimate_texture_memory() const {
break;
default:
gobj_cat.warning() << "Unhandled format in estimate_texture_memory(): "
<< cdata->_format << "\n";
break;
}

View File

@ -341,7 +341,7 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels,
if (store_record && tex->is_cacheable()) {
// Store the on-disk cache record for next time.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
}
@ -473,7 +473,7 @@ ns_load_texture(const Filename &orig_filename,
if (store_record && tex->is_cacheable()) {
// Store the on-disk cache record for next time.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
}
@ -585,7 +585,7 @@ ns_load_3d_texture(const Filename &filename_pattern,
if (store_record && tex->is_cacheable()) {
// Store the on-disk cache record for next time.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
}
@ -691,7 +691,7 @@ ns_load_2d_texture_array(const Filename &filename_pattern,
if (store_record && tex->is_cacheable()) {
// Store the on-disk cache record for next time.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
}
@ -790,7 +790,7 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps,
if (store_record && tex->is_cacheable()) {
// Store the on-disk cache record for next time.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
}
@ -1166,7 +1166,7 @@ try_load_cache(PT(Texture) &tex, BamCache *cache, const Filename &filename,
// from the cache. To keep the cache current,
// rewrite it to the cache now, in its newly
// compressed form.
record->set_data(tex, tex);
record->set_data(tex);
cache->store(record);
compressed_cache_record = true;
}

View File

@ -14,49 +14,21 @@
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Default Constructor
// Function: LPoint2::Constructor
// Access: Public
// Description:
// Description: Constructs a new LPoint2 from a LVecBase2
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)() {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) &copy) : FLOATNAME(LVecBase2)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2) &FLOATNAME(LPoint2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
FLOATNAME(LVecBase2)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Copy Fill Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2) &FLOATNAME(LPoint2)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase2)::operator = (fill_value);
return *this;
FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2)& copy) :
FLOATNAME(LVecBase2)(copy)
{
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Constructor
// Access: Public
// Description:
// Description: Constructs a new LPoint2 all components set to the
// fill value.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(FLOATTYPE fill_value) :
@ -67,7 +39,7 @@ FLOATNAME(LPoint2)(FLOATTYPE fill_value) :
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Constructor
// Access: Public
// Description:
// Description: Constructs a new LPoint2 with the given components
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(FLOATTYPE x, FLOATTYPE y) :
@ -186,6 +158,18 @@ operator / (FLOATTYPE scalar) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LPoint2::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
normalized() const {
return FLOATNAME(LVecBase2)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::project
// Access: Published

View File

@ -19,10 +19,9 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LPoint2) : public FLOATNAME(LVecBase2) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint2)();
INLINE_LINMATH FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LPoint2) &operator = (const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LPoint2) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint2)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2)& copy);
INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE x, FLOATTYPE y);
@ -51,6 +50,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint2) operator / (FLOATTYPE scalar) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LPoint2) normalized() const;
INLINE_LINMATH FLOATNAME(LPoint2) project(const FLOATNAME(LVecBase2) &onto) const;
#endif

View File

@ -13,15 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)() {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Copy Constructor
// Access: Public
@ -31,28 +22,6 @@ INLINE_LINMATH FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) &copy) : FLOATNAME(LVecBase3)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint3) &FLOATNAME(LPoint3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
FLOATNAME(LVecBase3)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Copy Fill Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint3) &FLOATNAME(LPoint3)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase3)::operator = (fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Constructor
// Access: Public
@ -230,6 +199,18 @@ cross(const FLOATNAME(LVecBase3) &other) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LPoint3::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
normalized() const {
return FLOATNAME(LVecBase3)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::project
// Access: Published

View File

@ -24,10 +24,8 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LPoint3) : public FLOATNAME(LVecBase3) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint3)();
INLINE_LINMATH FLOATNAME(LPoint3)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LPoint3) &operator = (const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LPoint3) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
INLINE_LINMATH FLOATNAME(LPoint3)(const FLOATNAME(LVecBase2) &copy, FLOATTYPE z);
@ -61,6 +59,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint3) cross(const FLOATNAME(LVecBase3) &other) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LPoint3) normalized() const;
INLINE_LINMATH FLOATNAME(LPoint3) project(const FLOATNAME(LVecBase3) &onto) const;
#endif

View File

@ -13,15 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)() {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Copy Constructor
// Access: Public
@ -31,28 +22,6 @@ INLINE_LINMATH FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) &copy) : FLOATNAME(LVecBase4)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint4) &FLOATNAME(LPoint4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
FLOATNAME(LVecBase4)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Copy Fill Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint4) &FLOATNAME(LPoint4)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase4)::operator = (fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Constructor
// Access: Public
@ -217,6 +186,19 @@ operator / (FLOATTYPE scalar) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LPoint4::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
normalized() const {
return FLOATNAME(LVecBase4)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::project
// Access: Published

View File

@ -18,10 +18,8 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LPoint4) : public FLOATNAME(LVecBase4) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint4)();
INLINE_LINMATH FLOATNAME(LPoint4)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LPoint4) &operator = (const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LPoint4) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
INLINE_LINMATH FLOATNAME(LPoint4)(const FLOATNAME(LVecBase3) &copy, FLOATTYPE w);
@ -53,6 +51,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LPoint4) operator / (FLOATTYPE scalar) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LPoint4) normalized() const;
INLINE_LINMATH FLOATNAME(LPoint4) project(const FLOATNAME(LVecBase4) &onto) const;
#endif

View File

@ -12,48 +12,6 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Default Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) &copy) : _v(copy._v) {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
TAU_PROFILE("void LVecBase2::operator = (LVecBase2 &)", " ", TAU_USER);
_v = copy._v;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Fill Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2)::
operator = (FLOATTYPE fill_value) {
fill(fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Constructor
// Access: Published
@ -107,15 +65,6 @@ unit_y() {
return _unit_y;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2)::
~FLOATNAME(LVecBase2)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Indexing Operator
// Access: Published
@ -143,7 +92,7 @@ operator [](int i) {
// Access: Published, Static
// Description: Returns 2: the number of components of a LVecBase2.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase2)::
CONSTEXPR int FLOATNAME(LVecBase2)::
size() {
return 2;
}
@ -274,8 +223,8 @@ get_data() const {
// Access: Published
// Description: Returns the number of elements in the vector, two.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase2)::
get_num_components() const {
CONSTEXPR int FLOATNAME(LVecBase2)::
get_num_components() {
return 2;
}
@ -418,6 +367,22 @@ normalize() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
normalized() const {
FLOATTYPE l2 = length_squared();
if (l2 == (FLOATTYPE)0.0f) {
return FLOATNAME(LVecBase2)(0.0f);
}
return (*this) / csqrt(l2);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::project
// Access: Published

View File

@ -34,38 +34,38 @@ PUBLISHED:
#endif
};
INLINE_LINMATH FLOATNAME(LVecBase2)();
INLINE_LINMATH FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LVecBase2) &operator = (const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LVecBase2) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase2)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVecBase2)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase2)(FLOATTYPE x, FLOATTYPE y);
ALLOC_DELETED_CHAIN(FLOATNAME(LVecBase2));
INLINE_LINMATH static const FLOATNAME(LVecBase2) &zero();
INLINE_LINMATH static const FLOATNAME(LVecBase2) &unit_x();
INLINE_LINMATH static const FLOATNAME(LVecBase2) &unit_y();
INLINE_LINMATH ~FLOATNAME(LVecBase2)();
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);
INLINE_LINMATH static int size();
CONSTEXPR static int size();
INLINE_LINMATH bool is_nan() const;
INLINE_LINMATH FLOATTYPE get_cell(int i) const;
INLINE_LINMATH void set_cell(int i, FLOATTYPE value);
INLINE_LINMATH FLOATTYPE get_x() const;
INLINE_LINMATH FLOATTYPE get_y() const;
INLINE_LINMATH void set_cell(int i, FLOATTYPE value);
INLINE_LINMATH void set_x(FLOATTYPE value);
INLINE_LINMATH void set_y(FLOATTYPE value);
PUBLISHED:
MAKE_PROPERTY(x, get_x, set_x);
MAKE_PROPERTY(y, get_y, set_y);
// These next functions add to an existing value.
// i.e. foo.set_x(foo.get_x() + value)
// These are useful to reduce overhead in scripting
@ -75,7 +75,7 @@ PUBLISHED:
INLINE_LINMATH void add_y(FLOATTYPE value);
INLINE_LINMATH const FLOATTYPE *get_data() const;
INLINE_LINMATH int get_num_components() const;
CONSTEXPR static int get_num_components();
public:
INLINE_LINMATH iterator begin();
@ -94,6 +94,7 @@ PUBLISHED:
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATTYPE length() const;
INLINE_LINMATH bool normalize();
INLINE_LINMATH FLOATNAME(LVecBase2) normalized() const;
INLINE_LINMATH FLOATNAME(LVecBase2) project(const FLOATNAME(LVecBase2) &onto) const;
#endif

View File

@ -13,47 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) &copy) : _v(copy._v) {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
TAU_PROFILE("void LVecBase3::operator =(LVecBase3 &)", " ", TAU_USER);
_v = copy._v;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Fill Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3)::
operator = (FLOATTYPE fill_value) {
fill(fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Constructor
// Access: Public
@ -128,15 +87,6 @@ unit_z() {
return _unit_z;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3)::
~FLOATNAME(LVecBase3)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Indexing Operator
// Access: Public
@ -164,7 +114,7 @@ operator [](int i) {
// Access: Public, Static
// Description: Returns 3: the number of components of a LVecBase3.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase3)::
CONSTEXPR int FLOATNAME(LVecBase3)::
size() {
return 3;
}
@ -358,8 +308,8 @@ get_data() const {
// Access: Public
// Description: Returns the number of elements in the vector, three.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase3)::
get_num_components() const {
CONSTEXPR int FLOATNAME(LVecBase3)::
get_num_components() {
return 3;
}
@ -509,6 +459,22 @@ normalize() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
normalized() const {
FLOATTYPE l2 = length_squared();
if (l2 == (FLOATTYPE)0.0f) {
return FLOATNAME(LVecBase3)(0.0f);
}
return (*this) / csqrt(l2);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::project
// Access: Published

View File

@ -34,10 +34,7 @@ PUBLISHED:
#endif
};
INLINE_LINMATH FLOATNAME(LVecBase3)();
INLINE_LINMATH FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LVecBase3) &operator = (const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LVecBase3) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase3)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVecBase3)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
INLINE_LINMATH FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase2) &copy, FLOATTYPE z);
@ -48,15 +45,13 @@ PUBLISHED:
INLINE_LINMATH static const FLOATNAME(LVecBase3) &unit_y();
INLINE_LINMATH static const FLOATNAME(LVecBase3) &unit_z();
INLINE_LINMATH ~FLOATNAME(LVecBase3)();
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);
INLINE_LINMATH static int size();
CONSTEXPR static int size();
INLINE_LINMATH bool is_nan() const;
@ -74,6 +69,12 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVecBase2) get_xz() const;
INLINE_LINMATH FLOATNAME(LVecBase2) get_yz() const;
PUBLISHED:
MAKE_PROPERTY(x, get_x, set_x);
MAKE_PROPERTY(y, get_y, set_y);
MAKE_PROPERTY(z, get_z, set_z);
MAKE_PROPERTY(xy, get_xy);
// These next functions add to an existing value.
// i.e. foo.set_x(foo.get_x() + value)
// These are useful to reduce overhead in scripting
@ -84,7 +85,7 @@ PUBLISHED:
INLINE_LINMATH void add_z(FLOATTYPE value);
INLINE_LINMATH const FLOATTYPE *get_data() const;
INLINE_LINMATH int get_num_components() const;
CONSTEXPR static int get_num_components();
public:
INLINE_LINMATH iterator begin();
@ -103,6 +104,7 @@ PUBLISHED:
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATTYPE length() const;
INLINE_LINMATH bool normalize();
INLINE_LINMATH FLOATNAME(LVecBase3) normalized() const;
INLINE_LINMATH FLOATNAME(LVecBase3) project(const FLOATNAME(LVecBase3) &onto) const;
#endif

View File

@ -13,24 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Default Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) &copy) : _v(copy._v) {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Copy Constructor
// Access: Public
@ -41,40 +23,6 @@ FLOATNAME(LVecBase4)(const FLOATNAME(UnalignedLVecBase4) &copy) {
set(copy[0], copy[1], copy[2], copy[3]);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
TAU_PROFILE("void LVecBase4::operator = (LVecBase4 &)", " ", TAU_USER);
_v = copy._v;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4)::
operator = (const FLOATNAME(UnalignedLVecBase4) &copy) {
set(copy[0], copy[1], copy[2], copy[3]);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Fill Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4)::
operator = (FLOATTYPE fill_value) {
fill(fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Constructor
// Access: Published
@ -128,15 +76,6 @@ FLOATNAME(LVecBase4)(const FLOATNAME(LVector3) &vector) {
set(vector[0], vector[1], vector[2], 0);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4)::
~FLOATNAME(LVecBase4)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::zero Named Constructor
// Access: Published
@ -214,7 +153,7 @@ operator [](int i) {
// Access: Published, Static
// Description: Returns 4: the number of components of a LVecBase4.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase4)::
CONSTEXPR int FLOATNAME(LVecBase4)::
size() {
return 4;
}
@ -286,6 +225,26 @@ get_w() const {
return _v(3);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::get_xyz
// Access: Published
// Description: Returns the x, y and z component of this vector
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LVecBase4)::
get_xyz() const {
return FLOATNAME(LVecBase3)(_v(0), _v(1), _v(2));
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::get_xy
// Access: Published
// Description: Returns the x and y component of this vector
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LVecBase4)::
get_xy() const {
return FLOATNAME(LVecBase2)(_v(0), _v(1));
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::set_cell
// Access: Published
@ -405,8 +364,8 @@ get_data() const {
// Access: Published
// Description: Returns the number of elements in the vector, four.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(LVecBase4)::
get_num_components() const {
CONSTEXPR int FLOATNAME(LVecBase4)::
get_num_components() {
return 4;
}
@ -559,6 +518,22 @@ normalize() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
normalized() const {
FLOATTYPE l2 = length_squared();
if (l2 == (FLOATTYPE)0.0f) {
return FLOATNAME(LVecBase4)(0.0f);
}
return (*this) / csqrt(l2);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::project
// Access: Published
@ -1107,15 +1082,6 @@ read_datagram(DatagramIterator &source) {
#endif
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)::
FLOATNAME(UnalignedLVecBase4)() {
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Copy Constructor
// Access: Public
@ -1126,38 +1092,6 @@ FLOATNAME(UnalignedLVecBase4)(const FLOATNAME(LVecBase4) &copy) {
set(copy[0], copy[1], copy[2], copy[3]);
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)::
FLOATNAME(UnalignedLVecBase4)(const FLOATNAME(UnalignedLVecBase4) &copy) : _v(copy._v) {
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &FLOATNAME(UnalignedLVecBase4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
set(copy[0], copy[1], copy[2], copy[3]);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &FLOATNAME(UnalignedLVecBase4)::
operator = (const FLOATNAME(UnalignedLVecBase4) &copy) {
TAU_PROFILE("void UnalignedLVecBase4::operator =(UnalignedLVecBase4 &)", " ", TAU_USER);
_v = copy._v;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: UnalignedLVecBase4::Constructor
// Access: Public
@ -1210,7 +1144,7 @@ operator [](int i) {
// Access: Public, Static
// Description: Returns 4: the number of components of a LVecBase4.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(UnalignedLVecBase4)::
CONSTEXPR int FLOATNAME(UnalignedLVecBase4)::
size() {
return 4;
}
@ -1232,7 +1166,7 @@ get_data() const {
// Access: Public
// Description: Returns the number of elements in the vector, 4.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH int FLOATNAME(UnalignedLVecBase4)::
get_num_components() const {
CONSTEXPR int FLOATNAME(UnalignedLVecBase4)::
get_num_components() {
return 4;
}

View File

@ -39,14 +39,10 @@ PUBLISHED:
#endif
};
INLINE_LINMATH FLOATNAME(LVecBase4)();
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(UnalignedLVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVecBase4) &operator = (const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVecBase4) &operator = (const FLOATNAME(UnalignedLVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVecBase4) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase4)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVecBase4)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVecBase4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(UnalignedLVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase3) &copy, FLOATTYPE w);
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LPoint3) &point);
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVector3) &vector);
@ -58,30 +54,39 @@ PUBLISHED:
INLINE_LINMATH static const FLOATNAME(LVecBase4) &unit_z();
INLINE_LINMATH static const FLOATNAME(LVecBase4) &unit_w();
INLINE_LINMATH ~FLOATNAME(LVecBase4)();
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);
INLINE_LINMATH static int size();
CONSTEXPR static int size();
INLINE_LINMATH bool is_nan() const;
INLINE_LINMATH FLOATTYPE get_cell(int i) const;
INLINE_LINMATH void set_cell(int i, FLOATTYPE value);
INLINE_LINMATH FLOATTYPE get_x() const;
INLINE_LINMATH FLOATTYPE get_y() const;
INLINE_LINMATH FLOATTYPE get_z() const;
INLINE_LINMATH FLOATTYPE get_w() const;
INLINE_LINMATH void set_cell(int i, FLOATTYPE value);
INLINE_LINMATH FLOATNAME(LVecBase3) get_xyz() const;
INLINE_LINMATH FLOATNAME(LVecBase2) get_xy() const;
INLINE_LINMATH void set_x(FLOATTYPE value);
INLINE_LINMATH void set_y(FLOATTYPE value);
INLINE_LINMATH void set_z(FLOATTYPE value);
INLINE_LINMATH void set_w(FLOATTYPE value);
PUBLISHED:
MAKE_PROPERTY(x, get_x, set_x);
MAKE_PROPERTY(y, get_y, set_y);
MAKE_PROPERTY(z, get_z, set_z);
MAKE_PROPERTY(xy, get_xy);
MAKE_PROPERTY(xyz, get_xyz);
// These next functions add to an existing value.
// i.e. foo.set_x(foo.get_x() + value)
// These are useful to reduce overhead in scripting
@ -93,7 +98,7 @@ PUBLISHED:
INLINE_LINMATH void add_w(FLOATTYPE value);
INLINE_LINMATH const FLOATTYPE *get_data() const;
INLINE_LINMATH int get_num_components() const;
CONSTEXPR static int get_num_components();
INLINE_LINMATH void extract_data(float*){};
public:
@ -113,6 +118,7 @@ PUBLISHED:
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATTYPE length() const;
INLINE_LINMATH bool normalize();
INLINE_LINMATH FLOATNAME(LVecBase4) normalized() const;
INLINE_LINMATH FLOATNAME(LVecBase4) project(const FLOATNAME(LVecBase4) &onto) const;
#endif
@ -223,21 +229,18 @@ PUBLISHED:
#endif
};
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)();
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)(const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)(const FLOATNAME(UnalignedLVecBase4) &copy);
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &operator = (const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &operator = (const FLOATNAME(UnalignedLVecBase4) &copy);
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
INLINE_LINMATH void set(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
INLINE_LINMATH FLOATTYPE operator [](int i) const;
INLINE_LINMATH FLOATTYPE &operator [](int i);
INLINE_LINMATH static int size();
CONSTEXPR static int size();
INLINE_LINMATH const FLOATTYPE *get_data() const;
INLINE_LINMATH int get_num_components() const;
CONSTEXPR static int get_num_components();
public:
typedef FLOATTYPE numeric_type;

View File

@ -12,50 +12,23 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVector2::Default Constructor
// Function: LVector2::Constructor
// Access: Public
// Description:
// Description: Constructs a new LVector2 from a LVecBase2
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2)::
FLOATNAME(LVector2)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2)::
FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) &copy) : FLOATNAME(LVecBase2)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2) &FLOATNAME(LVector2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
FLOATNAME(LVecBase2)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::Copy Fill Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2) &FLOATNAME(LVector2)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase2)::operator = (fill_value);
return *this;
FLOATNAME(LVector2)(const FLOATNAME(LVecBase2)& copy) :
FLOATNAME(LVecBase2)(copy)
{
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::Constructor
// Access: Public
// Description:
// Description: Constructs a new LVector2 with all components set
// to the fill value.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2)::
FLOATNAME(LVector2)(FLOATTYPE fill_value) :
@ -175,6 +148,18 @@ operator / (FLOATTYPE scalar) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LVector2::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector2) FLOATNAME(LVector2)::
normalized() const {
return FLOATNAME(LVecBase2)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::project
// Access: Published

View File

@ -18,10 +18,9 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LVector2) : public FLOATNAME(LVecBase2) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector2)();
INLINE_LINMATH FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LVector2) &operator = (const FLOATNAME(LVecBase2) &copy);
INLINE_LINMATH FLOATNAME(LVector2) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector2)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVector2)(const FLOATNAME(LVecBase2)& copy);
INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE x, FLOATTYPE y);
@ -44,6 +43,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector2) operator / (FLOATTYPE scalar) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LVector2) normalized() const;
INLINE_LINMATH FLOATNAME(LVector2) project(const FLOATNAME(LVecBase2) &onto) const;
INLINE_LINMATH FLOATTYPE signed_angle_rad(const FLOATNAME(LVector2) &other) const;
INLINE_LINMATH FLOATTYPE signed_angle_deg(const FLOATNAME(LVector2) &other) const;

View File

@ -13,15 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVector3::Default Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector3)::
FLOATNAME(LVector3)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::Copy Constructor
// Access: Published
@ -31,27 +22,6 @@ INLINE_LINMATH FLOATNAME(LVector3)::
FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) &copy) : FLOATNAME(LVecBase3)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector3) &FLOATNAME(LVector3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
FLOATNAME(LVecBase3)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::Copy Fill Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector3) &FLOATNAME(LVector3)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase3)::operator = (fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::Constructor
@ -220,6 +190,19 @@ cross(const FLOATNAME(LVecBase3) &other) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LVector3::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector3) FLOATNAME(LVector3)::
normalized() const {
return FLOATNAME(LVecBase3)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::project
// Access: Published

View File

@ -24,10 +24,8 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LVector3) : public FLOATNAME(LVecBase3) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector3)();
INLINE_LINMATH FLOATNAME(LVector3)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LVector3) &operator = (const FLOATNAME(LVecBase3) &copy);
INLINE_LINMATH FLOATNAME(LVector3) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
INLINE_LINMATH FLOATNAME(LVector3)(const FLOATNAME(LVecBase2) &copy, FLOATTYPE z);
@ -55,6 +53,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector3) cross(const FLOATNAME(LVecBase3) &other) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LVector3) normalized() const;
INLINE_LINMATH FLOATNAME(LVector3) project(const FLOATNAME(LVecBase3) &onto) const;
INLINE_LINMATH FLOATTYPE angle_rad(const FLOATNAME(LVector3) &other) const;
INLINE_LINMATH FLOATTYPE angle_deg(const FLOATNAME(LVector3) &other) const;

View File

@ -13,15 +13,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LVector4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector4)::
FLOATNAME(LVector4)() {
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::Copy Constructor
// Access: Public
@ -31,28 +22,6 @@ INLINE_LINMATH FLOATNAME(LVector4)::
FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) &copy) : FLOATNAME(LVecBase4)(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector4) &FLOATNAME(LVector4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
FLOATNAME(LVecBase4)::operator = (copy);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::Copy Fill Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector4) &FLOATNAME(LVector4)::
operator = (FLOATTYPE fill_value) {
FLOATNAME(LVecBase4)::operator = (fill_value);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::Constructor
// Access: Public
@ -207,6 +176,19 @@ operator / (FLOATTYPE scalar) const {
}
#ifndef FLOATTYPE_IS_INT
////////////////////////////////////////////////////////////////////
// Function: LVector4::normalized
// Access: Published
// Description: Normalizes the vector and returns the normalized
// vector as a copy. If the vector was a zero-length
// vector, a zero length vector will be returned.
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVector4) FLOATNAME(LVector4)::
normalized() const {
return FLOATNAME(LVecBase4)::normalized();
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::project
// Access: Published

View File

@ -18,10 +18,8 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_LINMATH FLOATNAME(LVector4) : public FLOATNAME(LVecBase4) {
PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector4)();
INLINE_LINMATH FLOATNAME(LVector4)() DEFAULT_CTOR;
INLINE_LINMATH FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVector4) &operator = (const FLOATNAME(LVecBase4) &copy);
INLINE_LINMATH FLOATNAME(LVector4) &operator = (FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE fill_value);
INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
INLINE_LINMATH FLOATNAME(LVector4)(const FLOATNAME(LVecBase3) &copy, FLOATTYPE w);
@ -47,6 +45,7 @@ PUBLISHED:
INLINE_LINMATH FLOATNAME(LVector4) operator / (FLOATTYPE scalar) const;
#ifndef FLOATTYPE_IS_INT
INLINE_LINMATH FLOATNAME(LVector4) normalized() const;
INLINE_LINMATH FLOATNAME(LVector4) project(const FLOATNAME(LVecBase4) &onto) const;
#endif

View File

@ -960,12 +960,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the off planes pointers if any
Planes::const_iterator fi;
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
NodePath plane = (*fi);
// Since we can't write out a NodePath, we write out just the
// plain PandaNode. The user can use the AttribNodeRegistry on
// re-read if there is any ambiguity that needs to be resolved.
manager->write_pointer(dg, plane.node());
(*fi).write_datagram(manager, dg);
}
// write the number of on planes
@ -973,8 +968,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the on planes pointers if any
Planes::const_iterator nti;
for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
NodePath plane = (*nti);
manager->write_pointer(dg, plane.node());
(*nti).write_datagram(manager, dg);
}
}
@ -990,38 +984,62 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderAttrib::complete_pointers(p_list, manager);
AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
Planes::iterator ci = _off_planes.begin();
while (ci != _off_planes.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
// We go through some effort to look up the node in the registry
// without creating a NodePath around it first (which would up,
// and then down, the reference count, possibly deleting the
// node).
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < _off_planes.size(); ++i) {
pi += _off_planes[i].complete_pointers(p_list + pi, manager);
int n = areg->find_node(_off_planes[i]);
if (n != -1) {
// If it's in the registry, replace it.
_off_planes[i] = areg->get_node(n);
}
}
for (int i = 0; i < _on_planes.size(); ++i) {
pi += _on_planes[i].complete_pointers(p_list + pi, manager);
int n = areg->find_node(_on_planes[i]);
if (n != -1) {
// If it's in the registry, replace it.
_on_planes[i] = areg->get_node(n);
}
}
} else {
Planes::iterator ci = _off_planes.begin();
while (ci != _off_planes.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
// We go through some effort to look up the node in the registry
// without creating a NodePath around it first (which would up,
// and then down, the reference count, possibly deleting the
// node).
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
}
++ci;
}
ci = _on_planes.begin();
while (ci != _on_planes.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
}
++ci;
}
++ci;
}
_off_planes.sort();
ci = _on_planes.begin();
while (ci != _on_planes.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
}
++ci;
}
_on_planes.sort();
return pi;
@ -1073,31 +1091,28 @@ void ClipPlaneAttrib::
fillin(DatagramIterator &scan, BamReader *manager) {
RenderAttrib::fillin(scan, manager);
// We cheat a little bit here. In the middle of bam version 4.10,
// we completely redefined the bam storage definition for
// ClipPlaneAttribs, without bothering to up the bam version or even to
// attempt to read the old definition. We get away with this,
// knowing that the egg loader doesn't create ClipPlaneAttribs, and
// hence no old bam files have the old definition for ClipPlaneAttrib
// within them.
_off_all_planes = scan.get_bool();
int num_off_planes = scan.get_uint16();
// Push back an empty NodePath for each off Plane for now, until we
// get the actual list of pointers later in complete_pointers().
_off_planes.reserve(num_off_planes);
int i;
for (i = 0; i < num_off_planes; i++) {
manager->read_pointer(scan);
_off_planes.push_back(NodePath());
_off_planes.resize(num_off_planes);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < num_off_planes; i++) {
_off_planes[i].fillin(scan, manager);
}
} else {
manager->read_pointers(scan, num_off_planes);
}
int num_on_planes = scan.get_uint16();
_on_planes.reserve(num_on_planes);
for (i = 0; i < num_on_planes; i++) {
manager->read_pointer(scan);
_on_planes.push_back(NodePath());
_on_planes.resize(num_on_planes);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < num_on_planes; i++) {
manager->read_pointer(scan);
}
} else {
manager->read_pointers(scan, num_on_planes);
}
}

View File

@ -45,7 +45,9 @@ CData(const Light::CData &copy) :
////////////////////////////////////////////////////////////////////
INLINE Light::
Light() :
_priority(0)
_priority(0),
_has_color_temperature(true),
_color_temperature(6500)
{
}
@ -57,6 +59,8 @@ Light() :
INLINE Light::
Light(const Light &copy) :
_priority(copy._priority),
_has_color_temperature(copy._has_color_temperature),
_color_temperature(copy._color_temperature),
_cycler(copy._cycler)
{
}
@ -81,9 +85,34 @@ INLINE void Light::
set_color(const LColor &color) {
CDWriter cdata(_cycler);
cdata->_color = color;
_has_color_temperature = false;
mark_viz_stale();
}
////////////////////////////////////////////////////////////////////
// Function: Light::has_color_temperature
// Access: Published
// Description: Returns true if the color was specified as a
// temperature in kelvins, and get_color_temperature
// is defined.
////////////////////////////////////////////////////////////////////
INLINE bool Light::
has_color_temperature() const {
return _has_color_temperature;
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_color_temperature
// Access: Published
// Description: Returns the basic color temperature of the light,
// assuming has_color_temperature() returns true.
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat Light::
get_color_temperature() const {
nassertr(_has_color_temperature, _color_temperature);
return _color_temperature;
}
////////////////////////////////////////////////////////////////////
// Function: Light::set_priority
// Access: Published

View File

@ -76,6 +76,70 @@ is_ambient_light() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: Light::set_color_temperature
// Access: Published
// Description: Sets the color temperature of the light in kelvins.
// This will recalculate the light's color.
//
// The default value is 6500 K, corresponding to a
// perfectly white light assuming a D65 white point.
////////////////////////////////////////////////////////////////////
void Light::
set_color_temperature(PN_stdfloat temperature) {
if (_has_color_temperature && _color_temperature == temperature) {
return;
}
_has_color_temperature = true;
_color_temperature = temperature;
// Recalculate the color.
PN_stdfloat x, y;
if (temperature == 6500) {
// sRGB D65 white point.
x = 0.31271;
y = 0.32902;
} else {
PN_stdfloat mm = 1000.0 / temperature;
PN_stdfloat mm2 = mm * mm;
PN_stdfloat mm3 = mm2 * mm;
if (temperature < 4000) {
x = -0.2661239 * mm3 - 0.2343580 * mm2 + 0.8776956 * mm + 0.179910;
} else {
x = -3.0258469 * mm3 + 2.1070379 * mm2 + 0.2226347 * mm + 0.240390;
}
PN_stdfloat x2 = x * x;
PN_stdfloat x3 = x2 * x;
if (temperature < 2222) {
y = -1.1063814 * x3 - 1.34811020 * x2 + 2.18555832 * x - 0.20219683;
} else if (temperature < 4000) {
y = -0.9549476 * x3 - 1.37418593 * x2 + 2.09137015 * x - 0.16748867;
} else {
y = 3.0817580 * x3 - 5.87338670 * x2 + 3.75112997 * x - 0.37001483;
}
}
// xyY to XYZ, assuming Y=1.
LVecBase3 xyz(x / y, 1, (1 - x - y) / y);
// Convert XYZ to linearized sRGB.
const static LMatrix3 xyz_to_rgb(
3.2406255, -0.9689307, 0.0557101,
-1.537208, 1.8757561, -0.2040211,
-0.4986286, 0.0415175, 1.0569959);
LColor color(xyz_to_rgb.xform(xyz), 1);
CDWriter cdata(_cycler);
cdata->_color = color;
mark_viz_stale();
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_exponent
// Access: Public, Virtual
@ -175,7 +239,12 @@ fill_viz_geom(GeomNode *) {
////////////////////////////////////////////////////////////////////
void Light::
write_datagram(BamWriter *manager, Datagram &dg) {
manager->write_cdata(dg, _cycler);
dg.add_bool(_has_color_temperature);
if (_has_color_temperature) {
dg.add_stdfloat(_color_temperature);
} else {
manager->write_cdata(dg, _cycler);
}
dg.add_int32(_priority);
}
@ -188,6 +257,15 @@ write_datagram(BamWriter *manager, Datagram &dg) {
////////////////////////////////////////////////////////////////////
void Light::
fillin(DatagramIterator &scan, BamReader *manager) {
manager->read_cdata(scan, _cycler);
if (manager->get_file_minor_ver() >= 39) {
_has_color_temperature = scan.get_bool();
} else {
_has_color_temperature = false;
}
if (_has_color_temperature) {
set_color_temperature(scan.get_stdfloat());
} else {
manager->read_cdata(scan, _cycler);
}
_priority = scan.get_int32();
}

View File

@ -52,6 +52,12 @@ PUBLISHED:
INLINE void set_color(const LColor &color);
MAKE_PROPERTY(color, get_color, set_color);
INLINE bool has_color_temperature() const;
INLINE PN_stdfloat get_color_temperature() const;
void set_color_temperature(PN_stdfloat temperature);
MAKE_PROPERTY(color_temperature, get_color_temperature,
set_color_temperature);
virtual PN_stdfloat get_exponent() const;
virtual const LColor &get_specular_color() const;
virtual const LVecBase3 &get_attenuation() const;
@ -98,6 +104,11 @@ private:
int _priority;
static UpdateSeq _sort_seq;
// The color temperature is not cycled either, because we only need
// to pass down the computed color anyway.
bool _has_color_temperature;
PN_stdfloat _color_temperature;
// This is the data that must be cycled between pipeline stages.
class EXPCL_PANDA_PGRAPH CData : public CycleData {
public:

View File

@ -990,12 +990,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the off lights pointers if any
Lights::const_iterator fi;
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
NodePath light = (*fi);
// Since we can't write out a NodePath, we write out just the
// plain PandaNode. The user can use the AttribNodeRegistry on
// re-read if there is any ambiguity that needs to be resolved.
manager->write_pointer(dg, light.node());
(*fi).write_datagram(manager, dg);
}
// write the number of on lights
@ -1003,8 +998,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the on lights pointers if any
Lights::const_iterator nti;
for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) {
NodePath light = (*nti);
manager->write_pointer(dg, light.node());
(*nti).write_datagram(manager, dg);
}
}
@ -1019,22 +1013,33 @@ int LightAttrib::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderAttrib::complete_pointers(p_list, manager);
BamAuxData *aux = (BamAuxData *)manager->get_aux_data(this, "lights");
nassertr(aux != NULL, pi);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < _off_lights.size(); ++i) {
pi += _off_lights[i].complete_pointers(p_list + pi, manager);
}
int i;
aux->_off_list.reserve(aux->_num_off_lights);
for (i = 0; i < aux->_num_off_lights; ++i) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
aux->_off_list.push_back(node);
}
for (int i = 0; i < _on_lights.size(); ++i) {
pi += _on_lights[i].complete_pointers(p_list + pi, manager);
}
aux->_on_list.reserve(aux->_num_on_lights);
for (i = 0; i < aux->_num_on_lights; ++i) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
aux->_on_list.push_back(node);
} else {
BamAuxData *aux = (BamAuxData *)manager->get_aux_data(this, "lights");
nassertr(aux != NULL, pi);
int i;
aux->_off_list.reserve(aux->_num_off_lights);
for (i = 0; i < aux->_num_off_lights; ++i) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
aux->_off_list.push_back(node);
}
aux->_on_list.reserve(aux->_num_on_lights);
for (i = 0; i < aux->_num_on_lights; ++i) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
aux->_on_list.push_back(node);
}
}
return pi;
@ -1049,43 +1054,68 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
////////////////////////////////////////////////////////////////////
void LightAttrib::
finalize(BamReader *manager) {
// Now it's safe to convert our saved PandaNodes into NodePaths.
BamAuxData *aux = (BamAuxData *)manager->get_aux_data(this, "lights");
nassertv(aux != NULL);
nassertv(aux->_num_off_lights == (int)aux->_off_list.size());
nassertv(aux->_num_on_lights == (int)aux->_on_list.size());
if (manager->get_file_minor_ver() >= 40) {
AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
// Check if any of the nodes we loaded are mentioned in the
// AttribNodeRegistry. If so, replace them.
for (int i = 0; i < _off_lights.size(); ++i) {
int n = areg->find_node(_off_lights[i]);
if (n != -1) {
// If it's in the registry, replace it.
_off_lights[i] = areg->get_node(n);
}
}
_off_lights.reserve(aux->_off_list.size());
NodeList::iterator ni;
for (ni = aux->_off_list.begin(); ni != aux->_off_list.end(); ++ni) {
PandaNode *node = (*ni);
int n = areg->find_node(node->get_type(), node->get_name());
if (n != -1) {
// If it's in the registry, add that NodePath.
_off_lights.push_back(areg->get_node(n));
} else {
// Otherwise, add any arbitrary NodePath. Complain if it's
// ambiguous.
_off_lights.push_back(NodePath(node));
for (int i = 0; i < _on_lights.size(); ++i) {
int n = areg->find_node(_on_lights[i]);
if (n != -1) {
// If it's in the registry, replace it.
_on_lights[i] = areg->get_node(n);
}
}
} else {
// Now it's safe to convert our saved PandaNodes into NodePaths.
BamAuxData *aux = (BamAuxData *)manager->get_aux_data(this, "lights");
nassertv(aux != NULL);
nassertv(aux->_num_off_lights == (int)aux->_off_list.size());
nassertv(aux->_num_on_lights == (int)aux->_on_list.size());
AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
_off_lights.reserve(aux->_off_list.size());
NodeList::iterator ni;
for (ni = aux->_off_list.begin(); ni != aux->_off_list.end(); ++ni) {
PandaNode *node = (*ni);
int n = areg->find_node(node->get_type(), node->get_name());
if (n != -1) {
// If it's in the registry, add that NodePath.
_off_lights.push_back(areg->get_node(n));
} else {
// Otherwise, add any arbitrary NodePath. Complain if it's
// ambiguous.
_off_lights.push_back(NodePath(node));
}
}
_on_lights.reserve(aux->_on_list.size());
for (ni = aux->_on_list.begin(); ni != aux->_on_list.end(); ++ni) {
PandaNode *node = (*ni);
int n = areg->find_node(node->get_type(), node->get_name());
if (n != -1) {
// If it's in the registry, add that NodePath.
_on_lights.push_back(areg->get_node(n));
} else {
// Otherwise, add any arbitrary NodePath. Complain if it's
// ambiguous.
_on_lights.push_back(NodePath(node));
}
}
}
// Now that the NodePaths have been filled in, we can sort the list.
_off_lights.sort();
_on_lights.reserve(aux->_on_list.size());
for (ni = aux->_on_list.begin(); ni != aux->_on_list.end(); ++ni) {
PandaNode *node = (*ni);
int n = areg->find_node(node->get_type(), node->get_name());
if (n != -1) {
// If it's in the registry, add that NodePath.
_on_lights.push_back(areg->get_node(n));
} else {
// Otherwise, add any arbitrary NodePath. Complain if it's
// ambiguous.
_on_lights.push_back(NodePath(node));
}
}
_on_lights.sort();
}
@ -1124,12 +1154,24 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_off_all_lights = scan.get_bool();
BamAuxData *aux = new BamAuxData;
manager->set_aux_data(this, "lights", aux);
if (manager->get_file_minor_ver() >= 40) {
_off_lights.resize(scan.get_uint16());
for (int i = 0; i < _off_lights.size(); ++i) {
_off_lights[i].fillin(scan, manager);
}
aux->_num_off_lights = scan.get_uint16();
manager->read_pointers(scan, aux->_num_off_lights);
aux->_num_on_lights = scan.get_uint16();
manager->read_pointers(scan, aux->_num_on_lights);
_on_lights.resize(scan.get_uint16());
for (int i = 0; i < _on_lights.size(); ++i) {
_on_lights[i].fillin(scan, manager);
}
} else {
BamAuxData *aux = new BamAuxData;
manager->set_aux_data(this, "lights", aux);
aux->_num_off_lights = scan.get_uint16();
manager->read_pointers(scan, aux->_num_off_lights);
aux->_num_on_lights = scan.get_uint16();
manager->read_pointers(scan, aux->_num_on_lights);
}
}

View File

@ -357,7 +357,7 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
if (result != (PandaNode *)NULL) {
if (record != (BamCacheRecord *)NULL) {
// Store the loaded model in the model cache.
record->set_data(result, result);
record->set_data(result);
cache->store(record);
}

View File

@ -6345,6 +6345,10 @@ write_bam_file(const Filename &filename) const {
bool okflag = false;
if (bam_file.open_write(filename)) {
// Tell the BamWriter which node is the root node, for making
// NodePaths relative to when writing them out to the file.
bam_file.get_writer()->set_root_node(node());
if (bam_file.write_object(node())) {
okflag = true;
}
@ -6368,6 +6372,10 @@ write_bam_stream(ostream &out) const {
bool okflag = false;
if (bam_file.open_write(out)) {
// Tell the BamWriter which node is the root node, for making
// NodePaths relative to when writing them out to the file.
bam_file.get_writer()->set_root_node(node());
if (bam_file.write_object(node())) {
okflag = true;
}
@ -6434,6 +6442,10 @@ encode_to_bam_stream(string &data, BamWriter *writer) const {
num_nodes = 1;
}
// Tell the BamWriter which node is the root node, for making
// NodePaths relative to when writing them out to the file.
writer->set_root_node(node());
// Write an initial Datagram to represent the error type and
// number of nodes.
Datagram dg;
@ -7451,3 +7463,125 @@ r_find_all_materials(PandaNode *node, const RenderState *state,
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::write_datagram
// Access: Public
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void NodePath::
write_datagram(BamWriter *manager, Datagram &dg) const {
PandaNode *root = DCAST(PandaNode, manager->get_root_node());
// We have no root node to measure from.
if (root == (PandaNode *)NULL || root == node()) {
manager->write_pointer(dg, node());
manager->write_pointer(dg, NULL);
return;
}
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
// Record the chain of nodes from the root to this node.
pvector<PandaNode *> path;
NodePathComponent *comp = _head;
while (comp != NULL) {
PandaNode *node = comp->get_node();
path.push_back(node);
if (node == root) {
break;
}
comp = comp->get_next(pipeline_stage, current_thread);
}
if (comp == (NodePathComponent *)NULL) {
// We did not encounter the root node. Not much we can do.
manager->write_pointer(dg, node());
manager->write_pointer(dg, NULL);
return;
}
// Write out the nodes in reverse order, for fast reconstructing.
for (int i = path.size() - 1; i >= 0; --i) {
manager->write_pointer(dg, path[i]);
}
manager->write_pointer(dg, NULL);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::complete_pointers
// Access: Public
// Description: Receives an array of pointers, one for each time
// manager->read_pointer() was called in fillin().
// Returns the number of pointers processed.
////////////////////////////////////////////////////////////////////
int NodePath::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = 0;
PT(PandaNode) node = DCAST(PandaNode, p_list[pi++]);
if (node.is_null()) {
// An empty NodePath.
_head = (NodePathComponent *)NULL;
return pi;
}
Thread *current_thread = Thread::get_current_thread();
int pipeline_stage = current_thread->get_pipeline_stage();
// Take an arbitrary path to the root of the NodePath. This probably
// won't be ambiguous, as this is usually the root of the model or scene
// we are currently loading.
PT(NodePathComponent) comp = node->get_generic_component(false, pipeline_stage, current_thread);
nassertd(!comp.is_null()) {
while (p_list[pi++]) {}
return pi;
}
// Build up the chain of NodePathComponents leading up to this node.
while (p_list[pi] != NULL) {
PT(PandaNode) node = DCAST(PandaNode, p_list[pi++]);
LightReMutexHolder holder(node->_paths_lock);
// First, walk through the list of NodePathComponents we already
// have on the child, looking for one that already exists,
// referencing the indicated parent component.
PandaNode::Paths::const_iterator it;
for (it = node->_paths.begin(); it != node->_paths.end(); ++it) {
if ((*it)->get_next(pipeline_stage, current_thread) == comp) {
// If we already have such a component, use that.
comp = (*it);
break;
}
}
if (it == node->_paths.end()) {
// We don't already have a NodePathComponent referring to this
// parent-child relationship. Create a new one. Note that we can't
// verify that they are actually related because we may not have
// completed the node's pointers yet, so we trust that the .bam is right.
comp = new NodePathComponent(node, comp, pipeline_stage, current_thread);
node->_paths.insert(comp);
}
}
// One more for the final NULL node.
++pi;
_head = comp;
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new NodePath.
////////////////////////////////////////////////////////////////////
void NodePath::
fillin(DatagramIterator &scan, BamReader *manager) {
while(manager->read_pointer(scan)) {};
}

View File

@ -994,6 +994,11 @@ private:
static PStatCollector _get_transform_pcollector;
static PStatCollector _verify_complete_pcollector;
public:
void write_datagram(BamWriter *manager, Datagram &dg) const;
int complete_pointers(TypedWritable **plist, BamReader *manager);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -129,6 +129,7 @@ public:
private:
static TypeHandle _type_handle;
friend class PandaNode;
friend class NodePath;
};
INLINE ostream &operator << (ostream &out, const NodePathComponent &comp);

View File

@ -169,8 +169,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the on occluders pointers if any
Occluders::const_iterator nti;
for (nti = _on_occluders.begin(); nti != _on_occluders.end(); ++nti) {
NodePath occluder = (*nti);
manager->write_pointer(dg, occluder.node());
(*nti).write_datagram(manager, dg);
}
}
@ -186,19 +185,32 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderEffect::complete_pointers(p_list, manager);
AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
Occluders::iterator ci;
ci = _on_occluders.begin();
while (ci != _on_occluders.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < _on_occluders.size(); ++i) {
pi += _on_occluders[i].complete_pointers(p_list + pi, manager);
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
int n = areg->find_node(_on_occluders[i]);
if (n != -1) {
// If it's in the registry, replace it.
_on_occluders[i] = areg->get_node(n);
}
}
} else {
Occluders::iterator ci;
ci = _on_occluders.begin();
while (ci != _on_occluders.end()) {
PandaNode *node;
DCAST_INTO_R(node, p_list[pi++], pi);
int ni = areg->find_node(node->get_type(), node->get_name());
if (ni != -1) {
(*ci) = areg->get_node(ni);
} else {
(*ci) = NodePath(node);
}
++ci;
}
++ci;
}
_on_occluders.sort();
@ -250,13 +262,16 @@ make_from_bam(const FactoryParams &params) {
void OccluderEffect::
fillin(DatagramIterator &scan, BamReader *manager) {
RenderEffect::fillin(scan, manager);
// Push back an empty NodePath for each Occluder for now, until we
// get the actual list of pointers later in complete_pointers().
int num_on_occluders = scan.get_uint16();
_on_occluders.reserve(num_on_occluders);
for (int i = 0; i < num_on_occluders; i++) {
manager->read_pointer(scan);
_on_occluders.push_back(NodePath());
_on_occluders.resize(num_on_occluders);
if (manager->get_file_minor_ver() >= 40) {
for (int i = 0; i < num_on_occluders; i++) {
_on_occluders[i].fillin(scan, manager);
}
} else {
manager->read_pointers(scan, num_on_occluders);
}
}

View File

@ -48,15 +48,7 @@ register_with_read_factory() {
void ParamNodePath::
write_datagram(BamWriter *manager, Datagram &dg) {
ParamValueBase::write_datagram(manager, dg);
// We can't store a NodePath, so we store a pointer to the
// underlying node, and pray that there is an unambiguous path
// from the root to it.
if (_node_path.is_empty()) {
manager->write_pointer(dg, NULL);
} else {
manager->write_pointer(dg, _node_path.node());
}
_node_path.write_datagram(manager, dg);
}
////////////////////////////////////////////////////////////////////
@ -69,7 +61,12 @@ write_datagram(BamWriter *manager, Datagram &dg) {
int ParamNodePath::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = ParamValueBase::complete_pointers(p_list, manager);
_node_path = NodePath(DCAST(PandaNode, p_list[pi++]));
if (manager->get_file_minor_ver() >= 40) {
pi += _node_path.complete_pointers(p_list + pi, manager);
} else {
_node_path = NodePath(DCAST(PandaNode, p_list[pi++]));
}
return pi;
}
@ -104,5 +101,10 @@ make_from_bam(const FactoryParams &params) {
void ParamNodePath::
fillin(DatagramIterator &scan, BamReader *manager) {
ParamValueBase::fillin(scan, manager);
manager->read_pointer(scan);
if (manager->get_file_minor_ver() >= 40) {
_node_path.fillin(scan, manager);
} else {
manager->read_pointer(scan);
}
}

View File

@ -43,12 +43,16 @@ CData(const DirectionalLight::CData &copy) :
// Function: DirectionalLight::get_specular_color
// Access: Public, Final
// Description: Returns the color of specular highlights generated by
// the light.
// the light. This is usually the same as get_color().
////////////////////////////////////////////////////////////////////
INLINE const LColor &DirectionalLight::
get_specular_color() const {
CDReader cdata(_cycler);
return cdata->_specular_color;
if (_has_specular_color) {
CDReader cdata(_cycler);
return cdata->_specular_color;
} else {
return get_color();
}
}
////////////////////////////////////////////////////////////////////
@ -60,9 +64,21 @@ get_specular_color() const {
INLINE void DirectionalLight::
set_specular_color(const LColor &color) {
CDWriter cdata(_cycler);
_has_specular_color = true;
cdata->_specular_color = color;
}
////////////////////////////////////////////////////////////////////
// Function: DirectionalLight::clear_specular_color
// Access: Public
// Description: Clears a custom specular color setting, meaning that
// the specular color will now come from the color.
////////////////////////////////////////////////////////////////////
INLINE void DirectionalLight::
clear_specular_color() {
_has_specular_color = false;
}
////////////////////////////////////////////////////////////////////
// Function: DirectionalLight::get_point
// Access: Public

Some files were not shown because too many files have changed in this diff Show More