Merge branch 'master' of https://github.com/panda3d/panda3d
This commit is contained in:
commit
bc58335214
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 '}'
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 << " **)";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ¢er);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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())) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ EggMaterial(const string &mref_name)
|
|||
EggMaterial::
|
||||
EggMaterial(const EggMaterial ©)
|
||||
: EggNode(copy),
|
||||
_base(copy._base),
|
||||
_diff(copy._diff),
|
||||
_amb(copy._amb),
|
||||
_emit(copy._emit),
|
||||
|
|
@ -46,6 +47,7 @@ EggMaterial(const EggMaterial ©)
|
|||
_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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -687,6 +687,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
|||
_glgsg->_glGetActiveUniform(_glsl_program, i, name_buflen, NULL, ¶m_size, ¶m_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ PT(Material) Material::_default;
|
|||
void Material::
|
||||
operator = (const Material ©) {
|
||||
Namable::operator = (copy);
|
||||
_base_color = copy._base_color;
|
||||
_ambient = copy._ambient;
|
||||
_diffuse = copy._diffuse;
|
||||
_specular = copy._specular;
|
||||
|
|
@ -38,9 +39,80 @@ operator = (const Material ©) {
|
|||
_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 ¶ms) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase2)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LPoint2::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LPoint2) &FLOATNAME(LPoint2)::
|
||||
operator = (const FLOATNAME(LVecBase2) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LPoint2) &operator = (const FLOATNAME(LVecBase2) ©);
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase3)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LPoint3::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LPoint3) &FLOATNAME(LPoint3)::
|
||||
operator = (const FLOATNAME(LVecBase3) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LPoint3) &operator = (const FLOATNAME(LVecBase3) ©);
|
||||
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) ©, 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase4)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LPoint4::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LPoint4) &FLOATNAME(LPoint4)::
|
||||
operator = (const FLOATNAME(LVecBase4) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LPoint4) &operator = (const FLOATNAME(LVecBase4) ©);
|
||||
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) ©, 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ©) : _v(copy._v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVecBase2::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2)::
|
||||
operator = (const FLOATNAME(LVecBase2) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -34,38 +34,38 @@ PUBLISHED:
|
|||
#endif
|
||||
};
|
||||
|
||||
INLINE_LINMATH FLOATNAME(LVecBase2)();
|
||||
INLINE_LINMATH FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase2) &operator = (const FLOATNAME(LVecBase2) ©);
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ©) : _v(copy._v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVecBase3::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3)::
|
||||
operator = (const FLOATNAME(LVecBase3) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -34,10 +34,7 @@ PUBLISHED:
|
|||
#endif
|
||||
};
|
||||
|
||||
INLINE_LINMATH FLOATNAME(LVecBase3)();
|
||||
INLINE_LINMATH FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase3) &operator = (const FLOATNAME(LVecBase3) ©);
|
||||
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) ©, 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ©) : _v(copy._v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVecBase4::Copy Constructor
|
||||
// Access: Public
|
||||
|
|
@ -41,40 +23,6 @@ FLOATNAME(LVecBase4)(const FLOATNAME(UnalignedLVecBase4) ©) {
|
|||
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) ©) {
|
||||
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) ©) {
|
||||
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) ©) {
|
|||
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) ©) : _v(copy._v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UnalignedLVecBase4::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &FLOATNAME(UnalignedLVecBase4)::
|
||||
operator = (const FLOATNAME(LVecBase4) ©) {
|
||||
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) ©) {
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,14 +39,10 @@ PUBLISHED:
|
|||
#endif
|
||||
};
|
||||
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4)();
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(UnalignedLVecBase4) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4) &operator = (const FLOATNAME(LVecBase4) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4) &operator = (const FLOATNAME(UnalignedLVecBase4) ©);
|
||||
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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase3) ©, 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) ©);
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4)(const FLOATNAME(UnalignedLVecBase4) ©);
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &operator = (const FLOATNAME(LVecBase4) ©);
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLVecBase4) &operator = (const FLOATNAME(UnalignedLVecBase4) ©);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase2)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVector2::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LVector2) &FLOATNAME(LVector2)::
|
||||
operator = (const FLOATNAME(LVecBase2) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVector2) &operator = (const FLOATNAME(LVecBase2) ©);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase3)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVector3::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LVector3) &FLOATNAME(LVector3)::
|
||||
operator = (const FLOATNAME(LVecBase3) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVector3) &operator = (const FLOATNAME(LVecBase3) ©);
|
||||
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) ©, 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;
|
||||
|
|
|
|||
|
|
@ -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) ©) : FLOATNAME(LVecBase4)(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVector4::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LVector4) &FLOATNAME(LVector4)::
|
||||
operator = (const FLOATNAME(LVecBase4) ©) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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) ©);
|
||||
INLINE_LINMATH FLOATNAME(LVector4) &operator = (const FLOATNAME(LVecBase4) ©);
|
||||
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) ©, 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ CData(const Light::CData ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Light::
|
||||
Light() :
|
||||
_priority(0)
|
||||
_priority(0),
|
||||
_has_color_temperature(true),
|
||||
_color_temperature(6500)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +59,8 @@ Light() :
|
|||
INLINE Light::
|
||||
Light(const Light ©) :
|
||||
_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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)) {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ public:
|
|||
private:
|
||||
static TypeHandle _type_handle;
|
||||
friend class PandaNode;
|
||||
friend class NodePath;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const NodePathComponent &comp);
|
||||
|
|
|
|||
|
|
@ -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 ¶ms) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ¶ms) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,16 @@ CData(const DirectionalLight::CData ©) :
|
|||
// 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
Loading…
Reference in New Issue