mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
57b66ebeaf
@ -23,7 +23,7 @@
|
||||
* parameter type accepts an arbitrary (or possibly fixed) number of nested
|
||||
* fields, all of which are of the same type.
|
||||
*/
|
||||
class DCArrayParameter : public DCParameter {
|
||||
class EXPCL_DIRECT_DCPARSER DCArrayParameter : public DCParameter {
|
||||
public:
|
||||
DCArrayParameter(DCParameter *element_type,
|
||||
const DCUnsignedIntRange &size = DCUnsignedIntRange());
|
||||
|
@ -27,7 +27,7 @@
|
||||
* This defines an interface to the Distributed Class, and is always
|
||||
* implemented as a remote procedure method.
|
||||
*/
|
||||
class DCAtomicField : public DCField {
|
||||
class EXPCL_DIRECT_DCPARSER DCAtomicField : public DCField {
|
||||
public:
|
||||
DCAtomicField(const std::string &name, DCClass *dclass, bool bogus_field);
|
||||
virtual ~DCAtomicField();
|
||||
|
@ -41,7 +41,7 @@ class DCParameter;
|
||||
/**
|
||||
* Defines a particular DistributedClass as read from an input .dc file.
|
||||
*/
|
||||
class DCClass : public DCDeclaration {
|
||||
class EXPCL_DIRECT_DCPARSER DCClass : public DCDeclaration {
|
||||
public:
|
||||
DCClass(DCFile *dc_file, const std::string &name,
|
||||
bool is_struct, bool bogus_class);
|
||||
|
@ -23,7 +23,7 @@ class DCClass;
|
||||
* This represents a class (or struct) object used as a parameter itself.
|
||||
* This means that all the fields of the class get packed into the message.
|
||||
*/
|
||||
class DCClassParameter : public DCParameter {
|
||||
class EXPCL_DIRECT_DCPARSER DCClassParameter : public DCParameter {
|
||||
public:
|
||||
DCClassParameter(const DCClass *dclass);
|
||||
DCClassParameter(const DCClassParameter ©);
|
||||
|
@ -26,7 +26,7 @@ class DCSwitch;
|
||||
* only purpose is so that classes and typedefs can be stored in one list
|
||||
* together so they can be ordered correctly on output.
|
||||
*/
|
||||
class DCDeclaration {
|
||||
class EXPCL_DIRECT_DCPARSER DCDeclaration {
|
||||
public:
|
||||
virtual ~DCDeclaration();
|
||||
|
||||
|
@ -34,7 +34,7 @@ class HashGenerator;
|
||||
/**
|
||||
* A single field of a Distributed Class, either atomic or molecular.
|
||||
*/
|
||||
class DCField : public DCPackerInterface, public DCKeywordList {
|
||||
class EXPCL_DIRECT_DCPARSER DCField : public DCPackerInterface, public DCKeywordList {
|
||||
public:
|
||||
DCField();
|
||||
DCField(const std::string &name, DCClass *dclass);
|
||||
|
@ -29,7 +29,7 @@ class DCDeclaration;
|
||||
* Represents the complete list of Distributed Class descriptions as read from
|
||||
* a .dc file.
|
||||
*/
|
||||
class DCFile {
|
||||
class EXPCL_DIRECT_DCPARSER DCFile {
|
||||
PUBLISHED:
|
||||
DCFile();
|
||||
~DCFile();
|
||||
|
@ -25,7 +25,7 @@ class HashGenerator;
|
||||
* define a communication property associated with a field, for instance
|
||||
* "broadcast" or "airecv".
|
||||
*/
|
||||
class DCKeyword : public DCDeclaration {
|
||||
class EXPCL_DIRECT_DCPARSER DCKeyword : public DCDeclaration {
|
||||
public:
|
||||
DCKeyword(const std::string &name, int historical_flag = ~0);
|
||||
virtual ~DCKeyword();
|
||||
|
@ -23,7 +23,7 @@ class HashGenerator;
|
||||
* This is a list of keywords (see DCKeyword) that may be set on a particular
|
||||
* field.
|
||||
*/
|
||||
class DCKeywordList {
|
||||
class EXPCL_DIRECT_DCPARSER DCKeywordList {
|
||||
public:
|
||||
DCKeywordList();
|
||||
DCKeywordList(const DCKeywordList ©);
|
||||
|
@ -25,7 +25,7 @@ class DCParameter;
|
||||
* This represents a combination of two or more related atomic fields, that
|
||||
* will often be treated as a unit.
|
||||
*/
|
||||
class DCMolecularField : public DCField {
|
||||
class EXPCL_DIRECT_DCPARSER DCMolecularField : public DCField {
|
||||
public:
|
||||
DCMolecularField(const std::string &name, DCClass *dclass);
|
||||
|
||||
|
@ -52,7 +52,7 @@ operator = (const DCNumericRange<NUM> ©) {
|
||||
* otherwise.
|
||||
*/
|
||||
template <class NUM>
|
||||
bool DCNumericRange<NUM>::
|
||||
INLINE bool DCNumericRange<NUM>::
|
||||
is_in_range(Number num) const {
|
||||
if (_ranges.empty()) {
|
||||
return true;
|
||||
@ -106,7 +106,7 @@ get_one_value() const {
|
||||
*
|
||||
*/
|
||||
template <class NUM>
|
||||
void DCNumericRange<NUM>::
|
||||
INLINE void DCNumericRange<NUM>::
|
||||
generate_hash(HashGenerator &hashgen) const {
|
||||
if (!_ranges.empty()) {
|
||||
hashgen.add_int(_ranges.size());
|
||||
@ -124,7 +124,7 @@ generate_hash(HashGenerator &hashgen) const {
|
||||
*
|
||||
*/
|
||||
template <class NUM>
|
||||
void DCNumericRange<NUM>::
|
||||
INLINE void DCNumericRange<NUM>::
|
||||
output(std::ostream &out, Number divisor) const {
|
||||
if (!_ranges.empty()) {
|
||||
typename Ranges::const_iterator ri;
|
||||
@ -144,7 +144,7 @@ output(std::ostream &out, Number divisor) const {
|
||||
* characters.
|
||||
*/
|
||||
template <class NUM>
|
||||
void DCNumericRange<NUM>::
|
||||
INLINE void DCNumericRange<NUM>::
|
||||
output_char(std::ostream &out, Number divisor) const {
|
||||
if (divisor != 1) {
|
||||
output(out, divisor);
|
||||
@ -179,7 +179,7 @@ clear() {
|
||||
* minmax overlaps an existing minmax.
|
||||
*/
|
||||
template <class NUM>
|
||||
bool DCNumericRange<NUM>::
|
||||
INLINE bool DCNumericRange<NUM>::
|
||||
add_range(Number min, Number max) {
|
||||
// Check for an overlap. This is probably indicative of a typo and should
|
||||
// be reported.
|
||||
|
@ -23,7 +23,7 @@
|
||||
* to constrain simple numeric types, as well as array sizes.
|
||||
*/
|
||||
template <class NUM>
|
||||
class DCNumericRange {
|
||||
class EXPCL_DIRECT_DCPARSER DCNumericRange {
|
||||
public:
|
||||
typedef NUM Number;
|
||||
|
||||
@ -32,20 +32,20 @@ public:
|
||||
INLINE DCNumericRange(const DCNumericRange ©);
|
||||
INLINE void operator = (const DCNumericRange ©);
|
||||
|
||||
bool is_in_range(Number num) const;
|
||||
INLINE bool is_in_range(Number num) const;
|
||||
INLINE void validate(Number num, bool &range_error) const;
|
||||
|
||||
INLINE bool has_one_value() const;
|
||||
INLINE Number get_one_value() const;
|
||||
|
||||
void generate_hash(HashGenerator &hashgen) const;
|
||||
INLINE void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
void output(std::ostream &out, Number divisor = 1) const;
|
||||
void output_char(std::ostream &out, Number divisor = 1) const;
|
||||
INLINE void output(std::ostream &out, Number divisor = 1) const;
|
||||
INLINE void output_char(std::ostream &out, Number divisor = 1) const;
|
||||
|
||||
public:
|
||||
INLINE void clear();
|
||||
bool add_range(Number min, Number max);
|
||||
INLINE bool add_range(Number min, Number max);
|
||||
|
||||
INLINE bool is_empty() const;
|
||||
INLINE int get_num_ranges() const;
|
||||
|
@ -19,7 +19,7 @@
|
||||
/**
|
||||
* This is a block of data that receives the results of DCPacker.
|
||||
*/
|
||||
class DCPackData {
|
||||
class EXPCL_DIRECT_DCPARSER DCPackData {
|
||||
PUBLISHED:
|
||||
INLINE DCPackData();
|
||||
INLINE ~DCPackData();
|
||||
|
@ -31,7 +31,7 @@ class DCSwitchParameter;
|
||||
* See also direct/src/doc/dcPacker.txt for a more complete description and
|
||||
* examples of using this class.
|
||||
*/
|
||||
class DCPacker {
|
||||
class EXPCL_DIRECT_DCPARSER DCPacker {
|
||||
PUBLISHED:
|
||||
DCPacker();
|
||||
~DCPacker();
|
||||
|
@ -26,7 +26,7 @@ class DCSwitchParameter;
|
||||
* requested from a particular field; its ownership is retained by the field
|
||||
* so it must not be deleted.
|
||||
*/
|
||||
class DCPackerCatalog {
|
||||
class EXPCL_DIRECT_DCPARSER DCPackerCatalog {
|
||||
private:
|
||||
DCPackerCatalog(const DCPackerInterface *root);
|
||||
DCPackerCatalog(const DCPackerCatalog ©);
|
||||
|
@ -64,7 +64,7 @@ END_PUBLISH
|
||||
* Normally these methods are called only by the DCPacker object; the user
|
||||
* wouldn't normally call these directly.
|
||||
*/
|
||||
class DCPackerInterface {
|
||||
class EXPCL_DIRECT_DCPARSER DCPackerInterface {
|
||||
public:
|
||||
DCPackerInterface(const std::string &name = std::string());
|
||||
DCPackerInterface(const DCPackerInterface ©);
|
||||
|
@ -32,7 +32,7 @@ class HashGenerator;
|
||||
* This may also be a typedef reference to another type, which has the same
|
||||
* properties as the referenced type, but a different name.
|
||||
*/
|
||||
class DCParameter : public DCField {
|
||||
class EXPCL_DIRECT_DCPARSER DCParameter : public DCField {
|
||||
protected:
|
||||
DCParameter();
|
||||
DCParameter(const DCParameter ©);
|
||||
|
@ -43,7 +43,7 @@ extern DCFile *dc_file;
|
||||
// that has member functions in a union), so we'll use a class instead. That
|
||||
// means we need to declare it externally, here.
|
||||
|
||||
class DCTokenType {
|
||||
class EXPCL_DIRECT_DCPARSER DCTokenType {
|
||||
public:
|
||||
union U {
|
||||
int s_int;
|
||||
|
@ -25,7 +25,7 @@
|
||||
* divisor, which is meaningful only for the numeric type elements (and
|
||||
* represents a fixed-point numeric convention).
|
||||
*/
|
||||
class DCSimpleParameter : public DCParameter {
|
||||
class EXPCL_DIRECT_DCPARSER DCSimpleParameter : public DCParameter {
|
||||
public:
|
||||
DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
|
||||
DCSimpleParameter(const DCSimpleParameter ©);
|
||||
|
@ -27,7 +27,7 @@ class DCField;
|
||||
* and represents two or more alternative unpacking schemes based on the first
|
||||
* field read.
|
||||
*/
|
||||
class DCSwitch : public DCDeclaration {
|
||||
class EXPCL_DIRECT_DCPARSER DCSwitch : public DCDeclaration {
|
||||
public:
|
||||
DCSwitch(const std::string &name, DCField *key_parameter);
|
||||
virtual ~DCSwitch();
|
||||
|
@ -23,7 +23,7 @@ class DCSwitch;
|
||||
* This represents a switch object used as a parameter itself, which packs the
|
||||
* appropriate fields of the switch into the message.
|
||||
*/
|
||||
class DCSwitchParameter : public DCParameter {
|
||||
class EXPCL_DIRECT_DCPARSER DCSwitchParameter : public DCParameter {
|
||||
public:
|
||||
DCSwitchParameter(const DCSwitch *dswitch);
|
||||
DCSwitchParameter(const DCSwitchParameter ©);
|
||||
|
@ -23,7 +23,7 @@ class DCParameter;
|
||||
* This represents a single typedef declaration in the dc file. It assigns a
|
||||
* particular type to a new name, just like a C typedef.
|
||||
*/
|
||||
class DCTypedef : public DCDeclaration {
|
||||
class EXPCL_DIRECT_DCPARSER DCTypedef : public DCDeclaration {
|
||||
public:
|
||||
DCTypedef(DCParameter *parameter, bool implicit = false);
|
||||
DCTypedef(const std::string &name);
|
||||
|
@ -70,6 +70,11 @@
|
||||
#define END_PUBLISH
|
||||
#define BLOCKING
|
||||
|
||||
// These control the declspec(dllexport/dllimport) on Windows. When compiling
|
||||
// outside of Panda, we assume we aren't part of a DLL.
|
||||
#define EXPCL_DIRECT_DCPARSER
|
||||
#define EXPTP_DIRECT_DCPARSER
|
||||
|
||||
// Panda defines some assert-type macros. We map those to the standard assert
|
||||
// macro outside of Panda.
|
||||
#define nassertr(condition, return_value) assert(condition)
|
||||
|
@ -20,7 +20,7 @@
|
||||
/**
|
||||
* This class generates an arbitrary hash number from a sequence of ints.
|
||||
*/
|
||||
class HashGenerator {
|
||||
class EXPCL_DIRECT_DCPARSER HashGenerator {
|
||||
public:
|
||||
HashGenerator();
|
||||
|
||||
|
@ -30,7 +30,7 @@ typedef std::vector<int> vector_int;
|
||||
* For a given integer n, it will return the nth prime number. This will
|
||||
* involve a recompute step only if n is greater than any previous n.
|
||||
*/
|
||||
class PrimeNumberGenerator {
|
||||
class EXPCL_DIRECT_DCPARSER PrimeNumberGenerator {
|
||||
public:
|
||||
PrimeNumberGenerator();
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
/* BUILDING_DIRECT is just a buildsystem shortcut for all of these: */
|
||||
#ifdef BUILDING_DIRECT
|
||||
#define BUILDING_DIRECT_DCPARSER
|
||||
#define BUILDING_DIRECT_DEADREC
|
||||
#define BUILDING_DIRECT_DIRECTD
|
||||
#define BUILDING_DIRECT_INTERVAL
|
||||
@ -26,6 +27,14 @@
|
||||
#define BUILDING_DIRECT_DISTRIBUTED
|
||||
#endif
|
||||
|
||||
#ifdef BUILDING_DIRECT_DCPARSER
|
||||
#define EXPCL_DIRECT_DCPARSER EXPORT_CLASS
|
||||
#define EXPTP_DIRECT_DCPARSER EXPORT_TEMPL
|
||||
#else
|
||||
#define EXPCL_DIRECT_DCPARSER IMPORT_CLASS
|
||||
#define EXPTP_DIRECT_DCPARSER IMPORT_TEMPL
|
||||
#endif
|
||||
|
||||
#ifdef BUILDING_DIRECT_DEADREC
|
||||
#define EXPCL_DIRECT_DEADREC EXPORT_CLASS
|
||||
#define EXPTP_DIRECT_DEADREC EXPORT_TEMPL
|
||||
|
@ -25,8 +25,8 @@ class PyDatagram(Datagram):
|
||||
STUint64: (Datagram.addUint64, int),
|
||||
STFloat64: (Datagram.addFloat64, None),
|
||||
STString: (Datagram.addString, None),
|
||||
STBlob: (Datagram.addString, None),
|
||||
STBlob32: (Datagram.addString32, None),
|
||||
STBlob: (Datagram.addBlob, None),
|
||||
STBlob32: (Datagram.addBlob32, None),
|
||||
}
|
||||
|
||||
#def addChannel(self, channelId):
|
||||
|
@ -23,8 +23,8 @@ class PyDatagramIterator(DatagramIterator):
|
||||
STUint64: DatagramIterator.getUint64,
|
||||
STFloat64: DatagramIterator.getFloat64,
|
||||
STString: DatagramIterator.getString,
|
||||
STBlob: DatagramIterator.getString,
|
||||
STBlob32: DatagramIterator.getString32,
|
||||
STBlob: DatagramIterator.getBlob,
|
||||
STBlob32: DatagramIterator.getBlob32,
|
||||
}
|
||||
|
||||
getChannel = DatagramIterator.getUint64
|
||||
|
@ -292,6 +292,10 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
||||
out << str;
|
||||
|
||||
} else if (_flags & F_operator_typecast) {
|
||||
out << "operator ";
|
||||
_return_type->output_instance(out, indent_level, scope, complete, "", prename + str);
|
||||
|
||||
} else {
|
||||
if (prename.empty()) {
|
||||
_return_type->output_instance(out, indent_level, scope, complete,
|
||||
|
@ -30,6 +30,20 @@ struct AtomicAdjust {
|
||||
#include "atomicAdjustDummyImpl.h"
|
||||
typedef AtomicAdjustDummyImpl AtomicAdjust;
|
||||
|
||||
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3))
|
||||
// GCC 4.7 and above has built-in __atomic functions for atomic operations.
|
||||
// Clang 3.0 and above also supports them.
|
||||
|
||||
#include "atomicAdjustGccImpl.h"
|
||||
typedef AtomicAdjustGccImpl AtomicAdjust;
|
||||
|
||||
#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_LONG_LOCK_FREE) > 0
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
|
||||
#endif
|
||||
#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
|
||||
#endif
|
||||
|
||||
#elif (defined(__i386__) || defined(_M_IX86)) && !defined(__APPLE__)
|
||||
// For an i386 architecture, we'll always use the i386 implementation. It
|
||||
// should be safe for any OS, and it might be a bit faster than any OS-
|
||||
@ -45,20 +59,6 @@ typedef AtomicAdjustI386Impl AtomicAdjust;
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
|
||||
|
||||
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3))
|
||||
// GCC 4.7 and above has built-in __atomic functions for atomic operations.
|
||||
// Clang 3.0 and above also supports them.
|
||||
|
||||
#include "atomicAdjustGccImpl.h"
|
||||
typedef AtomicAdjustGccImpl AtomicAdjust;
|
||||
|
||||
#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_INT_LOCK_FREE) > 0
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
|
||||
#endif
|
||||
#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0
|
||||
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
|
||||
#endif
|
||||
|
||||
#elif defined(THREAD_WIN32_IMPL)
|
||||
|
||||
#include "atomicAdjustWin32Impl.h"
|
||||
|
@ -789,8 +789,6 @@ InterfaceMakerPythonNative::
|
||||
*/
|
||||
void InterfaceMakerPythonNative::
|
||||
write_prototypes(ostream &out_code, ostream *out_h) {
|
||||
Functions::iterator fi;
|
||||
|
||||
if (out_h != nullptr) {
|
||||
*out_h << "#include \"py_panda.h\"\n\n";
|
||||
}
|
||||
@ -917,7 +915,6 @@ write_prototypes_class_external(ostream &out, Object *obj) {
|
||||
void InterfaceMakerPythonNative::
|
||||
write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
|
||||
std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
|
||||
Functions::iterator fi;
|
||||
|
||||
out_code << "/**\n";
|
||||
out_code << " * Forward declarations for top-level class " << ClassName << "\n";
|
||||
@ -1089,6 +1086,27 @@ write_class_details(ostream &out, Object *obj) {
|
||||
}
|
||||
}
|
||||
|
||||
// Are there any implicit cast operators that can cast this object to our
|
||||
// desired pointer?
|
||||
for (Function *func : obj->_methods) {
|
||||
for (FunctionRemap *remap : func->_remaps) {
|
||||
if (remap->_type == FunctionRemap::T_typecast_method &&
|
||||
is_remap_legal(remap) &&
|
||||
!remap->_return_type->return_value_needs_management() &&
|
||||
(remap->_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0 &&
|
||||
TypeManager::is_pointer(remap->_return_type->get_new_type())) {
|
||||
|
||||
CPPType *cast_type = remap->_return_type->get_orig_type();
|
||||
CPPType *obj_type = TypeManager::unwrap(TypeManager::resolve_type(remap->_return_type->get_new_type()));
|
||||
string return_expr = "(" + cast_type->get_local_name(&parser) + ")*local_this";
|
||||
out << " // " << *remap->_cppfunc << "\n";
|
||||
out << " if (requested_type == Dtool_Ptr_" << make_safe_name(obj_type->get_local_name(&parser)) << ") {\n";
|
||||
out << " return (void *)(" << remap->_return_type->get_return_expr(return_expr) << ");\n";
|
||||
out << " }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out << " return nullptr;\n";
|
||||
out << "}\n\n";
|
||||
|
||||
@ -3301,7 +3319,7 @@ write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
|
||||
*/
|
||||
void InterfaceMakerPythonNative::
|
||||
write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) {
|
||||
Function::Remaps::const_iterator ri;
|
||||
// Function::Remaps::const_iterator ri;
|
||||
|
||||
// for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
|
||||
// FunctionRemap *remap = (*ri);
|
||||
|
@ -5316,7 +5316,7 @@ if (PkgSkip("DIRECT")==0):
|
||||
#
|
||||
|
||||
if (PkgSkip("DIRECT")==0):
|
||||
OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA', 'BISONPREFIX_dcyy', 'PYTHON']
|
||||
OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy', 'PYTHON']
|
||||
CreateFile(GetOutputDir()+"/include/dcParser.h")
|
||||
TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx')
|
||||
TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY'])
|
||||
|
61
makepanda/test_wheel.py
Executable file
61
makepanda/test_wheel.py
Executable file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Tests a .whl file by installing it and pytest into a virtual environment and
|
||||
running the test suite.
|
||||
|
||||
Requires pip to be installed, as well as 'virtualenv' on Python 2.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def test_wheel(wheel, verbose=False):
|
||||
envdir = tempfile.mkdtemp(prefix="venv-")
|
||||
print("Setting up virtual environment in {0}".format(envdir))
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
subprocess.call([sys.executable, "-m", "venv", "--clear", envdir])
|
||||
else:
|
||||
subprocess.call([sys.executable, "-m", "virtualenv", "--clear", envdir])
|
||||
|
||||
# Install pytest into the environment, as well as our wheel.
|
||||
if sys.platform == "win32":
|
||||
pip = os.path.join(envdir, "Scripts", "pip.exe")
|
||||
else:
|
||||
pip = os.path.join(envdir, "bin", "pip")
|
||||
if subprocess.call([pip, "install", "pytest", wheel]) != 0:
|
||||
shutil.rmtree(envdir)
|
||||
sys.exit(1)
|
||||
|
||||
# Run the test suite.
|
||||
if sys.platform == "win32":
|
||||
python = os.path.join(envdir, "Scripts", "python.exe")
|
||||
else:
|
||||
python = os.path.join(envdir, "bin", "python")
|
||||
test_cmd = [python, "-m", "pytest", "tests"]
|
||||
if verbose:
|
||||
test_cmd.append("--verbose")
|
||||
|
||||
exit_code = subprocess.call(test_cmd)
|
||||
shutil.rmtree(envdir)
|
||||
|
||||
if exit_code != 0:
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = OptionParser(usage="%prog [options] file...")
|
||||
parser.add_option('', '--verbose', dest = 'verbose', help = 'Enable verbose output', action = 'store_true', default = False)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if not args:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
for arg in args:
|
||||
test_wheel(arg, verbose=options.verbose)
|
@ -16,6 +16,7 @@
|
||||
#include "collisionRay.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionHandler.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "config_collide.h"
|
||||
|
@ -558,7 +558,7 @@ remove_doubled_verts(bool closed) {
|
||||
*/
|
||||
void EggPrimitive::
|
||||
remove_nonunique_verts() {
|
||||
Vertices::iterator vi, vj;
|
||||
Vertices::iterator vi;
|
||||
Vertices new_vertices;
|
||||
int num_removed = 0;
|
||||
|
||||
|
@ -2661,7 +2661,6 @@ set_occluder_polygon(EggGroup *egg_group, OccluderNode *pnode) {
|
||||
} else {
|
||||
LMatrix4d mat = poly->get_vertex_to_node();
|
||||
|
||||
EggPolygon::const_iterator vi;
|
||||
LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
|
||||
LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
|
||||
LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
|
||||
|
@ -11,30 +11,11 @@
|
||||
* @date 2000-06-06
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs an empty datagram.
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram() :
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
_stdfloat_double(true)
|
||||
#else
|
||||
_stdfloat_double(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a datagram from an existing block of data.
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram(const void *data, size_t size) :
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
_stdfloat_double(true)
|
||||
#else
|
||||
_stdfloat_double(false)
|
||||
#endif
|
||||
{
|
||||
Datagram(const void *data, size_t size) {
|
||||
append_data(data, size);
|
||||
}
|
||||
|
||||
@ -43,13 +24,7 @@ Datagram(const void *data, size_t size) :
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram(vector_uchar data) :
|
||||
_data(std::move(data)),
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
_stdfloat_double(true)
|
||||
#else
|
||||
_stdfloat_double(false)
|
||||
#endif
|
||||
{
|
||||
_data(std::move(data)) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,6 +270,35 @@ add_fixed_string(const std::string &str, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a variable-length binary blob to the datagram. This actually adds a
|
||||
* count followed by n bytes.
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
add_blob(const vector_uchar &data) {
|
||||
// The max sendable size for a blob is 2^16.
|
||||
nassertv(data.size() <= (uint16_t)0xffff);
|
||||
|
||||
// Blobs always are preceded by their size
|
||||
add_uint16((uint16_t)data.size());
|
||||
|
||||
// Add the blob
|
||||
append_data(data.data(), data.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a variable-length binary blob to the datagram, using a 32-bit length
|
||||
* field to allow very long blobs.
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
add_blob32(const vector_uchar &data) {
|
||||
// Blobs always are preceded by their size
|
||||
add_uint32((uint32_t)data.size());
|
||||
|
||||
// Add the blob
|
||||
append_data(data.data(), data.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends some more raw data to the end of the datagram.
|
||||
*/
|
||||
@ -316,18 +320,6 @@ get_message() const {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the datagram's data as a bytes object.
|
||||
*/
|
||||
INLINE vector_uchar Datagram::
|
||||
__bytes__() const {
|
||||
if (!_data.empty()) {
|
||||
return vector_uchar(_data.v());
|
||||
} else {
|
||||
return vector_uchar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the beginning of the datagram's data.
|
||||
*/
|
||||
@ -482,3 +474,8 @@ INLINE void
|
||||
generic_write_datagram(Datagram &dest, const std::wstring &value) {
|
||||
dest.add_wstring(value);
|
||||
}
|
||||
|
||||
INLINE void
|
||||
generic_write_datagram(Datagram &dest, const vector_uchar &value) {
|
||||
dest.add_blob(value);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*/
|
||||
class EXPCL_PANDA_EXPRESS Datagram : public TypedObject {
|
||||
PUBLISHED:
|
||||
INLINE Datagram();
|
||||
INLINE Datagram() = default;
|
||||
INLINE Datagram(const void *data, size_t size);
|
||||
INLINE explicit Datagram(vector_uchar data);
|
||||
Datagram(const Datagram ©) = default;
|
||||
@ -81,15 +81,23 @@ PUBLISHED:
|
||||
INLINE void add_fixed_string(const std::string &str, size_t size);
|
||||
void add_wstring(const std::wstring &str);
|
||||
|
||||
INLINE void add_blob(const vector_uchar &);
|
||||
INLINE void add_blob32(const vector_uchar &);
|
||||
|
||||
void pad_bytes(size_t size);
|
||||
void append_data(const void *data, size_t size);
|
||||
INLINE void append_data(const vector_uchar &data);
|
||||
|
||||
public:
|
||||
void assign(const void *data, size_t size);
|
||||
|
||||
INLINE std::string get_message() const;
|
||||
INLINE vector_uchar __bytes__() const;
|
||||
INLINE const void *get_data() const;
|
||||
|
||||
PUBLISHED:
|
||||
EXTENSION(INLINE PyObject *get_message() const);
|
||||
EXTENSION(INLINE PyObject *__bytes__() const);
|
||||
|
||||
INLINE size_t get_length() const;
|
||||
|
||||
INLINE void set_array(PTA_uchar data);
|
||||
@ -109,7 +117,12 @@ PUBLISHED:
|
||||
|
||||
private:
|
||||
PTA_uchar _data;
|
||||
bool _stdfloat_double;
|
||||
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
bool _stdfloat_double = true;
|
||||
#else
|
||||
bool _stdfloat_double = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@ -148,6 +161,8 @@ INLINE void
|
||||
generic_write_datagram(Datagram &dest, const std::string &value);
|
||||
INLINE void
|
||||
generic_write_datagram(Datagram &dest, const std::wstring &value);
|
||||
INLINE void
|
||||
generic_write_datagram(Datagram &dest, const vector_uchar &value);
|
||||
|
||||
|
||||
#include "datagram.I"
|
||||
|
@ -400,6 +400,22 @@ get_be_float64() {
|
||||
return tempvar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a variable-length binary blob.
|
||||
*/
|
||||
INLINE vector_uchar DatagramIterator::
|
||||
get_blob() {
|
||||
return extract_bytes(get_uint16());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a variable-length binary blob with a 32-bit size field.
|
||||
*/
|
||||
INLINE vector_uchar DatagramIterator::
|
||||
get_blob32() {
|
||||
return extract_bytes(get_uint32());
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips over the indicated number of bytes in the datagram.
|
||||
*/
|
||||
@ -485,3 +501,8 @@ INLINE void
|
||||
generic_read_datagram(std::wstring &result, DatagramIterator &source) {
|
||||
result = source.get_wstring();
|
||||
}
|
||||
|
||||
INLINE void
|
||||
generic_read_datagram(vector_uchar &result, DatagramIterator &source) {
|
||||
result = source.get_blob();
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ PUBLISHED:
|
||||
std::string get_fixed_string(size_t size);
|
||||
std::wstring get_wstring();
|
||||
|
||||
INLINE vector_uchar get_blob();
|
||||
INLINE vector_uchar get_blob32();
|
||||
|
||||
INLINE void skip_bytes(size_t size);
|
||||
vector_uchar extract_bytes(size_t size);
|
||||
size_t extract_bytes(unsigned char *into, size_t size);
|
||||
|
35
panda/src/express/datagram_ext.I
Normal file
35
panda/src/express/datagram_ext.I
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file datagram_ext.I
|
||||
* @author rdb
|
||||
* @date 2018-08-19
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the datagram's data as a bytes object.
|
||||
*/
|
||||
INLINE PyObject *Extension<Datagram>::
|
||||
get_message() const {
|
||||
const char *data = (const char *)_this->get_data();
|
||||
size_t size = _this->get_length();
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyBytes_FromStringAndSize((char *)data, size);
|
||||
#else
|
||||
return PyString_FromStringAndSize((char *)data, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the datagram's data as a bytes object.
|
||||
*/
|
||||
PyObject *Extension<Datagram>::
|
||||
__bytes__() const {
|
||||
return get_message();
|
||||
}
|
40
panda/src/express/datagram_ext.h
Normal file
40
panda/src/express/datagram_ext.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file datagram_ext.h
|
||||
* @author rdb
|
||||
* @date 2018-08-19
|
||||
*/
|
||||
|
||||
#ifndef DATAGRAM_EXT_H
|
||||
#define DATAGRAM_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "datagram.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
/**
|
||||
* This class defines the extension methods for Datagram, which are called
|
||||
* instead of any C++ methods with the same prototype.
|
||||
*/
|
||||
template<>
|
||||
class Extension<Datagram> : public ExtensionBase<Datagram> {
|
||||
public:
|
||||
INLINE PyObject *get_message() const;
|
||||
INLINE PyObject *__bytes__() const;
|
||||
};
|
||||
|
||||
#include "datagram_ext.I"
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // DATAGRAM_EXT_H
|
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* The streambuf object that implements IDecompressStream and OCompressStream.
|
||||
*/
|
||||
class EXPCL_PANDA_DOWNLOADER ZStreamBuf : public std::streambuf {
|
||||
class EXPCL_PANDA_EXPRESS ZStreamBuf : public std::streambuf {
|
||||
public:
|
||||
ZStreamBuf();
|
||||
virtual ~ZStreamBuf();
|
||||
|
@ -44,6 +44,14 @@ size() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)::Row::
|
||||
operator const FLOATNAME(LVecBase3) &() const {
|
||||
return *(const FLOATNAME(LVecBase3) *)_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a row-level constant accessor to the matrix.
|
||||
*/
|
||||
@ -68,6 +76,14 @@ size() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)::CRow::
|
||||
operator const FLOATNAME(LVecBase3) &() const {
|
||||
return *(const FLOATNAME(LVecBase3) *)_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an identity matrix.
|
||||
*
|
||||
@ -132,6 +148,32 @@ FLOATNAME(LMatrix3)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02,
|
||||
_m(2, 2) = e22;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the matrix from three individual rows.
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)::
|
||||
FLOATNAME(LMatrix3)(const FLOATNAME(LVecBase3) &row0,
|
||||
const FLOATNAME(LVecBase3) &row1,
|
||||
const FLOATNAME(LVecBase3) &row2) {
|
||||
TAU_PROFILE("LMatrix3::LMatrix3(const LVecBase3 &, ...)", " ", TAU_USER);
|
||||
|
||||
#ifdef HAVE_EIGEN
|
||||
_m.row(0) = row0._v;
|
||||
_m.row(1) = row1._v;
|
||||
_m.row(2) = row2._v;
|
||||
#else
|
||||
_m(0, 0) = row0._v(0);
|
||||
_m(0, 1) = row0._v(1);
|
||||
_m(0, 2) = row0._v(2);
|
||||
_m(1, 0) = row1._v(0);
|
||||
_m(1, 1) = row1._v(1);
|
||||
_m(1, 2) = row1._v(2);
|
||||
_m(2, 0) = row2._v(0);
|
||||
_m(2, 1) = row2._v(1);
|
||||
_m(2, 2) = row2._v(2);
|
||||
#endif // HAVE_EIGEN
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -38,6 +38,7 @@ PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH FLOATTYPE &operator [](int i);
|
||||
INLINE_LINMATH static int size();
|
||||
INLINE_LINMATH operator const FLOATNAME(LVecBase3) &() const;
|
||||
public:
|
||||
FLOATTYPE *_row;
|
||||
friend class FLOATNAME(LMatrix3);
|
||||
@ -48,6 +49,7 @@ PUBLISHED:
|
||||
PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH static int size();
|
||||
INLINE_LINMATH operator const FLOATNAME(LVecBase3) &() const;
|
||||
public:
|
||||
const FLOATTYPE *_row;
|
||||
friend class FLOATNAME(LMatrix3);
|
||||
@ -58,10 +60,12 @@ PUBLISHED:
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3) &operator = (
|
||||
const FLOATNAME(LMatrix3) &other);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3) &operator = (FLOATTYPE fill_value);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)(
|
||||
FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02,
|
||||
FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12,
|
||||
FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)(FLOATTYPE, FLOATTYPE, FLOATTYPE,
|
||||
FLOATTYPE, FLOATTYPE, FLOATTYPE,
|
||||
FLOATTYPE, FLOATTYPE, FLOATTYPE);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)(const FLOATNAME(LVecBase3) &,
|
||||
const FLOATNAME(LVecBase3) &,
|
||||
const FLOATNAME(LVecBase3) &);
|
||||
ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix3));
|
||||
|
||||
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
|
||||
|
@ -44,6 +44,14 @@ size() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)::Row::
|
||||
operator const FLOATNAME(LVecBase4) &() const {
|
||||
return *(const FLOATNAME(LVecBase4) *)_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a row-level constant accessor to the matrix.
|
||||
*/
|
||||
@ -68,6 +76,14 @@ size() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)::CRow::
|
||||
operator const FLOATNAME(LVecBase4) &() const {
|
||||
return *(const FLOATNAME(LVecBase4) *)_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an identity matrix.
|
||||
*
|
||||
@ -178,6 +194,41 @@ FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
|
||||
_m(3, 3) = e33;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the matrix from four individual rows.
|
||||
*/
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)::
|
||||
FLOATNAME(LMatrix4)(const FLOATNAME(LVecBase4) &row0,
|
||||
const FLOATNAME(LVecBase4) &row1,
|
||||
const FLOATNAME(LVecBase4) &row2,
|
||||
const FLOATNAME(LVecBase4) &row3) {
|
||||
TAU_PROFILE("LMatrix4::LMatrix4(const LVecBase4 &, ...)", " ", TAU_USER);
|
||||
|
||||
#ifdef HAVE_EIGEN
|
||||
_m.row(0) = row0._v;
|
||||
_m.row(1) = row1._v;
|
||||
_m.row(2) = row2._v;
|
||||
_m.row(3) = row3._v;
|
||||
#else
|
||||
_m(0, 0) = row0._v(0);
|
||||
_m(0, 1) = row0._v(1);
|
||||
_m(0, 2) = row0._v(2);
|
||||
_m(0, 3) = row0._v(3);
|
||||
_m(1, 0) = row1._v(0);
|
||||
_m(1, 1) = row1._v(1);
|
||||
_m(1, 2) = row1._v(2);
|
||||
_m(1, 3) = row1._v(3);
|
||||
_m(2, 0) = row2._v(0);
|
||||
_m(2, 1) = row2._v(1);
|
||||
_m(2, 2) = row2._v(2);
|
||||
_m(2, 3) = row2._v(3);
|
||||
_m(3, 0) = row3._v(0);
|
||||
_m(3, 1) = row3._v(1);
|
||||
_m(3, 2) = row3._v(2);
|
||||
_m(3, 3) = row3._v(3);
|
||||
#endif // HAVE_EIGEN
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -36,6 +36,7 @@ PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH FLOATTYPE &operator [](int i);
|
||||
INLINE_LINMATH static int size();
|
||||
INLINE_LINMATH operator const FLOATNAME(LVecBase4) &() const;
|
||||
public:
|
||||
FLOATTYPE *_row;
|
||||
friend class FLOATNAME(LMatrix4);
|
||||
@ -46,6 +47,7 @@ PUBLISHED:
|
||||
PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH static int size();
|
||||
INLINE_LINMATH operator const FLOATNAME(LVecBase4) &() const;
|
||||
public:
|
||||
const FLOATTYPE *_row;
|
||||
friend class FLOATNAME(LMatrix4);
|
||||
@ -60,10 +62,14 @@ PUBLISHED:
|
||||
const FLOATNAME(UnalignedLMatrix4) &other);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4) &operator = (FLOATTYPE fill_value);
|
||||
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
|
||||
FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13,
|
||||
FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23,
|
||||
FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)(FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE,
|
||||
FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE,
|
||||
FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE,
|
||||
FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE);
|
||||
INLINE_LINMATH FLOATNAME(LMatrix4)(const FLOATNAME(LVecBase4) &,
|
||||
const FLOATNAME(LVecBase4) &,
|
||||
const FLOATNAME(LVecBase4) &,
|
||||
const FLOATNAME(LVecBase4) &);
|
||||
ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix4));
|
||||
|
||||
EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
|
||||
|
@ -115,7 +115,6 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||
GeomList::iterator gi;
|
||||
PT(GeomList) geoms = cdata->modify_geoms();
|
||||
|
||||
// Iterate based on the number of geoms, not using STL iterators. This
|
||||
|
@ -742,7 +742,6 @@ make_compatible_state(GeomNode *node) {
|
||||
}
|
||||
|
||||
GeomNode::CDWriter cdata(node->_cycler);
|
||||
GeomNode::GeomList::iterator gi;
|
||||
PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
|
||||
|
||||
// For each geom, calculate a canonicalized RenderState, and classify all
|
||||
|
@ -82,10 +82,7 @@ play_frame(DatagramIterator &scan, BamReader *manager) {
|
||||
|
||||
int num_packets = scan.get_uint16();
|
||||
for (int i = 0; i < num_packets; i++) {
|
||||
size_t size = scan.get_uint16();
|
||||
vector_uchar packet(size);
|
||||
scan.extract_bytes(&packet[0], size);
|
||||
_data.push_back(Datagram(std::move(packet)));
|
||||
_data.push_back(Datagram(scan.get_blob()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1072,6 @@ render_polygon_contours(TextGlyph *glyph, bool face, bool extrude) {
|
||||
// create more vertices--they don't share the same normals.
|
||||
for (ci = _contours.begin(); ci != _contours.end(); ++ci) {
|
||||
const Contour &contour = (*ci);
|
||||
Points::const_iterator pi;
|
||||
|
||||
for (size_t i = 0; i < contour._points.size(); ++i) {
|
||||
const ContourPoint &cp = contour._points[i];
|
||||
|
@ -837,12 +837,12 @@ int MayaEggGeom::GetVert(EggVertex *vert, EggGroup *context)
|
||||
void MayaEggGeom::AssignNames(void)
|
||||
{
|
||||
string name = _pool->get_name();
|
||||
int nsize = name.size();
|
||||
if ((nsize > 6) && (name.rfind(".verts")==(nsize-6))) {
|
||||
name.resize(nsize-6);
|
||||
size_t nsize = name.size();
|
||||
if (nsize > 6 && name.rfind(".verts") == (nsize - 6)) {
|
||||
name.resize(nsize - 6);
|
||||
}
|
||||
if ((nsize > 4) && (name.rfind(".cvs")==(nsize-4))) {
|
||||
name.resize(nsize-4);
|
||||
if (nsize > 4 && name.rfind(".cvs") == (nsize - 4)) {
|
||||
name.resize(nsize - 4);
|
||||
}
|
||||
|
||||
MFnDependencyNode dnshape(_shapeNode);
|
||||
@ -913,7 +913,7 @@ void MayaEggGeom::AddEggFlag(MString fieldName) {
|
||||
typedef phash_map<LTexCoordd, int> TVertTable;
|
||||
typedef phash_map<LColor, int> CVertTable;
|
||||
|
||||
class MayaEggMesh : public MayaEggGeom
|
||||
class MayaEggMesh final : public MayaEggGeom
|
||||
{
|
||||
public:
|
||||
MColorArray _faceColorArray;
|
||||
@ -937,7 +937,7 @@ public:
|
||||
int GetCVert(const LColor &col);
|
||||
int AddFace(unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex);
|
||||
|
||||
void ConnectTextures(void);
|
||||
void ConnectTextures(void) override;
|
||||
};
|
||||
|
||||
int MayaEggMesh::GetTVert(const LTexCoordd &uv)
|
||||
@ -2012,7 +2012,7 @@ void MayaEggLoader::PrintData(MayaEggMesh *mesh)
|
||||
|
||||
void MayaEggLoader::ParseFrameInfo(string comment)
|
||||
{
|
||||
int pos, ls, le;
|
||||
size_t pos, ls, le;
|
||||
|
||||
pos = comment.find("-fri");
|
||||
if (pos != string::npos) {
|
||||
@ -2143,7 +2143,7 @@ bool MayaEggLoader::ConvertEggFile(const char *name, bool merge, bool model, boo
|
||||
MObject MayaEggLoader::GetDependencyNode(string givenName)
|
||||
{
|
||||
MObject node = MObject::kNullObj;
|
||||
int pos;
|
||||
size_t pos;
|
||||
string name;
|
||||
|
||||
pos = givenName.find(":");
|
||||
|
@ -2742,7 +2742,7 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader,
|
||||
// shader on the list is the base one, which should always pick up
|
||||
// the alpha from the texture file. But the top textures may have
|
||||
// to strip the alpha
|
||||
if (i!=shader._color.size()-1) {
|
||||
if ((size_t)i != shader._color.size() - 1) {
|
||||
if (!i && is_interpolate) {
|
||||
// this is the grass path mode where alpha on this texture
|
||||
// determines whether to show layer1 or layer2. Since by now
|
||||
@ -2846,7 +2846,7 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader,
|
||||
_textures.create_unique_texture(tex, ~0);
|
||||
|
||||
if (mesh) {
|
||||
if (uvset_name.find("not found") == -1) {
|
||||
if (uvset_name.find("not found") == string::npos) {
|
||||
primitive.add_texture(new_tex);
|
||||
color_def->_uvset_name.assign(uvset_name.c_str());
|
||||
if (uvset_name != "map1") {
|
||||
|
@ -37,7 +37,8 @@ def test_egg2pg_transform_ident(egg_coordsys, coordsys):
|
||||
@pytest.mark.parametrize("coordsys", COORD_SYSTEMS)
|
||||
def test_egg2pg_transform_mat_unchanged(coordsys):
|
||||
# Ensures that the matrix remains unchanged if coordinate system is same.
|
||||
mat = (5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2)
|
||||
matv = (5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2)
|
||||
mat = core.Mat4D(*matv)
|
||||
group = egg.EggGroup("group")
|
||||
group.add_matrix4(mat)
|
||||
assert not group.transform_is_identity()
|
||||
@ -57,7 +58,7 @@ def test_egg2pg_transform_mat_unchanged(coordsys):
|
||||
assert root
|
||||
node, = root.children
|
||||
|
||||
assert node.transform.mat == mat
|
||||
assert node.transform.mat == core.Mat4(*matv)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("egg_coordsys", COORD_SYSTEMS)
|
||||
|
@ -22,8 +22,10 @@ def image_rgb_path():
|
||||
"Generates an RGB image."
|
||||
|
||||
file = tempfile.NamedTemporaryFile(suffix='-rgb.png')
|
||||
write_image(file.name, 3)
|
||||
yield file.name
|
||||
path = core.Filename.from_os_specific(file.name)
|
||||
path.make_true_case()
|
||||
write_image(path, 3)
|
||||
yield path
|
||||
file.close()
|
||||
|
||||
|
||||
@ -32,8 +34,10 @@ def image_rgba_path():
|
||||
"Generates an RGBA image."
|
||||
|
||||
file = tempfile.NamedTemporaryFile(suffix='-rgba.png')
|
||||
write_image(file.name, 4)
|
||||
yield file.name
|
||||
path = core.Filename.from_os_specific(file.name)
|
||||
path.make_true_case()
|
||||
write_image(path, 4)
|
||||
yield path
|
||||
file.close()
|
||||
|
||||
|
||||
@ -42,8 +46,10 @@ def image_gray_path():
|
||||
"Generates a grayscale image."
|
||||
|
||||
file = tempfile.NamedTemporaryFile(suffix='-gray.png')
|
||||
write_image(file.name, 1)
|
||||
yield file.name
|
||||
path = core.Filename.from_os_specific(file.name)
|
||||
path.make_true_case()
|
||||
write_image(path, 1)
|
||||
yield path
|
||||
file.close()
|
||||
|
||||
|
||||
|
62
tests/linmath/test_lmatrix3.py
Normal file
62
tests/linmath/test_lmatrix3.py
Normal file
@ -0,0 +1,62 @@
|
||||
import pytest
|
||||
from copy import copy
|
||||
from panda3d import core
|
||||
|
||||
|
||||
def test_mat3_aliases():
|
||||
assert core.LMatrix3 is core.Mat3
|
||||
assert core.LMatrix3f is core.Mat3F
|
||||
assert core.LMatrix3d is core.Mat3D
|
||||
|
||||
assert (core.LMatrix3f is core.Mat3) != (core.LMatrix3d is core.Mat3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix3f, core.LMatrix3d))
|
||||
def test_mat3_constructor(type):
|
||||
# Test that three ways of construction produce the same matrix.
|
||||
mat1 = type((1, 2, 3),
|
||||
(4, 5, 6),
|
||||
(7, 8, 9))
|
||||
|
||||
mat2 = type(1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
mat3 = type((1, 2, 3, 4, 5, 6, 7, 8, 9))
|
||||
|
||||
assert mat1 == mat2
|
||||
assert mat2 == mat3
|
||||
assert mat1 == mat3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix3d, core.LMatrix3f))
|
||||
def test_mat3_copy_constuctor(type):
|
||||
mat1 = type((1, 2, 3),
|
||||
(4, 5, 6),
|
||||
(7, 8, 9))
|
||||
|
||||
# Make a copy. Changing it should not change the original.
|
||||
mat2 = type(mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
# Make a copy by unpacking.
|
||||
mat2 = type(*mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
# Make a copy by calling copy.copy.
|
||||
mat2 = copy(mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix3d, core.LMatrix3f))
|
||||
def test_mat3_invert_same_type(type):
|
||||
mat = type((1, 0, 0,
|
||||
0, 1, 0,
|
||||
1, 2, 3))
|
||||
|
||||
inv = core.invert(mat)
|
||||
assert mat.__class__ == inv.__class__
|
89
tests/linmath/test_lmatrix4.py
Normal file
89
tests/linmath/test_lmatrix4.py
Normal file
@ -0,0 +1,89 @@
|
||||
import pytest
|
||||
from copy import copy
|
||||
from panda3d import core
|
||||
|
||||
|
||||
def test_mat4_aliases():
|
||||
assert core.LMatrix4 is core.Mat4
|
||||
assert core.LMatrix4f is core.Mat4F
|
||||
assert core.LMatrix4d is core.Mat4D
|
||||
|
||||
assert (core.LMatrix4f is core.Mat4) != (core.LMatrix4d is core.Mat4)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||
def test_mat4_constructor(type):
|
||||
# Test that three ways of construction produce the same matrix.
|
||||
mat1 = type((1, 2, 3, 4),
|
||||
(5, 6, 7, 8),
|
||||
(9, 10, 11, 12),
|
||||
(13, 14, 15, 16))
|
||||
|
||||
mat2 = type(1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16)
|
||||
|
||||
mat3 = type((1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16))
|
||||
|
||||
assert mat1 == mat2
|
||||
assert mat2 == mat3
|
||||
assert mat1 == mat3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||
def test_mat4_copy_constuctor(type):
|
||||
mat1 = type((1, 2, 3, 4),
|
||||
(5, 6, 7, 8),
|
||||
(9, 10, 11, 12),
|
||||
(13, 14, 15, 16))
|
||||
|
||||
# Make a copy. Changing it should not change the original.
|
||||
mat2 = type(mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
# Make a copy by unpacking.
|
||||
mat2 = type(*mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
# Make a copy by calling copy.copy.
|
||||
mat2 = copy(mat1)
|
||||
assert mat1 == mat2
|
||||
mat2[0][0] = 100
|
||||
assert mat1 != mat2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||
def test_mat4_invert_same_type(type):
|
||||
mat = type((1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
1, 2, 3, 1))
|
||||
|
||||
inv = core.invert(mat)
|
||||
assert mat.__class__ == inv.__class__
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||
def test_mat4_invert_correct(type):
|
||||
mat = type((1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
1, 2, 3, 1))
|
||||
inv = type()
|
||||
assert inv.invert_from(mat)
|
||||
|
||||
assert inv == type(( 1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
-1, -2, -3, 1))
|
||||
|
||||
assert (mat * inv).is_identity()
|
||||
assert (inv * mat).is_identity()
|
@ -1,20 +0,0 @@
|
||||
import pytest
|
||||
from panda3d import core
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type", (core.Mat4, core.Mat4D))
|
||||
def test_mat4_invert(type):
|
||||
mat = type((1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
1, 2, 3, 1))
|
||||
inv = type()
|
||||
assert inv.invert_from(mat)
|
||||
|
||||
assert inv == type(( 1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
-1, -2, -3, 1))
|
||||
|
||||
assert (mat * inv).is_identity()
|
||||
assert (inv * mat).is_identity()
|
@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from panda3d import core
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# Fixtures for generating interesting datagrams (and verification functions) on
|
||||
# the fly...
|
||||
@ -28,6 +29,9 @@ def datagram_small(request):
|
||||
dg.add_string32('this is another string')
|
||||
dg.add_string('this is yet a third string')
|
||||
|
||||
dg.add_blob(b'blob data \x00\xf2\xa0\x00\x00')
|
||||
dg.add_blob32(b'\xc9\x8f\x00 test blob32')
|
||||
|
||||
dg.add_stdfloat(800.2)
|
||||
dg.add_stdfloat(3.1415926)
|
||||
dg.add_stdfloat(2.7182818)
|
||||
@ -49,6 +53,9 @@ def datagram_small(request):
|
||||
assert dgi.get_string32() == 'this is another string'
|
||||
assert dgi.get_string() == 'this is yet a third string'
|
||||
|
||||
assert dgi.get_blob() == b'blob data \x00\xf2\xa0\x00\x00'
|
||||
assert dgi.get_blob32() == b'\xc9\x8f\x00 test blob32'
|
||||
|
||||
assert dgi.get_stdfloat() == pytest.approx(800.2)
|
||||
assert dgi.get_stdfloat() == pytest.approx(3.1415926)
|
||||
assert dgi.get_stdfloat() == pytest.approx(2.7182818)
|
||||
@ -88,6 +95,12 @@ def test_datagram_bytes():
|
||||
dgi.get_remaining_bytes() == b'abc\x00\xff123'
|
||||
|
||||
|
||||
def test_datagram_get_message():
|
||||
dg = core.Datagram(b'abc\x00')
|
||||
dg.append_data(b'\xff123')
|
||||
assert dg.get_message() == b'abc\x00\xff123'
|
||||
|
||||
|
||||
def test_iterator(datagram_small):
|
||||
"""This tests Datagram/DatagramIterator, and sort of serves as a self-check
|
||||
of the test fixtures too."""
|
||||
@ -135,30 +148,39 @@ def do_file_test(dg, verify, filename):
|
||||
dgi = core.DatagramIterator(dg2)
|
||||
verify(dgi)
|
||||
|
||||
def test_file_small(datagram_small, tmpdir):
|
||||
@pytest.fixture
|
||||
def tmpfile():
|
||||
file = tempfile.NamedTemporaryFile(suffix='.bin')
|
||||
yield file
|
||||
file.close()
|
||||
|
||||
def test_file_small(datagram_small, tmpfile):
|
||||
"""This tests DatagramOutputFile/DatagramInputFile on small datagrams."""
|
||||
dg, verify = datagram_small
|
||||
|
||||
p = tmpdir.join('datagram.bin')
|
||||
filename = core.Filename.from_os_specific(str(p))
|
||||
file = tempfile.NamedTemporaryFile(suffix='.bin')
|
||||
filename = core.Filename.from_os_specific(file.name)
|
||||
filename.make_true_case()
|
||||
|
||||
do_file_test(dg, verify, filename)
|
||||
|
||||
def test_file_large(datagram_large, tmpdir):
|
||||
def test_file_large(datagram_large, tmpfile):
|
||||
"""This tests DatagramOutputFile/DatagramInputFile on very large datagrams."""
|
||||
dg, verify = datagram_large
|
||||
|
||||
p = tmpdir.join('datagram.bin')
|
||||
filename = core.Filename.from_os_specific(str(p))
|
||||
file = tempfile.NamedTemporaryFile(suffix='.bin')
|
||||
filename = core.Filename.from_os_specific(file.name)
|
||||
filename.make_true_case()
|
||||
|
||||
do_file_test(dg, verify, filename)
|
||||
|
||||
def test_file_corrupt(datagram_small, tmpdir):
|
||||
def test_file_corrupt(datagram_small, tmpfile):
|
||||
"""This tests DatagramInputFile's handling of a corrupt size header."""
|
||||
dg, verify = datagram_small
|
||||
|
||||
p = tmpdir.join('datagram.bin')
|
||||
filename = core.Filename.from_os_specific(str(p))
|
||||
file = tempfile.NamedTemporaryFile(suffix='.bin')
|
||||
filename = core.Filename.from_os_specific(file.name)
|
||||
filename.make_true_case()
|
||||
|
||||
dof = core.DatagramOutputFile()
|
||||
dof.open(filename)
|
||||
@ -166,9 +188,9 @@ def test_file_corrupt(datagram_small, tmpdir):
|
||||
dof.close()
|
||||
|
||||
# Corrupt the size header to 1GB
|
||||
with p.open(mode='r+b') as f:
|
||||
f.seek(0)
|
||||
f.write(b'\xFF\xFF\xFF\x4F')
|
||||
file.seek(0)
|
||||
file.write(b'\xFF\xFF\xFF\x4F')
|
||||
file.flush()
|
||||
|
||||
dg2 = core.Datagram()
|
||||
dif = core.DatagramInputFile()
|
||||
@ -178,8 +200,7 @@ def test_file_corrupt(datagram_small, tmpdir):
|
||||
|
||||
# Truncate the file
|
||||
for size in [12, 8, 4, 3, 2, 1, 0]:
|
||||
with p.open(mode='r+b') as f:
|
||||
f.truncate(size)
|
||||
file.truncate(size)
|
||||
|
||||
dg2 = core.Datagram()
|
||||
dif = core.DatagramInputFile()
|
||||
|
Loading…
x
Reference in New Issue
Block a user