Merge branch 'master' into deploy-ng
This commit is contained in:
commit
01915a36db
|
|
@ -653,15 +653,11 @@ class Actor(DirectObject, NodePath):
|
|||
"""
|
||||
# make sure we don't call this twice in a row
|
||||
# and pollute the the switches dictionary
|
||||
## sortedKeys = list(self.switches.keys())
|
||||
## sortedKeys.sort()
|
||||
child = self.__LODNode.find(str(lodName))
|
||||
index = self.__LODNode.node().findChild(child.node())
|
||||
self.__LODNode.node().forceSwitch(index)
|
||||
|
||||
def printLOD(self):
|
||||
## sortedKeys = list(self.switches.keys())
|
||||
## sortedKeys.sort()
|
||||
sortedKeys = self.__sortedLODNames
|
||||
for eachLod in sortedKeys:
|
||||
print("python switches for %s: in: %d, out %d" % (eachLod,
|
||||
|
|
@ -679,12 +675,6 @@ class Actor(DirectObject, NodePath):
|
|||
"""
|
||||
Restore all switch distance info (usually after a useLOD call)"""
|
||||
self.__LODNode.node().clearForceSwitch()
|
||||
## sortedKeys = list(self.switches.keys())
|
||||
## sortedKeys.sort()
|
||||
## for eachLod in sortedKeys:
|
||||
## index = sortedKeys.index(eachLod)
|
||||
## self.__LODNode.node().setSwitch(index, self.switches[eachLod][0],
|
||||
## self.switches[eachLod][1])
|
||||
|
||||
def addLOD(self, lodName, inDist=0, outDist=0, center=None):
|
||||
"""addLOD(self, string)
|
||||
|
|
@ -706,8 +696,6 @@ class Actor(DirectObject, NodePath):
|
|||
# save the switch distance info
|
||||
self.switches[lodName] = [inDist, outDist]
|
||||
# add the switch distance info
|
||||
## sortedKeys = list(self.switches.keys())
|
||||
## sortedKeys.sort()
|
||||
self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist)
|
||||
|
||||
def getLODIndex(self, lodName):
|
||||
|
|
|
|||
|
|
@ -262,6 +262,38 @@ pack_string(DCPackData &pack_data, const string &value,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the indicated numeric or string value into the stream.
|
||||
*/
|
||||
void DCArrayParameter::
|
||||
pack_blob(DCPackData &pack_data, const vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const {
|
||||
// We can only pack a string if the array element type is char or int8.
|
||||
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
|
||||
if (simple_type == nullptr) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t blob_size = value.size();
|
||||
|
||||
switch (simple_type->get_type()) {
|
||||
case ST_char:
|
||||
case ST_uint8:
|
||||
case ST_int8:
|
||||
_array_size_range.validate(blob_size, range_error);
|
||||
if (_num_length_bytes != 0) {
|
||||
nassertv(_num_length_bytes == 2);
|
||||
do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
|
||||
}
|
||||
pack_data.append_data((const char *)value.data(), blob_size);
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the arrayParameter's specified default value (or a sensible default
|
||||
* if no value is specified) into the stream. Returns true if the default
|
||||
|
|
@ -339,6 +371,46 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the current numeric or string value from the stream.
|
||||
*/
|
||||
void DCArrayParameter::
|
||||
unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const {
|
||||
// We can only unpack a string if the array element type is char or int8.
|
||||
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
|
||||
if (simple_type == nullptr) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t blob_size;
|
||||
|
||||
switch (simple_type->get_type()) {
|
||||
case ST_char:
|
||||
case ST_uint8:
|
||||
case ST_int8:
|
||||
if (_num_length_bytes != 0) {
|
||||
blob_size = do_unpack_uint16(data + p);
|
||||
p += 2;
|
||||
} else {
|
||||
nassertv(_array_size >= 0);
|
||||
blob_size = _array_size;
|
||||
}
|
||||
if (p + blob_size > length) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = vector_uchar((const unsigned char *)data + p,
|
||||
(const unsigned char *)data + p + blob_size);
|
||||
p += blob_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the other interface is bitwise the same as this one--that
|
||||
* is, a uint32 only matches a uint32, etc. Names of components, and range
|
||||
|
|
|
|||
|
|
@ -51,9 +51,13 @@ public:
|
|||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
virtual void unpack_string(const char *data, size_t length, size_t &p,
|
||||
std::string &value, bool &pack_error, bool &range_error) const;
|
||||
virtual void unpack_blob(const char *data, size_t length, size_t &p,
|
||||
vector_uchar &value, bool &pack_error, bool &range_error) const;
|
||||
|
||||
protected:
|
||||
virtual bool do_check_match(const DCPackerInterface *other) const;
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ get_element(int n) const {
|
|||
* If the element is an array-type element, the returned value will include
|
||||
* the two-byte length preceding the array data.
|
||||
*
|
||||
* This is deprecated; use get_element() instead.
|
||||
* @deprecated use get_element() instead.
|
||||
*/
|
||||
string DCAtomicField::
|
||||
vector_uchar DCAtomicField::
|
||||
get_element_default(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), vector_uchar());
|
||||
return _elements[n]->get_default_value();
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ get_element_default(int n) const {
|
|||
* Returns true if the nth element of the field has a default value specified,
|
||||
* false otherwise.
|
||||
*
|
||||
* This is deprecated; use get_element() instead.
|
||||
* @deprecated use get_element() instead.
|
||||
*/
|
||||
bool DCAtomicField::
|
||||
has_element_default(int n) const {
|
||||
|
|
@ -113,7 +113,7 @@ has_element_default(int n) const {
|
|||
* for documentary purposes; it does not generally affect operation. If a
|
||||
* name is not specified, this will be the empty string.
|
||||
*
|
||||
* This method is deprecated; use get_element()->get_name() instead.
|
||||
* @deprecated use get_element()->get_name() instead.
|
||||
*/
|
||||
string DCAtomicField::
|
||||
get_element_name(int n) const {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ PUBLISHED:
|
|||
DCParameter *get_element(int n) const;
|
||||
|
||||
// These five methods are deprecated and will be removed soon.
|
||||
std::string get_element_default(int n) const;
|
||||
vector_uchar get_element_default(int n) const;
|
||||
bool has_element_default(int n) const;
|
||||
std::string get_element_name(int n) const;
|
||||
DCSubatomicType get_element_type(int n) const;
|
||||
|
|
|
|||
|
|
@ -587,7 +587,7 @@ receive_update_other(PyObject *distobj, DatagramIterator &di) const {
|
|||
*/
|
||||
void DCClass::
|
||||
direct_update(PyObject *distobj, const string &field_name,
|
||||
const string &value_blob) {
|
||||
const vector_uchar &value_blob) {
|
||||
DCField *field = get_field_by_name(field_name);
|
||||
nassertv_always(field != nullptr);
|
||||
|
||||
|
|
@ -606,7 +606,14 @@ direct_update(PyObject *distobj, const string &field_name,
|
|||
void DCClass::
|
||||
direct_update(PyObject *distobj, const string &field_name,
|
||||
const Datagram &datagram) {
|
||||
direct_update(distobj, field_name, datagram.get_message());
|
||||
DCField *field = get_field_by_name(field_name);
|
||||
nassertv_always(field != nullptr);
|
||||
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data((const char *)datagram.get_data(), datagram.get_length(), false);
|
||||
packer.begin_unpack(field);
|
||||
field->receive_update(packer, distobj);
|
||||
packer.end_unpack();
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ PUBLISHED:
|
|||
void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
|
||||
|
||||
void direct_update(PyObject *distobj, const std::string &field_name,
|
||||
const std::string &value_blob);
|
||||
const vector_uchar &value_blob);
|
||||
void direct_update(PyObject *distobj, const std::string &field_name,
|
||||
const Datagram &datagram);
|
||||
bool pack_required_field(Datagram &datagram, PyObject *distobj,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ has_default_value() const {
|
|||
* explicitly set (e.g. has_default_value() returns true), returns that
|
||||
* value; otherwise, returns an implicit default for the field.
|
||||
*/
|
||||
INLINE const std::string &DCField::
|
||||
INLINE const vector_uchar &DCField::
|
||||
get_default_value() const {
|
||||
if (_default_value_stale) {
|
||||
((DCField *)this)->refresh_default_value();
|
||||
|
|
@ -172,8 +172,8 @@ set_class(DCClass *dclass) {
|
|||
* Establishes a default value for this field.
|
||||
*/
|
||||
INLINE void DCField::
|
||||
set_default_value(const std::string &default_value) {
|
||||
_default_value = default_value;
|
||||
set_default_value(vector_uchar default_value) {
|
||||
_default_value = std::move(default_value);
|
||||
_has_default_value = true;
|
||||
_default_value_stale = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ as_parameter() const {
|
|||
* is an error.
|
||||
*/
|
||||
string DCField::
|
||||
format_data(const string &packed_data, bool show_field_names) {
|
||||
format_data(const vector_uchar &packed_data, bool show_field_names) {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(packed_data);
|
||||
packer.begin_unpack(this);
|
||||
|
|
@ -178,20 +178,20 @@ format_data(const string &packed_data, bool show_field_names) {
|
|||
* above) that represents the value of this field, parse the string and return
|
||||
* the corresponding packed data. Returns empty string if there is an error.
|
||||
*/
|
||||
string DCField::
|
||||
vector_uchar DCField::
|
||||
parse_string(const string &formatted_string) {
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
if (!packer.parse_and_pack(formatted_string)) {
|
||||
// Parse error.
|
||||
return string();
|
||||
return vector_uchar();
|
||||
}
|
||||
if (!packer.end_pack()) {
|
||||
// Data type mismatch.
|
||||
return string();
|
||||
return vector_uchar();
|
||||
}
|
||||
|
||||
return packer.get_string();
|
||||
return packer.get_bytes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -200,7 +200,7 @@ parse_string(const string &formatted_string) {
|
|||
* record. Returns true if all fields are valid, false otherwise.
|
||||
*/
|
||||
bool DCField::
|
||||
validate_ranges(const string &packed_data) const {
|
||||
validate_ranges(const vector_uchar &packed_data) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(packed_data);
|
||||
packer.begin_unpack(this);
|
||||
|
|
@ -209,7 +209,7 @@ validate_ranges(const string &packed_data) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
return (packer.get_num_unpacked_bytes() == packed_data.length());
|
||||
return (packer.get_num_unpacked_bytes() == packed_data.size());
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
|
@ -488,7 +488,7 @@ pack_default_value(DCPackData &pack_data, bool &) const {
|
|||
// The default behavior is to pack the default value if we got it;
|
||||
// otherwise, to return false and let the packer visit our nested elements.
|
||||
if (!_default_value_stale) {
|
||||
pack_data.append_data(_default_value.data(), _default_value.length());
|
||||
pack_data.append_data((const char *)_default_value.data(), _default_value.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +566,8 @@ refresh_default_value() {
|
|||
if (!packer.end_pack()) {
|
||||
std::cerr << "Error while packing default value for " << get_name() << "\n";
|
||||
} else {
|
||||
_default_value.assign(packer.get_data(), packer.get_length());
|
||||
const unsigned char *data = (const unsigned char *)packer.get_data();
|
||||
_default_value = vector_uchar(data, data + packer.get_length());
|
||||
}
|
||||
_default_value_stale = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ PUBLISHED:
|
|||
virtual DCParameter *as_parameter();
|
||||
virtual const DCParameter *as_parameter() const;
|
||||
|
||||
std::string format_data(const std::string &packed_data, bool show_field_names = true);
|
||||
std::string parse_string(const std::string &formatted_string);
|
||||
std::string format_data(const vector_uchar &packed_data, bool show_field_names = true);
|
||||
vector_uchar parse_string(const std::string &formatted_string);
|
||||
|
||||
bool validate_ranges(const std::string &packed_data) const;
|
||||
bool validate_ranges(const vector_uchar &packed_data) const;
|
||||
|
||||
INLINE bool has_default_value() const;
|
||||
INLINE const std::string &get_default_value() const;
|
||||
INLINE const vector_uchar &get_default_value() const;
|
||||
|
||||
INLINE bool is_bogus_field() const;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ public:
|
|||
|
||||
INLINE void set_number(int number);
|
||||
INLINE void set_class(DCClass *dclass);
|
||||
INLINE void set_default_value(const std::string &default_value);
|
||||
INLINE void set_default_value(vector_uchar default_value);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
static std::string get_pystr(PyObject *value);
|
||||
|
|
@ -115,7 +115,7 @@ protected:
|
|||
bool _bogus_field;
|
||||
|
||||
private:
|
||||
std::string _default_value;
|
||||
vector_uchar _default_value;
|
||||
|
||||
#ifdef WITHIN_PANDA
|
||||
PStatCollector _field_update_pcollector;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
// Filename: dcLexer.lxx
|
||||
// Created by: drose (05Oct00)
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
|
|
@ -103,12 +103,12 @@ dcyyerror(const std::string &msg) {
|
|||
if (!dc_filename.empty()) {
|
||||
cerr << " in " << dc_filename;
|
||||
}
|
||||
cerr
|
||||
cerr
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
indent(cerr, col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
|
||||
error_count++;
|
||||
}
|
||||
|
||||
|
|
@ -120,10 +120,10 @@ dcyywarning(const std::string &msg) {
|
|||
if (!dc_filename.empty()) {
|
||||
cerr << " in " << dc_filename;
|
||||
}
|
||||
cerr
|
||||
cerr
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
indent(cerr, col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
warning_count++;
|
||||
|
|
@ -313,9 +313,9 @@ scan_quoted_string(char quote_mark) {
|
|||
|
||||
// scan_hex_string reads a string of hexadecimal digits delimited by
|
||||
// angle brackets and returns the representative string.
|
||||
static std::string
|
||||
static vector_uchar
|
||||
scan_hex_string() {
|
||||
std::string result;
|
||||
vector_uchar result;
|
||||
|
||||
// We don't touch the current line number and column number during
|
||||
// scanning, so that if we detect an error while scanning the string
|
||||
|
|
@ -345,24 +345,24 @@ scan_hex_string() {
|
|||
line_number = line;
|
||||
col_number = col;
|
||||
dcyyerror("Invalid hex digit.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
}
|
||||
|
||||
odd = !odd;
|
||||
if (odd) {
|
||||
last = value;
|
||||
} else {
|
||||
result += (char)((last << 4) | value);
|
||||
result.push_back((unsigned char)((last << 4) | value));
|
||||
}
|
||||
c = read_char(line, col);
|
||||
}
|
||||
|
||||
if (c == EOF) {
|
||||
dcyyerror("This hex string is unterminated.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
} else if (odd) {
|
||||
dcyyerror("Odd number of hex digits.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
}
|
||||
|
||||
line_number = line;
|
||||
|
|
@ -382,7 +382,7 @@ eat_c_comment() {
|
|||
int col = col_number;
|
||||
|
||||
int c, last_c;
|
||||
|
||||
|
||||
last_c = '\0';
|
||||
c = read_char(line, col);
|
||||
while (c != EOF && !(last_c == '*' && c == '/')) {
|
||||
|
|
@ -440,12 +440,12 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
yyless(1);
|
||||
}
|
||||
|
||||
[ \t\r] {
|
||||
[ \t\r] {
|
||||
// Eat whitespace.
|
||||
accept();
|
||||
}
|
||||
|
||||
"//".* {
|
||||
"//".* {
|
||||
// Eat C++-style comments.
|
||||
accept();
|
||||
}
|
||||
|
|
@ -453,7 +453,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
"/*" {
|
||||
// Eat C-style comments.
|
||||
accept();
|
||||
eat_c_comment();
|
||||
eat_c_comment();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -607,7 +607,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
return KW_CHAR;
|
||||
}
|
||||
|
||||
{UNSIGNED_INTEGERNUM} {
|
||||
{UNSIGNED_INTEGERNUM} {
|
||||
// An unsigned integer number.
|
||||
accept();
|
||||
|
||||
|
|
@ -626,11 +626,11 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
dcyylval.u.uint64 = next_value + (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
|
||||
return UNSIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{SIGNED_INTEGERNUM} {
|
||||
{SIGNED_INTEGERNUM} {
|
||||
// A signed integer number.
|
||||
accept();
|
||||
|
||||
|
|
@ -671,14 +671,14 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
dcyyerror("Number out of range.");
|
||||
dcyylval.u.int64 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return SIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{UNSIGNED_HEXNUM} {
|
||||
// A hexadecimal integer number.
|
||||
accept();
|
||||
accept();
|
||||
|
||||
// As above, we'll decode the hex string by hand.
|
||||
dcyylval.str = dcyytext;
|
||||
|
|
@ -700,15 +700,15 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
++p;
|
||||
}
|
||||
|
||||
return UNSIGNED_INTEGER;
|
||||
return UNSIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{REALNUM} {
|
||||
{REALNUM} {
|
||||
// A floating-point number.
|
||||
accept();
|
||||
dcyylval.u.real = patof(dcyytext);
|
||||
accept();
|
||||
dcyylval.u.real = patof(dcyytext);
|
||||
dcyylval.str = dcyytext;
|
||||
return REAL;
|
||||
return REAL;
|
||||
}
|
||||
|
||||
["] {
|
||||
|
|
@ -728,11 +728,11 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
[<] {
|
||||
// Long hex string.
|
||||
accept();
|
||||
dcyylval.str = scan_hex_string();
|
||||
dcyylval.bytes = scan_hex_string();
|
||||
return HEX_STRING;
|
||||
}
|
||||
|
||||
[A-Za-z_][A-Za-z_0-9]* {
|
||||
[A-Za-z_][A-Za-z_0-9]* {
|
||||
// Identifier or keyword.
|
||||
accept();
|
||||
dcyylval.str = dcyytext;
|
||||
|
|
@ -750,7 +750,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
|
||||
. {
|
||||
// Send any other printable character as itself.
|
||||
accept();
|
||||
accept();
|
||||
return dcyytext[0];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -217,16 +217,30 @@ pack_string(const std::string &value) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated string value into the stream, representing a single pre-
|
||||
* packed field element, or a whole group of field elements at once.
|
||||
* Packs the indicated numeric or string value into the stream.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
pack_literal_value(const std::string &value) {
|
||||
pack_blob(const vector_uchar &value) {
|
||||
nassertv(_mode == M_pack || _mode == M_repack);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
} else {
|
||||
_pack_data.append_data(value.data(), value.length());
|
||||
_current_field->pack_blob(_pack_data, value, _pack_error, _range_error);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated string value into the stream, representing a single pre-
|
||||
* packed field element, or a whole group of field elements at once.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
pack_literal_value(const vector_uchar &value) {
|
||||
nassertv(_mode == M_pack || _mode == M_repack);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
} else {
|
||||
_pack_data.append_data((const char *)value.data(), value.size());
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
|
@ -345,16 +359,36 @@ unpack_string() {
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the current binary data value from the stream.
|
||||
*/
|
||||
INLINE vector_uchar DCPacker::
|
||||
unpack_blob() {
|
||||
vector_uchar value;
|
||||
nassertr(_mode == M_unpack, value);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
|
||||
} else {
|
||||
_current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
|
||||
value, _pack_error, _range_error);
|
||||
advance();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the literal string that represents the packed value of the current
|
||||
* field, and advances the field pointer.
|
||||
*/
|
||||
INLINE std::string DCPacker::
|
||||
INLINE vector_uchar DCPacker::
|
||||
unpack_literal_value() {
|
||||
size_t start = _unpack_p;
|
||||
unpack_skip();
|
||||
nassertr(_unpack_p >= start, std::string());
|
||||
return std::string(_unpack_data + start, _unpack_p - start);
|
||||
nassertr(_unpack_p >= start, vector_uchar());
|
||||
return vector_uchar((const unsigned char *)_unpack_data + start,
|
||||
(const unsigned char *)_unpack_data + _unpack_p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -453,16 +487,33 @@ unpack_string(std::string &value) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the current numeric or string value from the stream.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
unpack_blob(vector_uchar &value) {
|
||||
nassertv(_mode == M_unpack);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
|
||||
} else {
|
||||
_current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
|
||||
value, _pack_error, _range_error);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the literal string that represents the packed value of the current
|
||||
* field, and advances the field pointer.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
unpack_literal_value(std::string &value) {
|
||||
unpack_literal_value(vector_uchar &value) {
|
||||
size_t start = _unpack_p;
|
||||
unpack_skip();
|
||||
nassertv(_unpack_p >= start);
|
||||
value.assign(_unpack_data + start, _unpack_p - start);
|
||||
value = vector_uchar((const unsigned char *)_unpack_data + start,
|
||||
(const unsigned char *)_unpack_data + _unpack_p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -541,6 +592,15 @@ get_string() const {
|
|||
return _pack_data.get_string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the packed data buffer as a bytes object. Also see get_data().
|
||||
*/
|
||||
INLINE vector_uchar DCPacker::
|
||||
get_bytes() const {
|
||||
const unsigned char *p = (const unsigned char *)_pack_data.get_data();
|
||||
return vector_uchar(p, p + _pack_data.get_length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of bytes in the unpack data buffer. This is the
|
||||
* buffer used when unpacking; it is separate from the pack data returned by
|
||||
|
|
@ -601,9 +661,9 @@ take_data() {
|
|||
* between packing sessions.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
append_data(const char *buffer, size_t size) {
|
||||
append_data(const unsigned char *buffer, size_t size) {
|
||||
nassertv(_mode == M_idle);
|
||||
_pack_data.append_data(buffer, size);
|
||||
_pack_data.append_data((const char *)buffer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -728,6 +788,16 @@ raw_pack_string(const std::string &value) {
|
|||
_pack_data.append_data(value.data(), value.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the data into the buffer between packing sessions.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
raw_pack_blob(const vector_uchar &value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value.size());
|
||||
_pack_data.append_data((const char *)value.data(), value.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the data from the buffer between unpacking sessions.
|
||||
*/
|
||||
|
|
@ -870,6 +940,16 @@ raw_unpack_string() {
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the data from the buffer between unpacking sessions.
|
||||
*/
|
||||
INLINE vector_uchar DCPacker::
|
||||
raw_unpack_blob() {
|
||||
vector_uchar value;
|
||||
raw_unpack_blob(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the data from the buffer between unpacking sessions.
|
||||
*/
|
||||
|
|
@ -971,6 +1051,24 @@ raw_unpack_string(std::string &value) {
|
|||
_unpack_p += string_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the data from the buffer between unpacking sessions.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_blob(vector_uchar &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != nullptr);
|
||||
unsigned int blob_size = raw_unpack_uint16();
|
||||
|
||||
if (_unpack_p + blob_size > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned char *p = (const unsigned char *)_unpack_data + _unpack_p;
|
||||
value = vector_uchar(p, p + blob_size);
|
||||
_unpack_p += blob_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances to the next field after a call to pack_value() or pop().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ end_pack() {
|
|||
* version of begin_unpack() that takes only one parameter.
|
||||
*/
|
||||
void DCPacker::
|
||||
set_unpack_data(const string &data) {
|
||||
set_unpack_data(const vector_uchar &data) {
|
||||
nassertv(_mode == M_idle);
|
||||
|
||||
char *buffer = new char[data.length()];
|
||||
memcpy(buffer, data.data(), data.length());
|
||||
set_unpack_data(buffer, data.length(), true);
|
||||
char *buffer = new char[data.size()];
|
||||
memcpy(buffer, data.data(), data.size());
|
||||
set_unpack_data(buffer, data.size(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -721,11 +721,11 @@ pack_object(PyObject *object) {
|
|||
pack_string(string(buffer, length));
|
||||
}
|
||||
} else if (PyBytes_Check(object)) {
|
||||
char *buffer;
|
||||
const unsigned char *buffer;
|
||||
Py_ssize_t length;
|
||||
PyBytes_AsStringAndSize(object, &buffer, &length);
|
||||
PyBytes_AsStringAndSize(object, (char **)&buffer, &length);
|
||||
if (buffer) {
|
||||
pack_string(string(buffer, length));
|
||||
pack_blob(vector_uchar(buffer, buffer + length));
|
||||
}
|
||||
#else
|
||||
} else if (PyString_Check(object) || PyUnicode_Check(object)) {
|
||||
|
|
@ -1118,9 +1118,9 @@ enquote_string(ostream &out, char quote_mark, const string &str) {
|
|||
* Outputs the indicated string as a hex constant.
|
||||
*/
|
||||
void DCPacker::
|
||||
output_hex_string(ostream &out, const string &str) {
|
||||
output_hex_string(ostream &out, const vector_uchar &str) {
|
||||
out << '<';
|
||||
for (string::const_iterator pi = str.begin();
|
||||
for (vector_uchar::const_iterator pi = str.begin();
|
||||
pi != str.end();
|
||||
++pi) {
|
||||
char buffer[10];
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ PUBLISHED:
|
|||
void begin_pack(const DCPackerInterface *root);
|
||||
bool end_pack();
|
||||
|
||||
void set_unpack_data(const std::string &data);
|
||||
void set_unpack_data(const vector_uchar &data);
|
||||
public:
|
||||
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data);
|
||||
|
|
@ -75,7 +75,8 @@ PUBLISHED:
|
|||
INLINE void pack_int64(int64_t value);
|
||||
INLINE void pack_uint64(uint64_t value);
|
||||
INLINE void pack_string(const std::string &value);
|
||||
INLINE void pack_literal_value(const std::string &value);
|
||||
INLINE void pack_blob(const vector_uchar &value);
|
||||
INLINE void pack_literal_value(const vector_uchar &value);
|
||||
void pack_default_value();
|
||||
|
||||
INLINE double unpack_double();
|
||||
|
|
@ -84,7 +85,8 @@ PUBLISHED:
|
|||
INLINE int64_t unpack_int64();
|
||||
INLINE uint64_t unpack_uint64();
|
||||
INLINE std::string unpack_string();
|
||||
INLINE std::string unpack_literal_value();
|
||||
INLINE vector_uchar unpack_blob();
|
||||
INLINE vector_uchar unpack_literal_value();
|
||||
void unpack_validate();
|
||||
void unpack_skip();
|
||||
|
||||
|
|
@ -97,7 +99,8 @@ public:
|
|||
INLINE void unpack_int64(int64_t &value);
|
||||
INLINE void unpack_uint64(uint64_t &value);
|
||||
INLINE void unpack_string(std::string &value);
|
||||
INLINE void unpack_literal_value(std::string &value);
|
||||
INLINE void unpack_blob(vector_uchar &value);
|
||||
INLINE void unpack_literal_value(vector_uchar &value);
|
||||
|
||||
PUBLISHED:
|
||||
|
||||
|
|
@ -119,6 +122,7 @@ PUBLISHED:
|
|||
|
||||
INLINE size_t get_length() const;
|
||||
INLINE std::string get_string() const;
|
||||
INLINE vector_uchar get_bytes() const;
|
||||
INLINE size_t get_unpack_length() const;
|
||||
INLINE std::string get_unpack_string() const;
|
||||
public:
|
||||
|
|
@ -126,7 +130,7 @@ public:
|
|||
INLINE const char *get_data() const;
|
||||
INLINE char *take_data();
|
||||
|
||||
INLINE void append_data(const char *buffer, size_t size);
|
||||
INLINE void append_data(const unsigned char *buffer, size_t size);
|
||||
INLINE char *get_write_pointer(size_t size);
|
||||
|
||||
INLINE const char *get_unpack_data() const;
|
||||
|
|
@ -148,6 +152,7 @@ PUBLISHED:
|
|||
INLINE void raw_pack_uint64(uint64_t value);
|
||||
INLINE void raw_pack_float64(double value);
|
||||
INLINE void raw_pack_string(const std::string &value);
|
||||
INLINE void raw_pack_blob(const vector_uchar &value);
|
||||
|
||||
// this is a hack to allw me to get in and out of 32bit Mode Faster need to
|
||||
// agree with channel_type in dcbase.h
|
||||
|
|
@ -165,6 +170,7 @@ PUBLISHED:
|
|||
INLINE uint64_t raw_unpack_uint64();
|
||||
INLINE double raw_unpack_float64();
|
||||
INLINE std::string raw_unpack_string();
|
||||
INLINE vector_uchar raw_unpack_blob();
|
||||
|
||||
public:
|
||||
INLINE void raw_unpack_int8(int &value);
|
||||
|
|
@ -177,10 +183,11 @@ public:
|
|||
INLINE void raw_unpack_uint64(uint64_t &value);
|
||||
INLINE void raw_unpack_float64(double &value);
|
||||
INLINE void raw_unpack_string(std::string &value);
|
||||
INLINE void raw_unpack_blob(vector_uchar &value);
|
||||
|
||||
public:
|
||||
static void enquote_string(std::ostream &out, char quote_mark, const std::string &str);
|
||||
static void output_hex_string(std::ostream &out, const std::string &str);
|
||||
static void output_hex_string(std::ostream &out, const vector_uchar &str);
|
||||
|
||||
private:
|
||||
INLINE void advance();
|
||||
|
|
|
|||
|
|
@ -248,6 +248,14 @@ pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
|
|||
pack_error = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the indicated numeric or string value into the stream.
|
||||
*/
|
||||
void DCPackerInterface::
|
||||
pack_blob(DCPackData &, const vector_uchar &, bool &pack_error, bool &) const {
|
||||
pack_error = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the field's specified default value (or a sensible default if no
|
||||
* value is specified) into the stream. Returns true if the default value is
|
||||
|
|
@ -306,6 +314,14 @@ unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool &
|
|||
pack_error = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the current numeric or string value from the stream.
|
||||
*/
|
||||
void DCPackerInterface::
|
||||
unpack_blob(const char *, size_t, size_t &, vector_uchar &, bool &pack_error, bool &) const {
|
||||
pack_error = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally unpacks the current numeric or string value and validates it
|
||||
* against the type range limits, but does not return the value. Returns true
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCField;
|
||||
|
|
@ -37,8 +38,8 @@ enum DCPackType {
|
|||
|
||||
// These PackTypes are all fundamental types, and should be packed (or
|
||||
// unpacked) with the corresponding call to pack_double(), pack_int(), etc.
|
||||
// PT_blob is the same as PT_string, but implies that the string contains
|
||||
// binary data.
|
||||
// PT_blob is similar to PT_string, except that it contains arbitrary binary
|
||||
// data instead of just UTF-8 text.
|
||||
PT_double,
|
||||
PT_int,
|
||||
PT_uint,
|
||||
|
|
@ -113,6 +114,8 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
virtual void unpack_double(const char *data, size_t length, size_t &p,
|
||||
|
|
@ -127,6 +130,8 @@ public:
|
|||
uint64_t &value, bool &pack_error, bool &range_error) const;
|
||||
virtual void unpack_string(const char *data, size_t length, size_t &p,
|
||||
std::string &value, bool &pack_error, bool &range_error) const;
|
||||
virtual void unpack_blob(const char *data, size_t length, size_t &p,
|
||||
vector_uchar &value, bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_validate(const char *data, size_t length, size_t &p,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_skip(const char *data, size_t length, size_t &p,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,20 +1,19 @@
|
|||
/* A Bison parser, made by GNU Bison 2.4.2. */
|
||||
/* A Bison parser, made by GNU Bison 3.1. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
|
@ -27,66 +26,74 @@
|
|||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
|
||||
# define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int dcyydebug;
|
||||
#endif
|
||||
|
||||
/* Tokens. */
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
UNSIGNED_INTEGER = 258,
|
||||
SIGNED_INTEGER = 259,
|
||||
REAL = 260,
|
||||
STRING = 261,
|
||||
HEX_STRING = 262,
|
||||
IDENTIFIER = 263,
|
||||
KEYWORD = 264,
|
||||
KW_DCLASS = 265,
|
||||
KW_STRUCT = 266,
|
||||
KW_FROM = 267,
|
||||
KW_IMPORT = 268,
|
||||
KW_TYPEDEF = 269,
|
||||
KW_KEYWORD = 270,
|
||||
KW_SWITCH = 271,
|
||||
KW_CASE = 272,
|
||||
KW_DEFAULT = 273,
|
||||
KW_BREAK = 274,
|
||||
KW_INT8 = 275,
|
||||
KW_INT16 = 276,
|
||||
KW_INT32 = 277,
|
||||
KW_INT64 = 278,
|
||||
KW_UINT8 = 279,
|
||||
KW_UINT16 = 280,
|
||||
KW_UINT32 = 281,
|
||||
KW_UINT64 = 282,
|
||||
KW_FLOAT64 = 283,
|
||||
KW_STRING = 284,
|
||||
KW_BLOB = 285,
|
||||
KW_BLOB32 = 286,
|
||||
KW_INT8ARRAY = 287,
|
||||
KW_INT16ARRAY = 288,
|
||||
KW_INT32ARRAY = 289,
|
||||
KW_UINT8ARRAY = 290,
|
||||
KW_UINT16ARRAY = 291,
|
||||
KW_UINT32ARRAY = 292,
|
||||
KW_UINT32UINT8ARRAY = 293,
|
||||
KW_CHAR = 294,
|
||||
START_DC = 295,
|
||||
START_PARAMETER_VALUE = 296,
|
||||
START_PARAMETER_DESCRIPTION = 297
|
||||
};
|
||||
enum yytokentype
|
||||
{
|
||||
UNSIGNED_INTEGER = 258,
|
||||
SIGNED_INTEGER = 259,
|
||||
REAL = 260,
|
||||
STRING = 261,
|
||||
IDENTIFIER = 262,
|
||||
HEX_STRING = 263,
|
||||
KEYWORD = 264,
|
||||
KW_DCLASS = 265,
|
||||
KW_STRUCT = 266,
|
||||
KW_FROM = 267,
|
||||
KW_IMPORT = 268,
|
||||
KW_TYPEDEF = 269,
|
||||
KW_KEYWORD = 270,
|
||||
KW_SWITCH = 271,
|
||||
KW_CASE = 272,
|
||||
KW_DEFAULT = 273,
|
||||
KW_BREAK = 274,
|
||||
KW_INT8 = 275,
|
||||
KW_INT16 = 276,
|
||||
KW_INT32 = 277,
|
||||
KW_INT64 = 278,
|
||||
KW_UINT8 = 279,
|
||||
KW_UINT16 = 280,
|
||||
KW_UINT32 = 281,
|
||||
KW_UINT64 = 282,
|
||||
KW_FLOAT64 = 283,
|
||||
KW_STRING = 284,
|
||||
KW_BLOB = 285,
|
||||
KW_BLOB32 = 286,
|
||||
KW_INT8ARRAY = 287,
|
||||
KW_INT16ARRAY = 288,
|
||||
KW_INT32ARRAY = 289,
|
||||
KW_UINT8ARRAY = 290,
|
||||
KW_UINT16ARRAY = 291,
|
||||
KW_UINT32ARRAY = 292,
|
||||
KW_UINT32UINT8ARRAY = 293,
|
||||
KW_CHAR = 294,
|
||||
START_DC = 295,
|
||||
START_PARAMETER_VALUE = 296,
|
||||
START_PARAMETER_DESCRIPTION = 297
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define UNSIGNED_INTEGER 258
|
||||
#define SIGNED_INTEGER 259
|
||||
#define REAL 260
|
||||
#define STRING 261
|
||||
#define HEX_STRING 262
|
||||
#define IDENTIFIER 263
|
||||
#define IDENTIFIER 262
|
||||
#define HEX_STRING 263
|
||||
#define KEYWORD 264
|
||||
#define KW_DCLASS 265
|
||||
#define KW_STRUCT 266
|
||||
|
|
@ -122,15 +129,11 @@
|
|||
#define START_PARAMETER_VALUE 296
|
||||
#define START_PARAMETER_DESCRIPTION 297
|
||||
|
||||
/* Value type. */
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE dcyylval;
|
||||
|
||||
int dcyyparse (void);
|
||||
|
||||
#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ dc_init_parser(istream &in, const string &filename, DCFile &file) {
|
|||
}
|
||||
|
||||
void
|
||||
dc_init_parser_parameter_value(istream &in, const string &filename,
|
||||
dc_init_parser_parameter_value(istream &in, const string &filename,
|
||||
DCPacker &packer) {
|
||||
dc_file = nullptr;
|
||||
current_packer = &packer;
|
||||
|
|
@ -89,15 +89,16 @@ dc_cleanup_parser() {
|
|||
%token <u.uint64> UNSIGNED_INTEGER
|
||||
%token <u.int64> SIGNED_INTEGER
|
||||
%token <u.real> REAL
|
||||
%token <str> STRING HEX_STRING IDENTIFIER
|
||||
%token <str> STRING IDENTIFIER
|
||||
%token <bytes> HEX_STRING
|
||||
%token <u.keyword> KEYWORD
|
||||
|
||||
%token KW_DCLASS
|
||||
%token KW_STRUCT
|
||||
%token KW_FROM
|
||||
%token KW_IMPORT
|
||||
%token KW_TYPEDEF
|
||||
%token KW_KEYWORD
|
||||
%token KW_DCLASS
|
||||
%token KW_STRUCT
|
||||
%token KW_FROM
|
||||
%token KW_IMPORT
|
||||
%token KW_TYPEDEF
|
||||
%token KW_KEYWORD
|
||||
%token KW_SWITCH
|
||||
%token KW_CASE
|
||||
%token KW_DEFAULT
|
||||
|
|
@ -224,7 +225,7 @@ import:
|
|||
{
|
||||
dc_file->add_import_module($2);
|
||||
}
|
||||
| KW_FROM import_identifier KW_IMPORT
|
||||
| KW_FROM import_identifier KW_IMPORT
|
||||
{
|
||||
dc_file->add_import_module($2);
|
||||
}
|
||||
|
|
@ -255,7 +256,7 @@ typedef_decl:
|
|||
{
|
||||
if ($2 != nullptr) {
|
||||
DCTypedef *dtypedef = new DCTypedef($2);
|
||||
|
||||
|
||||
if (!dc_file->add_typedef(dtypedef)) {
|
||||
DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
|
||||
if (old_typedef->is_bogus_typedef()) {
|
||||
|
|
@ -294,7 +295,7 @@ dclass_or_struct:
|
|||
;
|
||||
|
||||
dclass:
|
||||
KW_DCLASS optional_name
|
||||
KW_DCLASS optional_name
|
||||
{
|
||||
current_class = new DCClass(dc_file, $2, false, false);
|
||||
}
|
||||
|
|
@ -322,7 +323,7 @@ dclass_name:
|
|||
if (dclass->is_struct()) {
|
||||
yyerror("struct name not allowed");
|
||||
}
|
||||
|
||||
|
||||
$$ = dclass;
|
||||
}
|
||||
}
|
||||
|
|
@ -398,7 +399,7 @@ dclass_field:
|
|||
;
|
||||
|
||||
struct:
|
||||
KW_STRUCT optional_name
|
||||
KW_STRUCT optional_name
|
||||
{
|
||||
current_class = new DCClass(dc_file, $2, true, false);
|
||||
}
|
||||
|
|
@ -426,7 +427,7 @@ struct_name:
|
|||
if (!dstruct->is_struct()) {
|
||||
yyerror("struct name required");
|
||||
}
|
||||
|
||||
|
||||
$$ = dstruct;
|
||||
}
|
||||
}
|
||||
|
|
@ -538,7 +539,7 @@ unnamed_parameter:
|
|||
|
||||
named_parameter_with_default:
|
||||
named_parameter
|
||||
| named_parameter '='
|
||||
| named_parameter '='
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
|
|
@ -553,7 +554,7 @@ named_parameter_with_default:
|
|||
is_valid = $1->is_valid();
|
||||
}
|
||||
if (current_packer->end_pack()) {
|
||||
$1->set_default_value(current_packer->get_string());
|
||||
$1->set_default_value(current_packer->get_bytes());
|
||||
|
||||
} else {
|
||||
if (is_valid) {
|
||||
|
|
@ -568,7 +569,7 @@ named_parameter_with_default:
|
|||
|
||||
unnamed_parameter_with_default:
|
||||
unnamed_parameter
|
||||
| unnamed_parameter '='
|
||||
| unnamed_parameter '='
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
|
|
@ -583,7 +584,7 @@ unnamed_parameter_with_default:
|
|||
is_valid = $1->is_valid();
|
||||
}
|
||||
if (current_packer->end_pack()) {
|
||||
$1->set_default_value(current_packer->get_string());
|
||||
$1->set_default_value(current_packer->get_bytes());
|
||||
|
||||
} else {
|
||||
if (is_valid) {
|
||||
|
|
@ -663,7 +664,7 @@ simple_type_name:
|
|||
$$ = simple_param;
|
||||
}
|
||||
| simple_type_name '%' number
|
||||
{
|
||||
{
|
||||
DCSimpleParameter *simple_param = $1->as_simple_parameter();
|
||||
nassertr(simple_param != nullptr, 0);
|
||||
if (!simple_param->is_numeric_type()) {
|
||||
|
|
@ -703,10 +704,10 @@ type_name:
|
|||
dtypedef = new DCTypedef($1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dc_file->add_typedef(dtypedef);
|
||||
}
|
||||
|
||||
|
||||
$$ = dtypedef->make_new_parameter();
|
||||
}
|
||||
}
|
||||
|
|
@ -974,7 +975,7 @@ parameter_value:
|
|||
{
|
||||
if ($1 != current_packer->get_current_field_name()) {
|
||||
ostringstream strm;
|
||||
strm << "Got '" << $1 << "', expected '"
|
||||
strm << "Got '" << $1 << "', expected '"
|
||||
<< current_packer->get_current_field_name() << "'";
|
||||
yyerror(strm.str());
|
||||
}
|
||||
|
|
@ -1005,7 +1006,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pack_literal_value($1);
|
||||
}
|
||||
| '{'
|
||||
| '{'
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1013,7 +1014,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pop();
|
||||
}
|
||||
| '['
|
||||
| '['
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1021,7 +1022,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pop();
|
||||
}
|
||||
| '('
|
||||
| '('
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1223,7 +1224,7 @@ molecular_atom_list:
|
|||
if ($3 != nullptr) {
|
||||
current_molecular->add_atomic($3);
|
||||
if (!$3->is_bogus_field() && !current_molecular->compare_keywords(*$3)) {
|
||||
yyerror("Mismatched keywords in molecule between " +
|
||||
yyerror("Mismatched keywords in molecule between " +
|
||||
current_molecular->get_atomic(0)->get_name() + " and " +
|
||||
$3->get_name());
|
||||
}
|
||||
|
|
@ -1283,7 +1284,7 @@ switch_case:
|
|||
yyerror("Invalid value for switch parameter");
|
||||
current_switch->add_invalid_case();
|
||||
} else {
|
||||
int case_index = current_switch->add_case(current_packer->get_string());
|
||||
int case_index = current_switch->add_case(current_packer->get_bytes());
|
||||
if (case_index == -1) {
|
||||
yyerror("Duplicate case value");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCClass;
|
||||
|
|
@ -61,6 +62,7 @@ public:
|
|||
const DCKeyword *keyword;
|
||||
} u;
|
||||
std::string str;
|
||||
vector_uchar bytes;
|
||||
};
|
||||
|
||||
// The yacc-generated code expects to use the symbol 'YYSTYPE' to refer to the
|
||||
|
|
|
|||
|
|
@ -1069,6 +1069,52 @@ pack_string(DCPackData &pack_data, const string &value,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the indicated numeric or string value into the stream.
|
||||
*/
|
||||
void DCSimpleParameter::
|
||||
pack_blob(DCPackData &pack_data, const vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const {
|
||||
size_t blob_size = value.size();
|
||||
|
||||
switch (_type) {
|
||||
case ST_char:
|
||||
case ST_uint8:
|
||||
case ST_int8:
|
||||
if (blob_size == 0) {
|
||||
pack_error = true;
|
||||
} else {
|
||||
if (blob_size != 1) {
|
||||
range_error = true;
|
||||
}
|
||||
_uint_range.validate((unsigned int)value[0], range_error);
|
||||
do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)value[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_string:
|
||||
case ST_blob:
|
||||
_uint_range.validate(blob_size, range_error);
|
||||
validate_uint_limits(blob_size, 16, range_error);
|
||||
if (_num_length_bytes != 0) {
|
||||
do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
|
||||
}
|
||||
pack_data.append_data((const char *)value.data(), blob_size);
|
||||
break;
|
||||
|
||||
case ST_blob32:
|
||||
_uint_range.validate(blob_size, range_error);
|
||||
if (_num_length_bytes != 0) {
|
||||
do_pack_uint32(pack_data.get_write_pointer(4), blob_size);
|
||||
}
|
||||
pack_data.append_data((const char *)value.data(), blob_size);
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the simpleParameter's specified default value (or a sensible default
|
||||
* if no value is specified) into the stream. Returns true if the default
|
||||
|
|
@ -1937,6 +1983,79 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the current numeric or string value from the stream.
|
||||
*/
|
||||
void DCSimpleParameter::
|
||||
unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const {
|
||||
// If the type is a single byte, unpack it into a string of length 1.
|
||||
switch (_type) {
|
||||
case ST_char:
|
||||
case ST_int8:
|
||||
case ST_uint8:
|
||||
{
|
||||
if (p + 1 > length) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
unsigned int int_value = do_unpack_uint8(data + p);
|
||||
_uint_range.validate(int_value, range_error);
|
||||
value.resize(1);
|
||||
value[0] = int_value;
|
||||
p++;
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
size_t blob_size;
|
||||
|
||||
if (_num_length_bytes == 0) {
|
||||
blob_size = _fixed_byte_size;
|
||||
|
||||
} else {
|
||||
switch (_type) {
|
||||
case ST_string:
|
||||
case ST_blob:
|
||||
if (p + 2 > length) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
blob_size = do_unpack_uint16(data + p);
|
||||
p += 2;
|
||||
break;
|
||||
|
||||
case ST_blob32:
|
||||
if (p + 4 > length) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
blob_size = do_unpack_uint32(data + p);
|
||||
p += 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_uint_range.validate(blob_size, range_error);
|
||||
|
||||
if (p + blob_size > length) {
|
||||
pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = vector_uchar((const unsigned char *)data + p,
|
||||
(const unsigned char *)data + p + blob_size);
|
||||
p += blob_size;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally unpacks the current numeric or string value and validates it
|
||||
* against the type range limits, but does not return the value. Returns true
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
virtual void unpack_double(const char *data, size_t length, size_t &p,
|
||||
|
|
@ -76,6 +78,8 @@ public:
|
|||
uint64_t &value, bool &pack_error, bool &range_error) const;
|
||||
virtual void unpack_string(const char *data, size_t length, size_t &p,
|
||||
std::string &value, bool &pack_error, bool &range_error) const;
|
||||
virtual void unpack_blob(const char *data, size_t length, size_t &p,
|
||||
vector_uchar &value, bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_validate(const char *data, size_t length, size_t &p,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_skip(const char *data, size_t length, size_t &p,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ get_num_cases() const {
|
|||
* if no case has this value.
|
||||
*/
|
||||
int DCSwitch::
|
||||
get_case_by_value(const string &case_value) const {
|
||||
get_case_by_value(const vector_uchar &case_value) const {
|
||||
CasesByValue::const_iterator vi;
|
||||
vi = _cases_by_value.find(case_value);
|
||||
if (vi != _cases_by_value.end()) {
|
||||
|
|
@ -140,9 +140,9 @@ get_default_case() const {
|
|||
/**
|
||||
* Returns the packed value associated with the indicated case.
|
||||
*/
|
||||
string DCSwitch::
|
||||
vector_uchar DCSwitch::
|
||||
get_value(int case_index) const {
|
||||
nassertr(case_index >= 0 && case_index < (int)_cases.size(), string());
|
||||
nassertr(case_index >= 0 && case_index < (int)_cases.size(), vector_uchar());
|
||||
return _cases[case_index]->_value;
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ is_field_valid() const {
|
|||
* -1. This is normally called only by the parser.
|
||||
*/
|
||||
int DCSwitch::
|
||||
add_case(const string &value) {
|
||||
add_case(const vector_uchar &value) {
|
||||
int case_index = (int)_cases.size();
|
||||
if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
|
||||
add_invalid_case();
|
||||
|
|
@ -283,7 +283,8 @@ add_break() {
|
|||
const DCPackerInterface *DCSwitch::
|
||||
apply_switch(const char *value_data, size_t length) const {
|
||||
CasesByValue::const_iterator vi;
|
||||
vi = _cases_by_value.find(string(value_data, length));
|
||||
vi = _cases_by_value.find(vector_uchar((const unsigned char *)value_data,
|
||||
(const unsigned char *)value_data + length));
|
||||
if (vi != _cases_by_value.end()) {
|
||||
return _cases[(*vi).second]->_fields;
|
||||
}
|
||||
|
|
@ -421,7 +422,7 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
Cases::const_iterator ci;
|
||||
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
|
||||
const SwitchCase *dcase = (*ci);
|
||||
hashgen.add_string(dcase->_value);
|
||||
hashgen.add_blob(dcase->_value);
|
||||
|
||||
const SwitchFields *fields = dcase->_fields;
|
||||
hashgen.add_int(fields->_fields.size());
|
||||
|
|
@ -702,7 +703,7 @@ do_check_match(const DCPackerInterface *) const {
|
|||
*
|
||||
*/
|
||||
DCSwitch::SwitchCase::
|
||||
SwitchCase(const string &value, DCSwitch::SwitchFields *fields) :
|
||||
SwitchCase(const vector_uchar &value, DCSwitch::SwitchFields *fields) :
|
||||
_value(value),
|
||||
_fields(fields)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,18 +40,18 @@ PUBLISHED:
|
|||
DCField *get_key_parameter() const;
|
||||
|
||||
int get_num_cases() const;
|
||||
int get_case_by_value(const std::string &case_value) const;
|
||||
int get_case_by_value(const vector_uchar &case_value) const;
|
||||
DCPackerInterface *get_case(int n) const;
|
||||
DCPackerInterface *get_default_case() const;
|
||||
|
||||
std::string get_value(int case_index) const;
|
||||
vector_uchar get_value(int case_index) const;
|
||||
int get_num_fields(int case_index) const;
|
||||
DCField *get_field(int case_index, int n) const;
|
||||
DCField *get_field_by_name(int case_index, const std::string &name) const;
|
||||
|
||||
public:
|
||||
bool is_field_valid() const;
|
||||
int add_case(const std::string &value);
|
||||
int add_case(const vector_uchar &value);
|
||||
void add_invalid_case();
|
||||
bool add_default();
|
||||
bool add_field(DCField *field);
|
||||
|
|
@ -98,13 +98,13 @@ public:
|
|||
|
||||
class SwitchCase {
|
||||
public:
|
||||
SwitchCase(const std::string &value, SwitchFields *fields);
|
||||
SwitchCase(const vector_uchar &value, SwitchFields *fields);
|
||||
~SwitchCase();
|
||||
|
||||
bool do_check_match_switch_case(const SwitchCase *other) const;
|
||||
|
||||
public:
|
||||
std::string _value;
|
||||
vector_uchar _value;
|
||||
SwitchFields *_fields;
|
||||
};
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ private:
|
|||
bool _fields_added;
|
||||
|
||||
// This map indexes into the _cases vector, above.
|
||||
typedef pmap<std::string, int> CasesByValue;
|
||||
typedef pmap<vector_uchar, int> CasesByValue;
|
||||
CasesByValue _cases_by_value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,18 @@ add_string(const std::string &str) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blob to the hash, by breaking it down into a sequence of integers.
|
||||
*/
|
||||
void HashGenerator::
|
||||
add_blob(const vector_uchar &bytes) {
|
||||
add_int(bytes.size());
|
||||
vector_uchar::const_iterator bi;
|
||||
for (bi = bytes.begin(); bi != bytes.end(); ++bi) {
|
||||
add_int(*bi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash number generated.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "primeNumberGenerator.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
/**
|
||||
* This class generates an arbitrary hash number from a sequence of ints.
|
||||
|
|
@ -26,6 +27,7 @@ public:
|
|||
|
||||
void add_int(int num);
|
||||
void add_string(const std::string &str);
|
||||
void add_blob(const vector_uchar &bytes);
|
||||
|
||||
unsigned long get_hash() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -797,7 +797,15 @@ EXCLUDE = dtool/src/parser-inc \
|
|||
panda/src/linmath/fltnames.h \
|
||||
panda/src/linmath/dblnames.h \
|
||||
panda/src/linmath/dbl2fltnames.h \
|
||||
panda/src/linmath/flt2dblnames.h
|
||||
panda/src/linmath/flt2dblnames.h \
|
||||
panda/src/android \
|
||||
panda/src/iphone \
|
||||
panda/src/tinydisplay \
|
||||
panda/src/movies/dr_flac.h \
|
||||
dtool/src/dtoolbase/pdtoa.cxx \
|
||||
dtool/src/dtoolutil/panda_getopt_long.h \
|
||||
dtool/src/dtoolutil/panda_getopt_impl.h \
|
||||
dtool/src/dtoolutil/panda_getopt_impl.cxx
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
|
|
@ -1972,7 +1980,13 @@ PREDEFINED = TVOLATILE= \
|
|||
EXTEND= \
|
||||
ALLOC_DELETED_CHAIN(x)= \
|
||||
BLOCKING= \
|
||||
TYPENAME=typename
|
||||
TYPENAME=typename \
|
||||
MAKE_PROPERTY(x)= \
|
||||
MAKE_PROPERTY2(x)= \
|
||||
MAKE_SEQ(x)= \
|
||||
MAKE_SEQ_PROPERTY(x)= \
|
||||
MAKE_MAP_PROPERTY(x)= \
|
||||
MAKE_MAP_KEYS_SEQ(x)=
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
|
|
|
|||
|
|
@ -665,7 +665,9 @@ EXCLUDE_SYMLINKS = NO
|
|||
# for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS = */Opt*-*/* \
|
||||
*/CVS/*
|
||||
*/CVS/* \
|
||||
*/.git/* \
|
||||
*/__pycache__/*
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
|
|
|
|||
|
|
@ -9,9 +9,20 @@ from __future__ import print_function
|
|||
|
||||
__all__ = []
|
||||
|
||||
import os
|
||||
import os, sys
|
||||
from distutils import sysconfig
|
||||
import panda3d, pandac
|
||||
from panda3d.dtoolconfig import *
|
||||
from panda3d.interrogatedb import *
|
||||
|
||||
|
||||
if 'interrogate_element_is_sequence' not in globals():
|
||||
def interrogate_element_is_sequence(element):
|
||||
return False
|
||||
|
||||
if 'interrogate_element_is_mapping' not in globals():
|
||||
def interrogate_element_is_mapping(element):
|
||||
return False
|
||||
|
||||
|
||||
LICENSE = """PANDA 3D SOFTWARE
|
||||
Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
|
|
@ -19,6 +30,16 @@ 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.\"""".split("\n")
|
||||
|
||||
MAINPAGE = """@mainpage Panda3D Python API Reference
|
||||
Welcome to the Panda3D API reference.
|
||||
|
||||
Use the links at the top of this page to browse through the list of modules or
|
||||
the list of classes.
|
||||
|
||||
This reference is automatically generated from comments in the source code.
|
||||
"""
|
||||
|
||||
|
||||
def comment(code):
|
||||
if not code:
|
||||
return ""
|
||||
|
|
@ -45,49 +66,16 @@ def comment(code):
|
|||
return ''
|
||||
|
||||
def block_comment(code):
|
||||
if not code:
|
||||
code = code.strip()
|
||||
|
||||
if not code.startswith('///<') and '@verbatim' not in code:
|
||||
code = code.replace('<', '\\<').replace('>', '\\>')
|
||||
|
||||
if not code or code[0] != '/':
|
||||
# Not really a comment; get rid of it.
|
||||
return ""
|
||||
|
||||
lines = code.split("\n")
|
||||
newlines = []
|
||||
indent = 0
|
||||
reading_desc = False
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("////"):
|
||||
continue
|
||||
|
||||
line = line.rstrip()
|
||||
strline = line.lstrip('/ \t')
|
||||
|
||||
if ':' in strline:
|
||||
pre, post = strline.split(':', 1)
|
||||
pre = pre.rstrip()
|
||||
if pre == "Description":
|
||||
strline = post.lstrip()
|
||||
elif pre in ("Class", "Access", "Function", "Created by", "Enum"):
|
||||
continue
|
||||
|
||||
if strline or len(newlines) > 0:
|
||||
newlines.append('/// ' + strline)
|
||||
|
||||
#if reading_desc:
|
||||
# newlines.append('/// ' + line[min(indent, len(line) - len(strline)):])
|
||||
#else:
|
||||
# # A "Description:" text starts the description.
|
||||
# if strline.startswith("Description"):
|
||||
# strline = strline[11:].lstrip(': \t')
|
||||
# indent = len(line) - len(strline)
|
||||
# reading_desc = True
|
||||
# newlines.append('/// ' + strline)
|
||||
# else:
|
||||
# print line
|
||||
|
||||
newcode = '\n'.join(newlines)
|
||||
if len(newcode) > 0:
|
||||
return newcode
|
||||
else:
|
||||
return ""
|
||||
return code
|
||||
|
||||
def translateFunctionName(name):
|
||||
if name.startswith("__"):
|
||||
|
|
@ -139,11 +127,17 @@ def translated_type_name(type, scoped=True):
|
|||
return "object"
|
||||
elif typename == "PN_stdfloat":
|
||||
return "float"
|
||||
elif typename == "size_t":
|
||||
return "int"
|
||||
|
||||
if interrogate_type_is_atomic(type):
|
||||
token = interrogate_type_atomic_token(type)
|
||||
if token == 7:
|
||||
return 'str'
|
||||
elif token == 8:
|
||||
return 'long'
|
||||
elif token == 9:
|
||||
return 'NoneType'
|
||||
else:
|
||||
return typename
|
||||
|
||||
|
|
@ -156,12 +150,25 @@ def translated_type_name(type, scoped=True):
|
|||
else:
|
||||
return typename
|
||||
|
||||
|
||||
def processElement(handle, element):
|
||||
if interrogate_element_has_comment(element):
|
||||
print(comment(interrogate_element_comment(element)), file=handle)
|
||||
elif interrogate_element_has_getter(element):
|
||||
# If the property has no comment, use the comment of the getter.
|
||||
getter = interrogate_element_getter(element)
|
||||
if interrogate_function_has_comment(getter):
|
||||
print(block_comment(interrogate_function_comment(getter)), file=handle)
|
||||
|
||||
if interrogate_element_is_mapping(element) or \
|
||||
interrogate_element_is_sequence(element):
|
||||
suffix = "[]"
|
||||
else:
|
||||
suffix = ""
|
||||
|
||||
print(translated_type_name(interrogate_element_type(element)), end=' ', file=handle)
|
||||
print(interrogate_element_name(element) + ';', file=handle)
|
||||
print(interrogate_element_name(element) + suffix + ';', file=handle)
|
||||
|
||||
|
||||
def processFunction(handle, function, isConstructor = False):
|
||||
for i_wrapper in range(interrogate_function_number_of_python_wrappers(function)):
|
||||
|
|
@ -195,6 +202,7 @@ def processFunction(handle, function, isConstructor = False):
|
|||
|
||||
print(");", file=handle)
|
||||
|
||||
|
||||
def processType(handle, type):
|
||||
typename = translated_type_name(type, scoped=False)
|
||||
derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
|
||||
|
|
@ -211,8 +219,10 @@ def processType(handle, type):
|
|||
print(interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ",", file=handle)
|
||||
|
||||
elif interrogate_type_is_typedef(type):
|
||||
wrapped_type = translated_type_name(interrogate_type_wrapped_type(type))
|
||||
print("typedef %s %s;" % (wrapped_type, typename), file=handle)
|
||||
wrapped_type = interrogate_type_wrapped_type(type)
|
||||
if interrogate_type_is_global(wrapped_type):
|
||||
wrapped_type_name = translated_type_name(wrapped_type)
|
||||
print("typedef %s %s;" % (wrapped_type_name, typename), file=handle)
|
||||
return
|
||||
else:
|
||||
if interrogate_type_is_struct(type):
|
||||
|
|
@ -249,6 +259,7 @@ def processType(handle, type):
|
|||
print("};", file=handle)
|
||||
|
||||
def processModule(handle, package):
|
||||
print("Processing module %s" % (package))
|
||||
print("namespace %s {" % package, file=handle)
|
||||
|
||||
if package != "core":
|
||||
|
|
@ -280,22 +291,39 @@ def processModule(handle, package):
|
|||
if __name__ == "__main__":
|
||||
handle = open("pandadoc.hpp", "w")
|
||||
|
||||
mainpage = MAINPAGE.strip()
|
||||
if mainpage:
|
||||
print("/**\n * " + mainpage.replace('\n', '\n * ') + '\n */', file=handle)
|
||||
|
||||
print(comment("Panda3D modules that are implemented in C++."), file=handle)
|
||||
print("namespace panda3d {", file=handle)
|
||||
|
||||
# Determine the path to the interrogatedb files
|
||||
interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "..", "..", "etc"))
|
||||
interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "input"))
|
||||
pandac = os.path.dirname(pandac.__file__)
|
||||
interrogate_add_search_directory(os.path.join(pandac, "..", "..", "etc"))
|
||||
interrogate_add_search_directory(os.path.join(pandac, "input"))
|
||||
|
||||
import panda3d.core
|
||||
processModule(handle, "core")
|
||||
|
||||
# Determine the suffix for the extension modules.
|
||||
if sys.version_info >= (3, 0):
|
||||
import _imp
|
||||
ext_suffix = _imp.extension_suffixes()[0]
|
||||
elif sys.platform == "win32":
|
||||
ext_suffix = ".pyd"
|
||||
else:
|
||||
ext_suffix = ".so"
|
||||
|
||||
for lib in os.listdir(os.path.dirname(panda3d.__file__)):
|
||||
if lib.endswith(('.pyd', '.so')) and not lib.startswith('core.'):
|
||||
module_name = os.path.splitext(lib)[0]
|
||||
if lib.endswith(ext_suffix) and not lib.startswith('core.'):
|
||||
module_name = lib[:-len(ext_suffix)]
|
||||
__import__("panda3d." + module_name)
|
||||
processModule(handle, module_name)
|
||||
|
||||
|
||||
print("}", file=handle)
|
||||
handle.close()
|
||||
|
||||
print("Wrote output to pandadoc.hpp. You can now run:")
|
||||
print()
|
||||
print(" doxygen built/direct/directscripts/Doxyfile.python")
|
||||
|
|
|
|||
|
|
@ -891,7 +891,7 @@ describe_message(std::ostream &out, const string &prefix,
|
|||
const Datagram &dg) const {
|
||||
DCPacker packer;
|
||||
|
||||
packer.set_unpack_data(dg.get_message());
|
||||
packer.set_unpack_data((const char *)dg.get_data(), dg.get_length(), false);
|
||||
CHANNEL_TYPE do_id;
|
||||
int msg_type;
|
||||
bool is_update = false;
|
||||
|
|
|
|||
|
|
@ -277,13 +277,6 @@ class _local(object):
|
|||
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
|
||||
d[key] = value
|
||||
|
||||
## def __getattr__(self, key):
|
||||
## d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
|
||||
## try:
|
||||
## return d[key]
|
||||
## except KeyError:
|
||||
## raise AttributeError
|
||||
|
||||
def __getattribute__(self, key):
|
||||
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
|
||||
if key == '__dict__':
|
||||
|
|
@ -292,6 +285,3 @@ class _local(object):
|
|||
return d[key]
|
||||
except KeyError:
|
||||
return object.__getattribute__(self, key)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -25,6 +25,7 @@
|
|||
#include "cppFunctionGroup.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppClosureType.h"
|
||||
#include "cppReferenceType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppBison.h"
|
||||
#include "pdtoa.h"
|
||||
|
|
@ -260,12 +261,12 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
|
|||
_u._variable = inst;
|
||||
return;
|
||||
}
|
||||
CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
/*CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
if (fgroup != nullptr) {
|
||||
_type = T_function;
|
||||
_u._fgroup = fgroup;
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
_type = T_unknown_ident;
|
||||
|
|
@ -1232,6 +1233,61 @@ determine_type() const {
|
|||
return nullptr; // Compiler kludge; can't get here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an lvalue expression.
|
||||
*/
|
||||
bool CPPExpression::
|
||||
is_lvalue() const {
|
||||
switch (_type) {
|
||||
case T_variable:
|
||||
case T_function:
|
||||
case T_unknown_ident:
|
||||
return true;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
{
|
||||
CPPReferenceType *ref_type = _u._typecast._to->as_reference_type();
|
||||
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
|
||||
}
|
||||
|
||||
case T_unary_operation:
|
||||
if (_u._op._operator == 'f') {
|
||||
// A function returning an lvalue reference.
|
||||
CPPType *return_type = determine_type();
|
||||
if (return_type != nullptr) {
|
||||
CPPReferenceType *ref_type = return_type->as_reference_type();
|
||||
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
|
||||
}
|
||||
}
|
||||
return _u._op._operator == PLUSPLUS
|
||||
|| _u._op._operator == MINUSMINUS
|
||||
|| _u._op._operator == '*';
|
||||
|
||||
case T_binary_operation:
|
||||
if (_u._op._operator == ',') {
|
||||
CPPReferenceType *ref_type = _u._op._op2->as_reference_type();
|
||||
return ref_type != nullptr && ref_type->_value_category == CPPReferenceType::VC_lvalue;
|
||||
}
|
||||
return (_u._op._operator == POINTSAT || _u._op._operator == ',');
|
||||
|
||||
case T_trinary_operation:
|
||||
return _u._op._op2->is_lvalue() && _u._op._op3->is_lvalue();
|
||||
|
||||
case T_literal:
|
||||
case T_raw_literal:
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ public:
|
|||
|
||||
Result evaluate() const;
|
||||
CPPType *determine_type() const;
|
||||
bool is_lvalue() const;
|
||||
bool is_tbd() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
|
|
|||
|
|
@ -4078,13 +4078,9 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
|
||||
/**
|
||||
* Special case optimization: if the last map is a subset of the map before
|
||||
* it, and the last parameter is only a simple parameter type (that we have
|
||||
* special default argument handling for), we can merge the cases. When this
|
||||
* happens, we can make use of a special feature of PyArg_ParseTuple for
|
||||
* handling of these last few default arguments. This doesn't work well for
|
||||
* all types of default expressions, though, hence the need for this elaborate
|
||||
* checking mechanism down here, which goes in parallel with the actual
|
||||
* optional arg handling logic in write_function_instance.
|
||||
* it, we can merge the cases. When this happens, we can make use of a
|
||||
* special feature of PyArg_ParseTuple for handling of these last few default
|
||||
* arguments.
|
||||
*
|
||||
* This isn't just to help reduce the amount of generated code; it also
|
||||
* enables arbitrary selection of keyword arguments for many functions, ie.
|
||||
|
|
@ -4095,14 +4091,6 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
* Thanks to this mechanism, we can call it like so:
|
||||
*
|
||||
* func(c=True, d=".")
|
||||
*
|
||||
* The return value is the minimum of the number of maximum arguments.
|
||||
*
|
||||
* Sorry, let me try that again: it returns the largest number of arguments
|
||||
* for which the overloads will be separated out rather than handled via the
|
||||
* special default handling mechanism. Or something.
|
||||
*
|
||||
* Please don't hate me.
|
||||
*/
|
||||
int InterfaceMakerPythonNative::
|
||||
collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
|
||||
|
|
@ -4118,70 +4106,8 @@ collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
|
|||
if (std::includes(rmi_next->second.begin(), rmi_next->second.end(),
|
||||
rmi->second.begin(), rmi->second.end())) {
|
||||
|
||||
// Check if the nth argument is something we can easily create a default
|
||||
// for.
|
||||
std::set<FunctionRemap *>::iterator sii;
|
||||
for (sii = rmi->second.begin(); sii != rmi->second.end(); ++sii) {
|
||||
FunctionRemap *remap = (*sii);
|
||||
size_t pn = (size_t)rmi->first;
|
||||
if (!remap->_has_this || remap->_type == FunctionRemap::T_constructor) {
|
||||
--pn;
|
||||
}
|
||||
nassertd(pn < remap->_parameters.size()) goto abort_iteration;
|
||||
|
||||
ParameterRemap *param = remap->_parameters[pn]._remap;
|
||||
CPPType *type = param->get_new_type();
|
||||
|
||||
if (param->new_type_is_atomic_string()) {
|
||||
CPPType *orig_type = param->get_orig_type();
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
} else if (TypeManager::is_wchar_pointer(orig_type)) {
|
||||
goto abort_iteration;
|
||||
} else if (TypeManager::is_wstring(orig_type)) {
|
||||
goto abort_iteration;
|
||||
} else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
|
||||
goto abort_iteration;
|
||||
} else {
|
||||
// Regular strings are OK if the default argument is a string
|
||||
// literal or the default string constructor, since those are
|
||||
// trivial to handle. This actually covers almost all of the
|
||||
// cases of default string args.
|
||||
CPPExpression::Type expr_type = param->get_default_value()->_type;
|
||||
if (expr_type != CPPExpression::T_default_construct &&
|
||||
expr_type != CPPExpression::T_string) {
|
||||
goto abort_iteration;
|
||||
}
|
||||
}
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
} else if (TypeManager::is_const_char_pointer(type)) {
|
||||
} else if (TypeManager::is_pointer_to_PyTypeObject(type)) {
|
||||
} else if (TypeManager::is_pointer_to_PyStringObject(type)) {
|
||||
} else if (TypeManager::is_pointer_to_PyUnicodeObject(type)) {
|
||||
} else if (TypeManager::is_pointer_to_PyObject(type)) {
|
||||
} else if (TypeManager::is_pointer_to_Py_buffer(type)) {
|
||||
goto abort_iteration;
|
||||
} else if (TypeManager::is_pointer_to_simple(type)) {
|
||||
goto abort_iteration;
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
// I'm allowing other pointer types, but only if the expression
|
||||
// happens to evaluate to a numeric constant (which will likely only
|
||||
// be NULL). There are too many issues to resolve right now with
|
||||
// allowing more complex default expressions, including issues in
|
||||
// the C++ parser (but the reader is welcome to give it a try!)
|
||||
CPPExpression::Result res = param->get_default_value()->evaluate();
|
||||
if (res._type != CPPExpression::RT_integer &&
|
||||
res._type != CPPExpression::RT_pointer) {
|
||||
goto abort_iteration;
|
||||
}
|
||||
} else {
|
||||
goto abort_iteration;
|
||||
}
|
||||
}
|
||||
|
||||
// rmi_next has a superset of the remaps in rmi, and we are going to
|
||||
// erase rmi_next, so put all the remaps in rmi. rmi->second =
|
||||
// rmi_next->second;
|
||||
// erase rmi_next, so put all the remaps in rmi.
|
||||
|
||||
max_required_args = rmi_next->first;
|
||||
rmi = rmi_next;
|
||||
|
|
@ -4191,7 +4117,6 @@ collapse_default_remaps(std::map<int, std::set<FunctionRemap *> > &map_sets,
|
|||
}
|
||||
}
|
||||
|
||||
abort_iteration:
|
||||
// Now erase the other remap sets. Reverse iterators are weird, we first
|
||||
// need to get forward iterators and decrement them by one.
|
||||
std::map<int, std::set<FunctionRemap *> >::iterator erase_begin, erase_end;
|
||||
|
|
@ -4738,6 +4663,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
"(" + orig_type->get_local_name(&parser) + ")" + param_name;
|
||||
|
||||
string default_expr;
|
||||
const char *null_assign = "";
|
||||
|
||||
if (is_optional) {
|
||||
// If this is an optional argument, PyArg_ParseTuple will leave the
|
||||
|
|
@ -4747,6 +4673,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
default_expr_str << " = ";
|
||||
default_value->output(default_expr_str, 0, &parser, false);
|
||||
default_expr = default_expr_str.str();
|
||||
null_assign = " = nullptr";
|
||||
|
||||
// We should only ever have to consider optional arguments for functions
|
||||
// taking a variable number of arguments.
|
||||
|
|
@ -4776,23 +4703,40 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
expected_params += "str";
|
||||
|
||||
} else if (TypeManager::is_wchar_pointer(orig_type)) {
|
||||
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#endif\n";
|
||||
out << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
|
||||
out << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << null_assign << ";\n";
|
||||
out << "#endif\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
|
||||
extra_convert
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
|
||||
<< "#else"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< param_name << "_str[" << param_name << "_len] = 0;\n"
|
||||
<< "#endif\n";
|
||||
if (is_optional) {
|
||||
extra_convert
|
||||
<< "wchar_t *" << param_name << "_str;\n"
|
||||
<< "if (" << param_name << " != nullptr) {\n"
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< " " << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
|
||||
<< "#else"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< " " << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< param_name << "_str[" << param_name << "_len] = 0;\n"
|
||||
<< "#endif\n"
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_str" << default_expr << ";\n"
|
||||
<< "}\n";
|
||||
} else {
|
||||
extra_convert
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString(" << param_name << ", nullptr);\n"
|
||||
<< "#else"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< param_name << "_str[" << param_name << "_len] = 0;\n"
|
||||
<< "#endif\n";
|
||||
}
|
||||
|
||||
pexpr_string = param_name + "_str";
|
||||
|
||||
|
|
@ -4803,56 +4747,48 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
|
||||
expected_params += "unicode";
|
||||
|
||||
} else if (TypeManager::is_wstring(orig_type)) {
|
||||
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#endif\n";
|
||||
} else if (TypeManager::is_wstring(orig_type) ||
|
||||
TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
|
||||
out << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
|
||||
out << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << null_assign << ";\n";
|
||||
out << "#endif\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
|
||||
extra_convert
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "Py_ssize_t " << param_name << "_len;\n"
|
||||
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
|
||||
<< param_name << ", &" << param_name << "_len);\n"
|
||||
<< "#else\n"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< "#endif\n";
|
||||
|
||||
pexpr_string = param_name + "_str, " + param_name + "_len";
|
||||
|
||||
extra_cleanup
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "PyMem_Free(" << param_name << "_str);\n"
|
||||
<< "#endif\n";
|
||||
|
||||
expected_params += "unicode";
|
||||
|
||||
} else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
|
||||
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#endif\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
|
||||
extra_convert
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "Py_ssize_t " << param_name << "_len;\n"
|
||||
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
|
||||
<< param_name << ", &" << param_name << "_len);\n"
|
||||
<< "#else\n"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< "#endif\n";
|
||||
|
||||
pexpr_string = param_name + "_str, " + param_name + "_len";
|
||||
if (is_optional) {
|
||||
extra_convert
|
||||
<< "Py_ssize_t " << param_name << "_len;\n"
|
||||
<< "wchar_t *" << param_name << "_str;\n"
|
||||
<< "std::wstring " << param_name << "_wstr;\n"
|
||||
<< "if (" << param_name << " != nullptr) {\n"
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< " " << param_name << "_str = PyUnicode_AsWideCharString("
|
||||
<< param_name << ", &" << param_name << "_len);\n"
|
||||
<< "#else\n"
|
||||
<< " " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< " " << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< "#endif\n"
|
||||
<< " " << param_name << "_wstr.assign(" << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_wstr" << default_expr << ";\n"
|
||||
<< "}\n";
|
||||
pexpr_string = "std::move(" + param_name + "_wstr)";
|
||||
} else {
|
||||
extra_convert
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
<< "Py_ssize_t " << param_name << "_len;\n"
|
||||
<< "wchar_t *" << param_name << "_str = PyUnicode_AsWideCharString("
|
||||
<< param_name << ", &" << param_name << "_len);\n"
|
||||
<< "#else\n"
|
||||
<< "Py_ssize_t " << param_name << "_len = PyUnicode_GET_SIZE(" << param_name << ");\n"
|
||||
<< "wchar_t *" << param_name << "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));\n"
|
||||
<< "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
|
||||
<< "#endif\n";
|
||||
pexpr_string = param_name + "_str, " + param_name + "_len";
|
||||
}
|
||||
|
||||
extra_cleanup
|
||||
<< "#if PY_VERSION_HEX >= 0x03030000\n"
|
||||
|
|
@ -5019,11 +4955,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
only_pyobjects = false;
|
||||
|
||||
} else if (TypeManager::is_wchar(type)) {
|
||||
indent(out, indent_level) << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
out << "#if PY_VERSION_HEX >= 0x03020000\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#else\n";
|
||||
out << "#else\n";
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "#endif\n";
|
||||
out << "#endif\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
|
||||
|
|
@ -5348,17 +5284,36 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
if (args_type == AT_single_arg) {
|
||||
param_name = "arg";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
indent(out, indent_level) << "Py_buffer " << param_name << "_view;\n";
|
||||
|
||||
extra_param_check << " && PyObject_GetBuffer("
|
||||
<< param_name << ", &"
|
||||
<< param_name << "_view, PyBUF_FULL) == 0";
|
||||
pexpr_string = "&" + param_name + "_view";
|
||||
extra_cleanup << "PyBuffer_Release(&" << param_name << "_view);\n";
|
||||
if (is_optional) {
|
||||
indent(out, indent_level) << "Py_buffer *" << param_name << "_viewp;\n";
|
||||
|
||||
extra_convert
|
||||
<< "bool " << param_name << "_success;\n"
|
||||
<< "if (" << param_name << " != nullptr) {\n"
|
||||
<< " " << param_name << "_success = (PyObject_GetBuffer("
|
||||
<< param_name << ", &" << param_name << "_view, PyBUF_FULL) == 0);\n"
|
||||
<< " " << param_name << "_viewp = &" << param_name << "_view;\n"
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_viewp" << default_expr << ";\n"
|
||||
<< " " << param_name << "_success = true;\n"
|
||||
<< "}\n";
|
||||
|
||||
extra_param_check << " && " << param_name << "_success";
|
||||
pexpr_string = param_name + "_viewp";
|
||||
extra_cleanup << "if (" << param_name << " != nullptr) PyBuffer_Release(&" << param_name << "_view);\n";
|
||||
} else {
|
||||
extra_param_check << " && PyObject_GetBuffer("
|
||||
<< param_name << ", &"
|
||||
<< param_name << "_view, PyBUF_FULL) == 0";
|
||||
pexpr_string = "&" + param_name + "_view";
|
||||
extra_cleanup << "PyBuffer_Release(&" << param_name << "_view);\n";
|
||||
}
|
||||
expected_params += "buffer";
|
||||
may_raise_typeerror = true;
|
||||
clear_error = true;
|
||||
|
|
@ -5367,7 +5322,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
if (args_type == AT_single_arg) {
|
||||
param_name = "arg";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyObject *" << param_name << ";\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
|
|
@ -5496,18 +5451,15 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
if (args_type == AT_single_arg) {
|
||||
param_name = "arg";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyObject *" << param_name;
|
||||
if (is_optional) {
|
||||
out << " = nullptr";
|
||||
}
|
||||
out << ";\n";
|
||||
indent(out, indent_level) << "PyObject *" << param_name << null_assign << ";\n";
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
|
||||
// If the default value is NULL, we also accept a None value.
|
||||
bool maybe_none = false;
|
||||
if (default_value != nullptr && (return_flags & RF_coerced) == 0) {
|
||||
if (default_value != nullptr && (return_flags & RF_coerced) == 0 &&
|
||||
TypeManager::is_pointer(orig_type)) {
|
||||
CPPExpression::Result res = param->get_default_value()->evaluate();
|
||||
if (res._type == CPPExpression::RT_integer ||
|
||||
res._type == CPPExpression::RT_pointer) {
|
||||
|
|
@ -5576,8 +5528,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
<< "if (" << param_name << " != nullptr && " << param_name << " != Py_None) {\n"
|
||||
<< " " << param_name << "_this";
|
||||
} else if (is_optional) {
|
||||
if (TypeManager::is_pointer(orig_type)) {
|
||||
extra_convert << default_expr;
|
||||
}
|
||||
extra_convert
|
||||
<< default_expr << ";\n"
|
||||
<< ";\n"
|
||||
<< "if (" << param_name << " != nullptr) {\n"
|
||||
<< " " << param_name << "_this";
|
||||
} else if (maybe_none) {
|
||||
|
|
@ -5590,7 +5545,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
extra_convert << " = Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_local);\n";
|
||||
|
||||
if (is_optional || maybe_none) {
|
||||
if (is_optional && !TypeManager::is_pointer(orig_type)) {
|
||||
extra_convert
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_local" << default_expr << ";\n"
|
||||
<< " " << param_name << "_this = &" << param_name << "_local;\n"
|
||||
<< "}\n";
|
||||
} else if (is_optional || maybe_none) {
|
||||
extra_convert << "}\n";
|
||||
}
|
||||
|
||||
|
|
@ -5645,21 +5606,60 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
} else { // The regular, non-coercion case.
|
||||
type->output_instance(extra_convert, param_name + "_this", &parser);
|
||||
if (is_optional && maybe_none) {
|
||||
// This parameter has a default value of nullptr, so we need to also
|
||||
// allow passing in None.
|
||||
extra_convert
|
||||
<< default_expr << ";\n"
|
||||
<< "if (" << param_name << " != nullptr && " << param_name << " != Py_None) {\n"
|
||||
<< " " << param_name << "_this";
|
||||
} else if (is_optional) {
|
||||
}
|
||||
else if (is_optional && !TypeManager::is_pointer(orig_type) && !default_value->is_lvalue()) {
|
||||
// Most annoying case, where we have to use an rvalue reference to
|
||||
// extend the lifetime of the default argument. In this case, the
|
||||
// default expression is invoked even if not used.
|
||||
extra_convert << ";\n";
|
||||
if (TypeManager::is_const_pointer_to_anything(type)) {
|
||||
extra_convert << "const ";
|
||||
obj_type->output_instance(extra_convert, "&" + param_name + "_ref", &parser);
|
||||
} else {
|
||||
obj_type->output_instance(extra_convert, "&&" + param_name + "_ref", &parser);
|
||||
}
|
||||
extra_convert
|
||||
<< default_expr << ";\n"
|
||||
<< "if (" << param_name << " != nullptr) {\n"
|
||||
<< "if (" << param_name << " == nullptr) {\n"
|
||||
<< " " << param_name << "_this = &" << param_name << "_ref;\n"
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_this";
|
||||
} else if (maybe_none) {
|
||||
}
|
||||
else if (is_optional) {
|
||||
// General case where the default argument is either an lvalue or a
|
||||
// pointer.
|
||||
extra_convert
|
||||
<< ";\n"
|
||||
<< "if (" << param_name << " == nullptr) {\n"
|
||||
<< " " << param_name << "_this = ";
|
||||
if (TypeManager::is_pointer(orig_type)) {
|
||||
default_value->output(extra_convert, 0, &parser, false);
|
||||
extra_convert << ";\n";
|
||||
} else {
|
||||
// The rvalue case was handled above, so this is an lvalue, which
|
||||
// means we can safely take a reference to it.
|
||||
extra_convert << "&(";
|
||||
default_value->output(extra_convert, 0, &parser, false);
|
||||
extra_convert << ");\n";
|
||||
}
|
||||
extra_convert
|
||||
<< "} else {\n"
|
||||
<< " " << param_name << "_this";
|
||||
}
|
||||
else if (maybe_none) {
|
||||
// No default argument, but we still need to check for None.
|
||||
extra_convert
|
||||
<< " = nullptr;\n"
|
||||
<< "if (" << param_name << " != Py_None) {\n"
|
||||
<< " " << param_name << "_this";
|
||||
}
|
||||
|
||||
if (const_ok && !report_errors) {
|
||||
// This function does the same thing in this case and is slightly
|
||||
// simpler. But maybe we should just reorganize these functions
|
||||
|
|
|
|||
|
|
@ -312,7 +312,10 @@ main(int argc, char **argv) {
|
|||
string command_line;
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
command_line += string(argv[i]) + " ";
|
||||
if (i > 0) {
|
||||
command_line += ' ';
|
||||
}
|
||||
command_line += string(argv[i]);
|
||||
}
|
||||
|
||||
Filename fn;
|
||||
|
|
|
|||
|
|
@ -2024,6 +2024,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
|
|||
if (iproperty._type != 0 && iproperty._type != return_index) {
|
||||
cerr << "Property " << property_name << " has inconsistent element type!\n";
|
||||
}
|
||||
iproperty._type = return_index;
|
||||
} else {
|
||||
iproperty._type = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,18 @@ interrogate_element_setter(ElementIndex element) {
|
|||
return InterrogateDatabase::get_ptr()->get_element(element).get_setter();
|
||||
}
|
||||
|
||||
bool
|
||||
interrogate_element_is_sequence(ElementIndex element) {
|
||||
// cerr << "interrogate_element_is_sequence(" << element << ")\n";
|
||||
return InterrogateDatabase::get_ptr()->get_element(element).is_sequence();
|
||||
}
|
||||
|
||||
bool
|
||||
interrogate_element_is_mapping(ElementIndex element) {
|
||||
// cerr << "interrogate_element_is_mapping(" << element << ")\n";
|
||||
return InterrogateDatabase::get_ptr()->get_element(element).is_mapping();
|
||||
}
|
||||
|
||||
int
|
||||
interrogate_number_of_globals() {
|
||||
// cerr << "interrogate_number_of_globals()\n";
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getter(ElementIndex elemen
|
|||
EXPCL_INTERROGATEDB bool interrogate_element_has_setter(ElementIndex element);
|
||||
EXPCL_INTERROGATEDB FunctionIndex interrogate_element_setter(ElementIndex element);
|
||||
|
||||
EXPCL_INTERROGATEDB bool interrogate_element_is_sequence(ElementIndex element);
|
||||
EXPCL_INTERROGATEDB bool interrogate_element_is_mapping(ElementIndex element);
|
||||
|
||||
// Global Data
|
||||
|
||||
// This is the list of global data elements.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
;
|
||||
; BUILT - location of panda install tree.
|
||||
; SOURCE - location of the panda source-tree if available, OR location of panda install tree.
|
||||
; PYVER - version of Python that Panda was built with (ie, "2.7")
|
||||
; INCLUDE_PYVER - version of Python that Panda was built with (eg. "2.7", "3.5-32")
|
||||
; REGVIEW - either 32 or 64, depending on the build architecture.
|
||||
;
|
||||
|
||||
|
|
@ -46,7 +46,9 @@ SetCompressor ${COMPRESSOR}
|
|||
!insertmacro MUI_PAGE_LICENSE "${SOURCE}/doc/LICENSE"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
|
||||
!ifdef INCLUDE_PYVER
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ConfirmPythonSelection
|
||||
!endif
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
|
@ -64,8 +66,9 @@ ShowUninstDetails hide
|
|||
|
||||
LicenseData "${SOURCE}/doc/LICENSE"
|
||||
|
||||
InstType "Full (Recommended)"
|
||||
InstType "Minimal"
|
||||
InstType "Auto (Recommended)"
|
||||
InstType "Full"
|
||||
InstType "Light"
|
||||
|
||||
LangString DESC_SecCore ${LANG_ENGLISH} "The Panda3D core libraries, configuration files and models/textures that are needed to use Panda3D."
|
||||
LangString DESC_SecOpenGL ${LANG_ENGLISH} "The OpenGL graphics back-end is the most well-supported renderer."
|
||||
|
|
@ -78,8 +81,9 @@ LangString DESC_SecODE ${LANG_ENGLISH} "Support for the Open Dynamics Engine to
|
|||
LangString DESC_SecPhysX ${LANG_ENGLISH} "Support for NVIDIA PhysX to implement physics."
|
||||
LangString DESC_SecRocket ${LANG_ENGLISH} "Support for the libRocket GUI library. This is an optional library that offers an HTML/CSS-like approach to creating user interfaces."
|
||||
LangString DESC_SecTools ${LANG_ENGLISH} "Useful tools and model converters to help with Panda3D development. Recommended."
|
||||
LangString DESC_SecPyBindings ${LANG_ENGLISH} "Contains the Python modules that allow use of Panda3D using Python. These will only work with a ${REGVIEW}-bit version of Python ${PYVER}."
|
||||
LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Python ${PYVER} preconfigured to make use of Panda3D."
|
||||
LangString DESC_SecGroupPython ${LANG_ENGLISH} "Contains modules that provide Python support for Panda3D."
|
||||
LangString DESC_SecPyShared ${LANG_ENGLISH} "Contains the common Python code used by the Panda3D Python bindings."
|
||||
LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Python ${INCLUDE_PYVER} preconfigured to make use of Panda3D."
|
||||
LangString DESC_SecHeadersLibs ${LANG_ENGLISH} "Headers and libraries needed for C++ development with Panda3D."
|
||||
LangString DESC_SecSamples ${LANG_ENGLISH} "The sample programs demonstrate how to make Python applications with Panda3D."
|
||||
LangString DESC_SecMaxPlugins ${LANG_ENGLISH} "Plug-ins for Autodesk 3ds Max (${REGVIEW}-bit) that can be used to export models to Panda3D."
|
||||
|
|
@ -112,222 +116,38 @@ var MANPAGE
|
|||
!insertmacro !defineifexist HAVE_ODE "${BUILT}\bin\libpandaode.dll"
|
||||
!insertmacro !defineifexist HAVE_PHYSX "${BUILT}\bin\libpandaphysx.dll"
|
||||
!insertmacro !defineifexist HAVE_ROCKET "${BUILT}\bin\libp3rocket.dll"
|
||||
!insertmacro !defineifexist HAVE_PYTHON "${BUILT}\python"
|
||||
!insertmacro !defineifexist HAVE_SAMPLES "${SOURCE}\samples"
|
||||
!insertmacro !defineifexist HAVE_MAX_PLUGINS "${BUILT}\plugins\*.dlo"
|
||||
!insertmacro !defineifexist HAVE_MAYA_PLUGINS "${BUILT}\plugins\*.mll"
|
||||
|
||||
Function runFunction
|
||||
ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
|
||||
FunctionEnd
|
||||
!macro RemovePythonPath PYVER
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" ""
|
||||
StrCmp $0 "$INSTDIR" 0 +2
|
||||
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D"
|
||||
!macroend
|
||||
|
||||
Function .onInit
|
||||
${If} ${REGVIEW} = 64
|
||||
${AndIfNot} ${RunningX64}
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows. Please download and install the 32-bit version of Panda3D instead."
|
||||
Abort
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
!macro PyBindingSection PYVER EXT_SUFFIX
|
||||
LangString DESC_SecPyBindings${PYVER} ${LANG_ENGLISH} "Contains the Python modules that allow use of Panda3D using a ${REGVIEW}-bit version of Python ${PYVER}."
|
||||
|
||||
SectionGroup "Panda3D Libraries"
|
||||
Section "Core Libraries" SecCore
|
||||
SectionIn 1 2 RO
|
||||
|
||||
SetShellVarContext current
|
||||
SetOverwrite try
|
||||
!insertmacro !defineifexist _present "${BUILT}\panda3d\core${EXT_SUFFIX}"
|
||||
!ifdef _present
|
||||
Section "${PYVER} bindings" SecPyBindings${PYVER}
|
||||
!if "${PYVER}" == "${INCLUDE_PYVER}"
|
||||
SectionIn 1 2 3
|
||||
!else
|
||||
!if "${PYVER}" == "2.7"
|
||||
SectionIn 1 2
|
||||
!else
|
||||
; See .onInit function where this is dynamically enabled.
|
||||
SectionIn 2
|
||||
!endif
|
||||
!endif
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Panda3D libraries..."
|
||||
DetailPrint "Installing Panda3D bindings for Python ${PYVER}..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File /nonfatal "${BUILT}\LICENSE"
|
||||
File /nonfatal "${BUILT}\ReleaseNotes"
|
||||
File /nonfatal "${BUILT}\pandaIcon.ico"
|
||||
|
||||
SetOutPath $INSTDIR\etc
|
||||
File /r "${BUILT}\etc\*"
|
||||
|
||||
SetOutPath $INSTDIR\bin
|
||||
File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
|
||||
|
||||
; Before Windows 10, we need these stubs for the UCRT as well.
|
||||
ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
|
||||
${If} $0 < 10
|
||||
ClearErrors
|
||||
File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
|
||||
File /nonfatal "${BUILT}\bin\ucrtbase.dll"
|
||||
${Endif}
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing models..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath $INSTDIR\models
|
||||
File /r /x CVS "${BUILT}\models\*"
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing optional components..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
RMDir /r "$SMPROGRAMS\${TITLE}"
|
||||
CreateDirectory "$SMPROGRAMS\${TITLE}"
|
||||
SectionEnd
|
||||
|
||||
!ifdef HAVE_GL
|
||||
Section "OpenGL" SecOpenGL
|
||||
SectionIn 1 2 RO
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandagl.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_DX9
|
||||
Section "Direct3D 9" SecDirect3D9
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandadx9.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\cgD3D9.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_OPENAL
|
||||
Section "OpenAL Audio" SecOpenAL
|
||||
SectionIn 1 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3openal_audio.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\OpenAL32.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\*_oal.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_FMOD
|
||||
Section "FMOD Audio" SecFMOD
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3fmod_audio.dll"
|
||||
File /r "${BUILT}\bin\fmodex*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_FFMPEG
|
||||
Section "FFMpeg" SecFFMpeg
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3ffmpeg.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\av*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\swscale*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\swresample*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\postproc*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_BULLET
|
||||
Section "Bullet Physics" SecBullet
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandabullet.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_ODE
|
||||
Section "ODE Physics" SecODE
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandaode.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_PHYSX
|
||||
Section "NVIDIA PhysX" SecPhysX
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandaphysx.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\PhysX*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\NxCharacter*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\cudart*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_ROCKET
|
||||
Section "libRocket GUI" SecRocket
|
||||
SectionIn 1
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3rocket.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
|
||||
File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
SectionGroupEnd
|
||||
|
||||
Section "Tools and utilities" SecTools
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing utilities..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File /r "${BUILT}\bin\*.exe"
|
||||
File /nonfatal /r "${BUILT}\bin\*.p3d"
|
||||
SetOutPath "$INSTDIR\NSIS"
|
||||
File /r /x CVS "${NSISDIR}\*"
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model" "" "Panda3D model/animation"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\DefaultIcon" "" "$INSTDIR\bin\pview.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress" "" "Compress to .pz"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress\command" "" '"$INSTDIR\bin\pzip.exe" "%1"'
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed" "" "Compressed file"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\DefaultIcon" "" "$INSTDIR\bin\pzip.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress" "" "Decompress"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress\command" "" '"$INSTDIR\bin\punzip.exe" "%1"'
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile" "" "Panda3D Multifile"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon" "" "$INSTDIR\bin\multify.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract" "" "Extract here"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract\command" "" '"$INSTDIR\bin\multify.exe" -xf "%1"'
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Python support"
|
||||
Section "Python bindings" SecPyBindings
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Panda3D Python modules..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File /nonfatal /r "${BUILT}\bin\*.pyd"
|
||||
|
||||
SetOutPath $INSTDIR\direct\directscripts
|
||||
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\directscripts\*"
|
||||
SetOutPath $INSTDIR\direct
|
||||
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\*.py"
|
||||
|
||||
Delete "$INSTDIR\panda3d.py"
|
||||
Delete "$INSTDIR\panda3d.pyc"
|
||||
Delete "$INSTDIR\panda3d.pyo"
|
||||
SetOutPath $INSTDIR\pandac
|
||||
File /r "${BUILT}\pandac\*.py"
|
||||
SetOutPath $INSTDIR\panda3d
|
||||
File /r "${BUILT}\panda3d\*.py"
|
||||
|
||||
File /nonfatal /r "${BUILT}\panda3d\core${EXT_SUFFIX}"
|
||||
File /nonfatal /r "${BUILT}\panda3d\ai${EXT_SUFFIX}"
|
||||
|
|
@ -384,87 +204,342 @@ SectionGroup "Python support"
|
|||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
; Check for a non-Panda3D system-wide Python installation.
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" UserExternalPthCheck 0
|
||||
StrCmp $0 "" UserExternalPthCheck 0
|
||||
IfFileExists "$0\ppython.exe" UserExternalPthCheck 0
|
||||
IfFileExists "$0\python.exe" AskExternalPth UserExternalPthCheck
|
||||
|
||||
; Check for a non-Panda3D user installation of Python.
|
||||
UserExternalPthCheck:
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" SkipExternalPth 0
|
||||
StrCmp $0 "" SkipExternalPth 0
|
||||
IfFileExists "$0\ppython.exe" SkipExternalPth 0
|
||||
IfFileExists "$0\python.exe" AskExternalPth SkipExternalPth
|
||||
|
||||
; We're pretty sure this Python build is of the right architecture.
|
||||
AskExternalPth:
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
"Your system already has a copy of Python ${PYVER} installed in:$\r$\n$0$\r$\nWould you like to configure it to be able to use the Panda3D libraries?$\r$\nIf you choose no, you will only be able to use Panda3D's own copy of Python." \
|
||||
IDYES WriteExternalPth IDNO SkipExternalPth
|
||||
|
||||
WriteExternalPth:
|
||||
;FileOpen $1 "$0\Lib\site-packages\panda.pth" w
|
||||
;FileWrite $1 "$INSTDIR$\r$\n"
|
||||
;FileWrite $1 "$INSTDIR\bin$\r$\n"
|
||||
;FileClose $1
|
||||
|
||||
; Actually, it looks like we can just do this instead:
|
||||
; Install a Panda3D path into the global PythonPath for this version
|
||||
; of Python.
|
||||
WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" "" "$INSTDIR"
|
||||
SectionEnd
|
||||
!undef _present
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
SkipExternalPth:
|
||||
Function runFunction
|
||||
ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
|
||||
FunctionEnd
|
||||
|
||||
SectionGroup "Panda3D Libraries"
|
||||
Section "Core Libraries" SecCore
|
||||
SectionIn 1 2 3 RO
|
||||
|
||||
SetShellVarContext current
|
||||
SetOverwrite try
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Panda3D libraries..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File /nonfatal "${BUILT}\LICENSE"
|
||||
File /nonfatal "${BUILT}\ReleaseNotes"
|
||||
File /nonfatal "${BUILT}\pandaIcon.ico"
|
||||
|
||||
SetOutPath $INSTDIR\etc
|
||||
File /r "${BUILT}\etc\*"
|
||||
|
||||
SetOutPath $INSTDIR\bin
|
||||
File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
|
||||
|
||||
; Before Windows 10, we need these stubs for the UCRT as well.
|
||||
ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
|
||||
${If} $0 < 10
|
||||
ClearErrors
|
||||
File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
|
||||
File /nonfatal "${BUILT}\bin\ucrtbase.dll"
|
||||
${Endif}
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing models..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath $INSTDIR\models
|
||||
File /r /x CVS "${BUILT}\models\*"
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing optional components..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
RMDir /r "$SMPROGRAMS\${TITLE}"
|
||||
CreateDirectory "$SMPROGRAMS\${TITLE}"
|
||||
SectionEnd
|
||||
|
||||
!ifdef HAVE_PYTHON
|
||||
Section "Python ${PYVER}" SecPython
|
||||
SectionIn 1 2
|
||||
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Python ${PYVER} (${REGVIEW}-bit)..."
|
||||
SetDetailsPrint listonly
|
||||
!ifdef HAVE_GL
|
||||
Section "OpenGL" SecOpenGL
|
||||
SectionIn 1 2 3 RO
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File /nonfatal "${BUILT}\bin\python*.dll"
|
||||
File "${BUILT}\bin\libpandagl.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
SetOutPath "$INSTDIR\python"
|
||||
File /r /x *.pdb "${BUILT}\python\*"
|
||||
!ifdef HAVE_DX9
|
||||
Section "Direct3D 9" SecDirect3D9
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Adding registry keys for Python..."
|
||||
SetDetailsPrint listonly
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandadx9.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\cgD3D9.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
; Check if a copy of Python is installed for this user.
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "$INSTDIR\python" RegPath 0
|
||||
StrCmp "$0" "" SkipFileCheck 0
|
||||
IfFileExists "$0\python.exe" AskRegPath 0
|
||||
SkipFileCheck:
|
||||
!ifdef HAVE_OPENAL
|
||||
Section "OpenAL Audio" SecOpenAL
|
||||
SectionIn 1 2 3
|
||||
|
||||
; Check if a system-wide copy of Python is installed.
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "$INSTDIR\python" RegPath 0
|
||||
StrCmp "$0" "" RegPath 0
|
||||
IfFileExists "$0\python.exe" AskRegPath RegPath
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3openal_audio.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\OpenAL32.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\*_oal.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
AskRegPath:
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
"You already have a copy of Python ${PYVER} installed in:$\r$\n$0$\r$\n$\r$\nPanda3D installs its own copy of Python ${PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python for your user account?" \
|
||||
IDNO SkipRegPath
|
||||
!ifdef HAVE_FMOD
|
||||
Section "FMOD Audio" SecFMOD
|
||||
SectionIn 1 2
|
||||
|
||||
RegPath:
|
||||
WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" "" "$INSTDIR\python"
|
||||
SkipRegPath:
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3fmod_audio.dll"
|
||||
File /r "${BUILT}\bin\fmodex*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_FFMPEG
|
||||
Section "FFMpeg" SecFFMpeg
|
||||
SectionIn 1 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3ffmpeg.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\av*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\swscale*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\swresample*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\postproc*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_BULLET
|
||||
Section "Bullet Physics" SecBullet
|
||||
SectionIn 1 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandabullet.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_ODE
|
||||
Section "ODE Physics" SecODE
|
||||
SectionIn 1 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandaode.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_PHYSX
|
||||
Section "NVIDIA PhysX" SecPhysX
|
||||
; Only enable in "Full"
|
||||
SectionIn 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libpandaphysx.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\PhysX*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\NxCharacter*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\cudart*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!ifdef HAVE_ROCKET
|
||||
Section "libRocket GUI" SecRocket
|
||||
SectionIn 1 2
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File "${BUILT}\bin\libp3rocket.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
|
||||
File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
|
||||
SectionEnd
|
||||
!endif
|
||||
SectionGroupEnd
|
||||
|
||||
Section "Tools and utilities" SecTools
|
||||
SectionIn 1 2 3
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing utilities..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File /r "${BUILT}\bin\*.exe"
|
||||
File /nonfatal /r "${BUILT}\bin\*.p3d"
|
||||
SetOutPath "$INSTDIR\NSIS"
|
||||
File /r /x CVS "${NSISDIR}\*"
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model" "" "Panda3D model/animation"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\DefaultIcon" "" "$INSTDIR\bin\pview.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress" "" "Compress to .pz"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Model\shell\compress\command" "" '"$INSTDIR\bin\pzip.exe" "%1"'
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed" "" "Compressed file"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\DefaultIcon" "" "$INSTDIR\bin\pzip.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\open\command" "" '"$INSTDIR\bin\pview.exe" -l "%1"'
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress" "" "Decompress"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Compressed\shell\decompress\command" "" '"$INSTDIR\bin\punzip.exe" "%1"'
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile" "" "Panda3D Multifile"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon" "" "$INSTDIR\bin\multify.exe"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract" "" "Extract here"
|
||||
WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract\command" "" '"$INSTDIR\bin\multify.exe" -xf "%1"'
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Python modules" SecGroupPython
|
||||
Section "Shared code" SecPyShared
|
||||
SectionIn 1 2 3
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Panda3D shared Python modules..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath $INSTDIR\direct\directscripts
|
||||
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\directscripts\*"
|
||||
SetOutPath $INSTDIR\direct
|
||||
File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\*.py"
|
||||
|
||||
Delete "$INSTDIR\panda3d.py"
|
||||
Delete "$INSTDIR\panda3d.pyc"
|
||||
Delete "$INSTDIR\panda3d.pyo"
|
||||
SetOutPath $INSTDIR\pandac
|
||||
File /r "${BUILT}\pandac\*.py"
|
||||
SetOutPath $INSTDIR\panda3d
|
||||
File /r "${BUILT}\panda3d\*.py"
|
||||
SectionEnd
|
||||
|
||||
!insertmacro PyBindingSection 2.7 .pyd
|
||||
!if "${REGVIEW}" == "32"
|
||||
!insertmacro PyBindingSection 3.5-32 .cp35-win32.pyd
|
||||
!insertmacro PyBindingSection 3.6-32 .cp36-win32.pyd
|
||||
!insertmacro PyBindingSection 3.7-32 .cp37-win32.pyd
|
||||
!insertmacro PyBindingSection 3.8-32 .cp38-win32.pyd
|
||||
!insertmacro PyBindingSection 3.9-32 .cp39-win32.pyd
|
||||
!else
|
||||
!insertmacro PyBindingSection 3.5 .cp35-win_amd64.pyd
|
||||
!insertmacro PyBindingSection 3.6 .cp36-win_amd64.pyd
|
||||
!insertmacro PyBindingSection 3.7 .cp37-win_amd64.pyd
|
||||
!insertmacro PyBindingSection 3.8 .cp38-win_amd64.pyd
|
||||
!insertmacro PyBindingSection 3.9 .cp39-win_amd64.pyd
|
||||
!endif
|
||||
SectionGroupEnd
|
||||
|
||||
!ifdef INCLUDE_PYVER
|
||||
Section "Python ${INCLUDE_PYVER}" SecPython
|
||||
SectionIn 1 2 3
|
||||
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Python ${INCLUDE_PYVER} interpreter (${REGVIEW}-bit)..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
File /nonfatal "${BUILT}\bin\python*.dll"
|
||||
|
||||
SetOutPath "$INSTDIR\python"
|
||||
File /r /x *.pdb "${BUILT}\python\*"
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Adding registry keys for Python..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
; Check if a copy of Python is installed for this user.
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "$INSTDIR\python" RegPath 0
|
||||
StrCmp "$0" "" SkipFileCheck 0
|
||||
IfFileExists "$0\python.exe" AskRegPath 0
|
||||
SkipFileCheck:
|
||||
|
||||
; Check if a system-wide copy of Python is installed.
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "$INSTDIR\python" RegPath 0
|
||||
StrCmp "$0" "" RegPath 0
|
||||
IfFileExists "$0\python.exe" AskRegPath RegPath
|
||||
|
||||
AskRegPath:
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
"You already have a copy of Python ${INCLUDE_PYVER} installed in:$\r$\n$0$\r$\n$\r$\nPanda3D installs its own copy of Python ${INCLUDE_PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python for your user account?" \
|
||||
IDNO SkipRegPath
|
||||
|
||||
RegPath:
|
||||
WriteRegStr HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" "" "$INSTDIR\python"
|
||||
WriteRegStr HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" "ExecutablePath" "$INSTDIR\python\python.exe"
|
||||
SkipRegPath:
|
||||
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
!macro MaybeEnablePyBindingSection PYVER
|
||||
!if "${INCLUDE_PYVER}" != "${PYVER}"
|
||||
!ifdef SecPyBindings${PYVER}
|
||||
; Check if a copy of Python is installed for this user.
|
||||
Push $0
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "" +2 0
|
||||
IfFileExists "$0\python.exe" Py${PYVER}Exists 0
|
||||
|
||||
; Check if a system-wide copy of Python is installed.
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp "$0" "" Py${PYVER}ExistsNot 0
|
||||
IfFileExists "$0\python.exe" Py${PYVER}Exists Py${PYVER}ExistsNot
|
||||
|
||||
Py${PYVER}Exists:
|
||||
SectionSetFlags ${SecPyBindings${PYVER}} ${SF_SELECTED}
|
||||
SectionSetInstTypes ${SecPyBindings${PYVER}} 3
|
||||
|
||||
Py${PYVER}ExistsNot:
|
||||
Pop $0
|
||||
!endif
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
Function .onInit
|
||||
${If} ${REGVIEW} = 64
|
||||
${AndIfNot} ${RunningX64}
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows. Please download and install the 32-bit version of Panda3D instead."
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
; We never check for 2.7; it is always enabled in Auto mode
|
||||
!if "${REGVIEW}" == "32"
|
||||
!insertmacro MaybeEnablePyBindingSection 3.5-32
|
||||
!insertmacro MaybeEnablePyBindingSection 3.6-32
|
||||
!insertmacro MaybeEnablePyBindingSection 3.7-32
|
||||
!insertmacro MaybeEnablePyBindingSection 3.8-32
|
||||
!insertmacro MaybeEnablePyBindingSection 3.9-32
|
||||
!else
|
||||
!insertmacro MaybeEnablePyBindingSection 3.5
|
||||
!insertmacro MaybeEnablePyBindingSection 3.6
|
||||
!insertmacro MaybeEnablePyBindingSection 3.7
|
||||
!insertmacro MaybeEnablePyBindingSection 3.8
|
||||
!insertmacro MaybeEnablePyBindingSection 3.9
|
||||
!endif
|
||||
FunctionEnd
|
||||
|
||||
Function .onSelChange
|
||||
; If someone selects any Python version, the "shared modules" must be on.
|
||||
${If} ${SectionIsPartiallySelected} ${SecGroupPython}
|
||||
SectionGetFlags ${SecPyShared} $R0
|
||||
IntOp $R0 $R0 | ${SF_SELECTED}
|
||||
SectionSetFlags ${SecPyShared} $R0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
!ifdef INCLUDE_PYVER
|
||||
Function ConfirmPythonSelection
|
||||
; Check the current state of the "Python" section selection.
|
||||
SectionGetFlags ${SecPython} $R0
|
||||
|
|
@ -474,16 +549,14 @@ Function ConfirmPythonSelection
|
|||
StrCmp $R1 ${SF_SELECTED} SkipCheck 0
|
||||
|
||||
; Maybe the user just doesn't want Python support at all?
|
||||
SectionGetFlags ${SecPyBindings} $R1
|
||||
IntOp $R1 $R1 & ${SF_SELECTED}
|
||||
StrCmp $R1 ${SF_SELECTED} 0 SkipCheck
|
||||
!insertmacro SectionFlagIsSet ${SecGroupPython} ${SF_PSELECTED} 0 SkipCheck
|
||||
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
; Check for a user installation of Python.
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" CheckSystemWidePython 0
|
||||
StrCmp $0 "" CheckSystemWidePython 0
|
||||
IfFileExists "$0\ppython.exe" CheckSystemWidePython 0
|
||||
|
|
@ -491,7 +564,7 @@ Function ConfirmPythonSelection
|
|||
|
||||
; Check for a system-wide Python installation.
|
||||
CheckSystemWidePython:
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" AskConfirmation 0
|
||||
StrCmp $0 "" AskConfirmation 0
|
||||
IfFileExists "$0\ppython.exe" AskConfirmation 0
|
||||
|
|
@ -501,7 +574,7 @@ Function ConfirmPythonSelection
|
|||
; of a different Panda3D build.) Ask the user if he's sure about this.
|
||||
AskConfirmation:
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION \
|
||||
"You do not appear to have a ${REGVIEW}-bit version of Python ${PYVER} installed. Are you sure you don't want Panda to install a compatible copy of Python?$\r$\n$\r$\nIf you choose Yes, you will not be able to do Python development with Panda3D until you install a ${REGVIEW}-bit version of Python ${PYVER} and manually configure it to be able to use Panda3D." \
|
||||
"You do not appear to have a ${REGVIEW}-bit version of Python ${INCLUDE_PYVER} installed. Are you sure you don't want Panda to install a compatible copy of Python?$\r$\n$\r$\nIf you choose Yes, you will not be able to do Python development with Panda3D until you install a ${REGVIEW}-bit version of Python and install the bindings for this version." \
|
||||
IDYES SkipCheck
|
||||
|
||||
; User clicked no, so re-enable the select box and abort.
|
||||
|
|
@ -511,9 +584,10 @@ Function ConfirmPythonSelection
|
|||
|
||||
SkipCheck:
|
||||
FunctionEnd
|
||||
!endif
|
||||
|
||||
Section "C++ support" SecHeadersLibs
|
||||
SectionIn 1
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing header files..."
|
||||
|
|
@ -532,7 +606,7 @@ SectionEnd
|
|||
|
||||
!ifdef HAVE_SAMPLES
|
||||
Section "Sample programs" SecSamples
|
||||
SectionIn 1
|
||||
SectionIn 1 2
|
||||
|
||||
; Necessary for proper start menu shortcut installation
|
||||
SetShellVarContext current
|
||||
|
|
@ -599,7 +673,7 @@ SectionEnd
|
|||
|
||||
!ifdef HAVE_MAX_PLUGINS
|
||||
Section "3ds Max plug-ins" SecMaxPlugins
|
||||
SectionIn 1 3
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Autodesk 3ds Max plug-ins..."
|
||||
|
|
@ -614,7 +688,7 @@ SectionEnd
|
|||
|
||||
!ifdef HAVE_MAYA_PLUGINS
|
||||
Section "Maya plug-ins" SecMayaPlugins
|
||||
SectionIn 1 3
|
||||
SectionIn 1 2
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing Autodesk Maya plug-ins..."
|
||||
|
|
@ -737,17 +811,30 @@ Section Uninstall
|
|||
DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon"
|
||||
DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\shell"
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" 0 +2
|
||||
DeleteRegKey HKLM "Software\Python\PythonCore\${PYVER}"
|
||||
!ifdef INCLUDE_PYVER
|
||||
ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" 0 +2
|
||||
DeleteRegKey HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}"
|
||||
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" 0 +2
|
||||
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}"
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" ""
|
||||
StrCmp $0 "$INSTDIR\python" 0 +2
|
||||
DeleteRegKey HKCU "Software\Python\PythonCore\${INCLUDE_PYVER}"
|
||||
!endif
|
||||
|
||||
ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" ""
|
||||
StrCmp $0 "$INSTDIR" 0 +2
|
||||
DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D"
|
||||
!insertmacro RemovePythonPath 2.7
|
||||
!if "${REGVIEW}" == "32"
|
||||
!insertmacro RemovePythonPath 3.5-32
|
||||
!insertmacro RemovePythonPath 3.6-32
|
||||
!insertmacro RemovePythonPath 3.7-32
|
||||
!insertmacro RemovePythonPath 3.8-32
|
||||
!insertmacro RemovePythonPath 3.9-32
|
||||
!else
|
||||
!insertmacro RemovePythonPath 3.5
|
||||
!insertmacro RemovePythonPath 3.6
|
||||
!insertmacro RemovePythonPath 3.7
|
||||
!insertmacro RemovePythonPath 3.8
|
||||
!insertmacro RemovePythonPath 3.9
|
||||
!endif
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Deleting files..."
|
||||
|
|
@ -812,8 +899,23 @@ SectionEnd
|
|||
!insertmacro MUI_DESCRIPTION_TEXT ${SecRocket} $(DESC_SecRocket)
|
||||
!endif
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecTools} $(DESC_SecTools)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings} $(DESC_SecPyBindings)
|
||||
!ifdef HAVE_PYTHON
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecGroupPython} $(DESC_SecGroupPython)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyShared} $(DESC_SecPyShared)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings2.7} $(DESC_SecPyBindings2.7)
|
||||
!if "${REGVIEW}" == "32"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.5-32} $(DESC_SecPyBindings3.5-32)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.6-32} $(DESC_SecPyBindings3.6-32)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.7-32} $(DESC_SecPyBindings3.7-32)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.8-32} $(DESC_SecPyBindings3.8-32)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.9-32} $(DESC_SecPyBindings3.9-32)
|
||||
!else
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.5} $(DESC_SecPyBindings3.5)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.6} $(DESC_SecPyBindings3.6)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.7} $(DESC_SecPyBindings3.7)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.8} $(DESC_SecPyBindings3.8)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.9} $(DESC_SecPyBindings3.9)
|
||||
!endif
|
||||
!ifdef INCLUDE_PYVER
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecPython} $(DESC_SecPython)
|
||||
!endif
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecHeadersLibs} $(DESC_SecHeadersLibs)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ from distutils.sysconfig import get_python_lib
|
|||
from optparse import OptionParser
|
||||
from makepandacore import *
|
||||
|
||||
def python_sitepackages_path():
|
||||
from distutils.sysconfig import get_python_lib
|
||||
return get_python_lib(1)
|
||||
PYTHON_SITEPACKAGES=python_sitepackages_path()
|
||||
|
||||
MIME_INFO = (
|
||||
("egg", "model/x-egg", "EGG model file", "pview"),
|
||||
|
|
@ -153,18 +149,11 @@ def GetLibDir():
|
|||
|
||||
return "lib"
|
||||
|
||||
def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir()):
|
||||
def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(), python_versions=[]):
|
||||
if (not prefix.startswith("/")):
|
||||
prefix = "/" + prefix
|
||||
libdir = prefix + "/" + libdir
|
||||
|
||||
# Determine the location of the Python executable and site-packages dir.
|
||||
PPATH = get_python_lib(1)
|
||||
if os.path.islink(sys.executable):
|
||||
PEXEC = os.path.join(os.path.dirname(sys.executable), os.readlink(sys.executable))
|
||||
else:
|
||||
PEXEC = sys.executable
|
||||
|
||||
# Create the directory structure that we will be putting our files in.
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/bin")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/include")
|
||||
|
|
@ -174,8 +163,10 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
|
|||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/application-registry")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+PPATH)
|
||||
oscmd("mkdir -m 0755 -p "+destdir+PPATH+"/panda3d")
|
||||
|
||||
for python_version in python_versions:
|
||||
oscmd("mkdir -m 0755 -p "+destdir+python_version["purelib"])
|
||||
oscmd("mkdir -m 0755 -p "+destdir+python_version["platlib"]+"/panda3d")
|
||||
|
||||
if (sys.platform.startswith("freebsd")):
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
|
||||
|
|
@ -201,10 +192,12 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
|
|||
if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/")
|
||||
if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
|
||||
|
||||
suffix = GetExtensionSuffix()
|
||||
for base in os.listdir(outputdir + "/panda3d"):
|
||||
if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
|
||||
oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+PPATH+"/panda3d/"+base)
|
||||
for python_version in python_versions:
|
||||
for base in os.listdir(outputdir + "/panda3d"):
|
||||
suffix = python_version["ext_suffix"]
|
||||
platlib = python_version["platlib"]
|
||||
if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
|
||||
oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+platlib+"/panda3d/"+base)
|
||||
|
||||
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
|
||||
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
|
||||
|
|
@ -214,10 +207,14 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
|
|||
oscmd("cp makepanda/pview.desktop "+destdir+prefix+"/share/applications/pview.desktop")
|
||||
|
||||
oscmd("cp doc/ReleaseNotes "+destdir+prefix+"/share/panda3d/ReleaseNotes")
|
||||
oscmd("echo '"+prefix+"/share/panda3d' > "+destdir+PPATH+"/panda3d.pth")
|
||||
oscmd("echo '"+libdir+"/panda3d'>> "+destdir+PPATH+"/panda3d.pth")
|
||||
if os.path.isdir(outputdir+"/panda3d.dist-info"):
|
||||
oscmd("cp -R "+outputdir+"/panda3d.dist-info "+destdir+PPATH)
|
||||
|
||||
for python_version in python_versions:
|
||||
pth_file = python_version["purelib"] + "/panda3d.pth"
|
||||
oscmd("echo '"+prefix+"/share/panda3d' > "+destdir+pth_file)
|
||||
|
||||
if os.path.isdir(outputdir+"/panda3d.dist-info"):
|
||||
oscmd("cp -R "+outputdir+"/panda3d.dist-info "+destdir+python_version["platlib"])
|
||||
|
||||
if (sys.platform.startswith("freebsd")):
|
||||
oscmd("echo '"+libdir+"/panda3d'> "+destdir+"/usr/local/libdata/ldconfig/panda3d")
|
||||
else:
|
||||
|
|
@ -302,6 +299,8 @@ if (__name__ == "__main__"):
|
|||
if (destdir != "" and not os.path.isdir(destdir)):
|
||||
exit("Directory '%s' does not exist!" % destdir)
|
||||
|
||||
SetOutputDir(options.outputdir)
|
||||
|
||||
if options.verbose:
|
||||
SetVerbose(True)
|
||||
|
||||
|
|
@ -310,6 +309,8 @@ if (__name__ == "__main__"):
|
|||
InstallRuntime(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
|
||||
else:
|
||||
print("Installing Panda3D SDK into " + destdir + options.prefix)
|
||||
InstallPanda(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
|
||||
InstallPanda(destdir=destdir,
|
||||
prefix=options.prefix,
|
||||
outputdir=options.outputdir,
|
||||
python_versions=ReadPythonVersionInfoFile())
|
||||
print("Installation finished!")
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ Architecture: ARCH
|
|||
Essential: no
|
||||
Depends: DEPENDS
|
||||
Recommends: RECOMMENDS
|
||||
Provides: panda3d, pythonPV-panda3d
|
||||
Conflicts: panda3d, pythonPV-panda3d
|
||||
Replaces: panda3d, pythonPV-panda3d
|
||||
Provides: PROVIDES
|
||||
Conflicts: PROVIDES
|
||||
Replaces: PROVIDES
|
||||
Maintainer: rdb <me@rdb.name>
|
||||
Installed-Size: INSTSIZE
|
||||
Description: Panda3D free 3D engine SDK
|
||||
|
|
@ -73,7 +73,6 @@ This package contains the SDK for development with Panda3D, install panda3d-runt
|
|||
/usr/share/panda3d
|
||||
/etc/ld.so.conf.d/panda3d.conf
|
||||
/usr/%_lib/panda3d
|
||||
""" + PYTHON_SITEPACKAGES + """
|
||||
/usr/include/panda3d
|
||||
"""
|
||||
INSTALLER_SPEC_FILE_PVIEW = \
|
||||
|
|
@ -169,17 +168,10 @@ def MakeInstallerNSIS(version, file, title, installdir, runtime=False, compresso
|
|||
elif os.path.isdir(file):
|
||||
shutil.rmtree(file)
|
||||
|
||||
if "PYTHONVERSION" in SDK:
|
||||
pyver = SDK["PYTHONVERSION"][6:9]
|
||||
else:
|
||||
pyver = "%d.%d" % (sys.version_info[:2])
|
||||
|
||||
if GetTargetArch() == 'x64':
|
||||
regview = '64'
|
||||
else:
|
||||
regview = '32'
|
||||
if int(pyver[0]) == 3 and int(pyver[2]) >= 5:
|
||||
pyver += '-32'
|
||||
|
||||
if runtime:
|
||||
# Invoke the make_installer script.
|
||||
|
|
@ -212,11 +204,22 @@ def MakeInstallerNSIS(version, file, title, installdir, runtime=False, compresso
|
|||
'OUTFILE' : '..\\' + file,
|
||||
'BUILT' : '..\\' + outputdir,
|
||||
'SOURCE' : '..',
|
||||
'PYVER' : pyver,
|
||||
'REGVIEW' : regview,
|
||||
'EXT_SUFFIX': GetExtensionSuffix(),
|
||||
}
|
||||
|
||||
# Are we shipping a version of Python?
|
||||
if os.path.isfile(os.path.join(outputdir, "python", "python.exe")):
|
||||
py_dlls = glob.glob(os.path.join(outputdir, "python", "python[0-9][0-9].dll")) \
|
||||
+ glob.glob(os.path.join(outputdir, "python", "python[0-9][0-9]_d.dll"))
|
||||
assert py_dlls
|
||||
py_dll = os.path.basename(py_dlls[0])
|
||||
pyver = py_dll[6] + "." + py_dll[7]
|
||||
|
||||
if GetTargetArch() != 'x64':
|
||||
pyver += '-32'
|
||||
|
||||
nsis_defs['INCLUDE_PYVER'] = pyver
|
||||
|
||||
if GetHost() == 'windows':
|
||||
cmd = os.path.join(GetThirdpartyBase(), 'win-nsis', 'makensis') + ' /V2'
|
||||
for item in nsis_defs.items():
|
||||
|
|
@ -254,17 +257,28 @@ def MakeDebugSymbolArchive(zipname, dirname):
|
|||
zip.close()
|
||||
|
||||
|
||||
def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
||||
def MakeInstallerLinux(version, debversion=None, rpmrelease=1, runtime=False,
|
||||
python_versions=[], **kwargs):
|
||||
outputdir = GetOutputDir()
|
||||
|
||||
if not runtime and not PkgSkip("PYTHON"):
|
||||
if "PYTHONVERSION" in SDK:
|
||||
PYTHONV = SDK["PYTHONVERSION"].rstrip('dmu')
|
||||
else:
|
||||
PYTHONV = "python%d.%d" % (sys.version_info[:2])
|
||||
else:
|
||||
PYTHONV = "python"
|
||||
PV = PYTHONV.replace("python", "")
|
||||
# We pack Python 2 and Python 3, if we built with support for it.
|
||||
python2_ver = None
|
||||
python3_ver = None
|
||||
install_python_versions = []
|
||||
|
||||
if not runtime:
|
||||
# What's the system version of Python 3?
|
||||
oscmd('python3 -V > "%s/tmp/python3_version.txt"' % (outputdir))
|
||||
sys_python3_ver = '.'.join(ReadFile(outputdir + "/tmp/python3_version.txt").strip().split(' ')[1].split('.')[:2])
|
||||
|
||||
# Check that we built with support for these.
|
||||
for version_info in python_versions:
|
||||
if version_info["version"] == "2.7":
|
||||
python2_ver = "2.7"
|
||||
install_python_versions.append(version_info)
|
||||
elif version_info["version"] == sys_python3_ver:
|
||||
python3_ver = sys_python3_ver
|
||||
install_python_versions.append(version_info)
|
||||
|
||||
major_version = '.'.join(version.split('.')[:2])
|
||||
if not debversion:
|
||||
|
|
@ -272,7 +286,7 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
|
||||
# Clean and set up a directory to install Panda3D into
|
||||
oscmd("rm -rf targetroot data.tar.gz control.tar.gz panda3d.spec")
|
||||
oscmd("mkdir --mode=0755 targetroot")
|
||||
oscmd("mkdir -m 0755 targetroot")
|
||||
|
||||
dpkg_present = False
|
||||
if os.path.exists("/usr/bin/dpkg-architecture") and os.path.exists("/usr/bin/dpkg-deb"):
|
||||
|
|
@ -288,9 +302,12 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
# Invoke installpanda.py to install it into a temporary dir
|
||||
lib_dir = GetDebLibDir()
|
||||
if runtime:
|
||||
InstallRuntime(destdir="targetroot", prefix="/usr", outputdir=outputdir, libdir=lib_dir)
|
||||
InstallRuntime(destdir="targetroot", prefix="/usr",
|
||||
outputdir=outputdir, libdir=lib_dir)
|
||||
else:
|
||||
InstallPanda(destdir="targetroot", prefix="/usr", outputdir=outputdir, libdir=lib_dir)
|
||||
InstallPanda(destdir="targetroot", prefix="/usr",
|
||||
outputdir=outputdir, libdir=lib_dir,
|
||||
python_versions=install_python_versions)
|
||||
oscmd("chmod -R 755 targetroot/usr/share/panda3d")
|
||||
oscmd("mkdir -m 0755 -p targetroot/usr/share/man/man1")
|
||||
oscmd("install -m 0644 doc/man/*.1 targetroot/usr/share/man/man1/")
|
||||
|
|
@ -301,9 +318,10 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
txt = RUNTIME_INSTALLER_DEB_FILE[1:]
|
||||
else:
|
||||
txt = INSTALLER_DEB_FILE[1:]
|
||||
txt = txt.replace("VERSION", debversion).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", major_version)
|
||||
txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
|
||||
oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
|
||||
txt = txt.replace("VERSION", debversion).replace("ARCH", pkg_arch).replace("MAJOR", major_version)
|
||||
txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") // 1024))
|
||||
|
||||
oscmd("mkdir -m 0755 -p targetroot/DEBIAN")
|
||||
oscmd("cd targetroot && (find usr -type f -exec md5sum {} ;) > DEBIAN/md5sums")
|
||||
if not runtime:
|
||||
oscmd("cd targetroot && (find etc -type f -exec md5sum {} ;) >> DEBIAN/md5sums")
|
||||
|
|
@ -337,6 +355,7 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
oscmd("cd targetroot && %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
|
||||
depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
|
||||
recommends = ""
|
||||
provides = "panda3d-runtime"
|
||||
else:
|
||||
pkg_name = "panda3d" + major_version
|
||||
pkg_dir = "debian/panda3d" + major_version
|
||||
|
|
@ -352,15 +371,29 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
# Parse the substvars files generated by dpkg-shlibdeps.
|
||||
depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()
|
||||
recommends = ReadFile("targetroot/debian/substvars_rec").replace("shlibs:Depends=", "").strip()
|
||||
if PkgSkip("PYTHON")==0:
|
||||
depends += ", " + PYTHONV
|
||||
recommends += ", python-wxversion, python-profiler (>= " + PV + "), python-pmw, python-tk (>= " + PV + ")"
|
||||
if PkgSkip("NVIDIACG")==0:
|
||||
provides = "panda3d"
|
||||
|
||||
if python2_ver or python3_ver:
|
||||
recommends += ", python-pmw"
|
||||
|
||||
if python2_ver:
|
||||
depends += ", python%s" % (python2_ver)
|
||||
recommends += ", python-wxversion"
|
||||
recommends += ", python-tk (>= %s)" % (python2_ver)
|
||||
provides += ", python2-panda3d"
|
||||
|
||||
if python3_ver:
|
||||
depends += ", python%s" % (python3_ver)
|
||||
recommends += ", python3-tk (>= %s)" % (python3_ver)
|
||||
provides += ", python3-panda3d"
|
||||
|
||||
if not PkgSkip("NVIDIACG"):
|
||||
depends += ", nvidia-cg-toolkit"
|
||||
|
||||
# Write back the dependencies, and delete the dummy set-up.
|
||||
txt = txt.replace("DEPENDS", depends.strip(', '))
|
||||
txt = txt.replace("RECOMMENDS", recommends.strip(', '))
|
||||
txt = txt.replace("PROVIDES", provides.strip(', '))
|
||||
WriteFile("targetroot/DEBIAN/control", txt)
|
||||
oscmd("rm -rf targetroot/debian")
|
||||
|
||||
|
|
@ -376,7 +409,9 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
if runtime:
|
||||
InstallRuntime(destdir="targetroot", prefix="/usr", outputdir=outputdir, libdir=GetRPMLibDir())
|
||||
else:
|
||||
InstallPanda(destdir="targetroot", prefix="/usr", outputdir=outputdir, libdir=GetRPMLibDir())
|
||||
InstallPanda(destdir="targetroot", prefix="/usr",
|
||||
outputdir=outputdir, libdir=GetRPMLibDir(),
|
||||
python_versions=install_python_versions)
|
||||
oscmd("chmod -R 755 targetroot/usr/share/panda3d")
|
||||
|
||||
oscmd("rpm -E '%_target_cpu' > "+outputdir+"/tmp/architecture.txt")
|
||||
|
|
@ -392,15 +427,23 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
if not PkgSkip("PVIEW"):
|
||||
txt += INSTALLER_SPEC_FILE_PVIEW
|
||||
|
||||
# Add the platform-specific Python directories.
|
||||
dirs = set()
|
||||
for version_info in install_python_versions:
|
||||
dirs.add(version_info["platlib"])
|
||||
dirs.add(version_info["purelib"])
|
||||
|
||||
for dir in dirs:
|
||||
txt += dir + "\n"
|
||||
|
||||
# Add the binaries in /usr/bin explicitly to the spec file
|
||||
for base in os.listdir(outputdir + "/bin"):
|
||||
txt += "/usr/bin/%s\n" % (base)
|
||||
|
||||
# Write out the spec file.
|
||||
txt = txt.replace("VERSION", version)
|
||||
txt = txt.replace("RPMRELEASE", rpmrelease)
|
||||
txt = txt.replace("RPMRELEASE", str(rpmrelease))
|
||||
txt = txt.replace("PANDASOURCE", pandasource)
|
||||
txt = txt.replace("PV", PV)
|
||||
WriteFile("panda3d.spec", txt)
|
||||
|
||||
oscmd("fakeroot rpmbuild --define '_rpmdir "+pandasource+"' --buildroot '"+os.path.abspath("targetroot")+"' -bb panda3d.spec")
|
||||
|
|
@ -414,7 +457,7 @@ def MakeInstallerLinux(version, debversion=None, runtime=False, **kwargs):
|
|||
exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")
|
||||
|
||||
|
||||
def MakeInstallerOSX(version, runtime=False, **kwargs):
|
||||
def MakeInstallerOSX(version, runtime=False, python_versions=[], **kwargs):
|
||||
outputdir = GetOutputDir()
|
||||
|
||||
if runtime:
|
||||
|
|
@ -428,17 +471,11 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
oscmd(cmdstr)
|
||||
return
|
||||
|
||||
if "PYTHONVERSION" in SDK:
|
||||
pyver = SDK["PYTHONVERSION"][6:9]
|
||||
else:
|
||||
pyver = "%d.%d" % (sys.version_info[:2])
|
||||
|
||||
dmg_name = "Panda3D-" + version
|
||||
if not pyver.startswith("2."):
|
||||
if len(python_versions) == 1 and not python_versions[0]["version"].startswith("2."):
|
||||
dmg_name += "-py" + pyver
|
||||
dmg_name += ".dmg"
|
||||
|
||||
import compileall
|
||||
if (os.path.isfile(dmg_name)): oscmd("rm -f %s" % dmg_name)
|
||||
if (os.path.exists("dstroot")): oscmd("rm -rf dstroot")
|
||||
if (os.path.exists("Panda3D-rw.dmg")): oscmd('rm -f Panda3D-rw.dmg')
|
||||
|
|
@ -479,33 +516,43 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
# OSX needs the -R argument to copy symbolic links correctly, it doesn't have -d. How weird.
|
||||
oscmd("cp -R " + outputdir + "/bin/" + base + " " + binname)
|
||||
|
||||
if not PkgSkip("PYTHON"):
|
||||
pyexec = SDK.get("PYTHONEXEC", sys.executable)
|
||||
oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
|
||||
if python_versions:
|
||||
# Let's only write a ppython link if there is only one Python version.
|
||||
if len(python_versions) == 1:
|
||||
oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
|
||||
oscmd("ln -s %s dstroot/pythoncode/usr/local/bin/ppython" % (python_versions[0]["executable"]))
|
||||
|
||||
oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D/panda3d")
|
||||
oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % pyver)
|
||||
WriteFile("dstroot/pythoncode/Library/Python/%s/site-packages/Panda3D.pth" % pyver, "/Developer/Panda3D")
|
||||
oscmd("cp -R %s/pandac dstroot/pythoncode/Developer/Panda3D/pandac" % outputdir)
|
||||
oscmd("cp -R %s/direct dstroot/pythoncode/Developer/Panda3D/direct" % outputdir)
|
||||
oscmd("ln -s %s dstroot/pythoncode/usr/local/bin/ppython" % pyexec)
|
||||
oscmd("cp -R %s/*.so dstroot/pythoncode/Developer/Panda3D/" % outputdir, True)
|
||||
oscmd("cp -R %s/*.py dstroot/pythoncode/Developer/Panda3D/" % outputdir, True)
|
||||
if os.path.isdir(outputdir+"/Pmw"):
|
||||
oscmd("cp -R %s/Pmw dstroot/pythoncode/Developer/Panda3D/Pmw" % outputdir)
|
||||
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/Pmw")
|
||||
WriteFile("dstroot/pythoncode/Developer/Panda3D/direct/__init__.py", "")
|
||||
for base in os.listdir("dstroot/pythoncode/Developer/Panda3D/direct"):
|
||||
if ((base != "extensions") and (base != "extensions_native")):
|
||||
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/direct/"+base)
|
||||
|
||||
suffix = GetExtensionSuffix()
|
||||
for base in os.listdir(outputdir+"/panda3d"):
|
||||
if base.endswith('.py') or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
|
||||
if base.endswith('.py'):
|
||||
libname = "dstroot/pythoncode/Developer/Panda3D/panda3d/" + base
|
||||
oscmd("cp -R " + outputdir + "/panda3d/" + base + " " + libname)
|
||||
|
||||
for version_info in python_versions:
|
||||
pyver = version_info["version"]
|
||||
oscmd("mkdir -p dstroot/pybindings%s/Library/Python/%s/site-packages" % (pyver, pyver))
|
||||
oscmd("mkdir -p dstroot/pybindings%s/Developer/Panda3D/panda3d" % (pyver))
|
||||
|
||||
# Copy over extension modules.
|
||||
suffix = version_info["ext_suffix"]
|
||||
for base in os.listdir(outputdir+"/panda3d"):
|
||||
if base.endswith(suffix) and '.' not in base[:-len(suffix)]:
|
||||
libname = "dstroot/pybindings%s/Developer/Panda3D/panda3d/%s" % (pyver, base)
|
||||
# We really need to specify -R in order not to follow symlinks
|
||||
# On OSX, just specifying -P is not enough to do that.
|
||||
oscmd("cp -R -P " + outputdir + "/panda3d/" + base + " " + libname)
|
||||
|
||||
# Write a .pth file.
|
||||
oscmd("mkdir -p dstroot/pybindings%s/Library/Python/%s/site-packages" % (pyver, pyver))
|
||||
WriteFile("dstroot/pybindings%s/Library/Python/%s/site-packages/Panda3D.pth" % (pyver, pyver), "/Developer/Panda3D")
|
||||
|
||||
if not PkgSkip("FFMPEG"):
|
||||
oscmd("mkdir -p dstroot/ffmpeg/Developer/Panda3D/lib")
|
||||
oscmd("cp -R %s/lib/libp3ffmpeg.* dstroot/ffmpeg/Developer/Panda3D/lib/" % outputdir)
|
||||
|
|
@ -528,9 +575,19 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
oscmd("mkdir -p dstroot/samples/Developer/Examples/Panda3D")
|
||||
oscmd("cp -R samples/* dstroot/samples/Developer/Examples/Panda3D/")
|
||||
|
||||
oscmd("chmod -R 0775 dstroot/*")
|
||||
DeleteVCS("dstroot")
|
||||
DeleteBuildFiles("dstroot")
|
||||
|
||||
# Compile Python files. Do this *after* the DeleteVCS step, above, which
|
||||
# deletes __pycache__ directories.
|
||||
for version_info in python_versions:
|
||||
if os.path.isdir("dstroot/pythoncode/Developer/Panda3D/Pmw"):
|
||||
oscmd("%s -m compileall -q -f -d /Developer/Panda3D/Pmw dstroot/pythoncode/Developer/Panda3D/Pmw" % (version_info["executable"]), True)
|
||||
oscmd("%s -m compileall -q -f -d /Developer/Panda3D/direct dstroot/pythoncode/Developer/Panda3D/direct" % (version_info["executable"]))
|
||||
oscmd("%s -m compileall -q -f -d /Developer/Panda3D/pandac dstroot/pythoncode/Developer/Panda3D/pandac" % (version_info["executable"]))
|
||||
oscmd("%s -m compileall -q -f -d /Developer/Panda3D/panda3d dstroot/pythoncode/Developer/Panda3D/panda3d" % (version_info["executable"]))
|
||||
|
||||
oscmd("chmod -R 0775 dstroot/*")
|
||||
# We need to be root to perform a chown. Bleh.
|
||||
# Fortunately PackageMaker does it for us, on 10.5 and above.
|
||||
#oscmd("chown -R root:admin dstroot/*", True)
|
||||
|
|
@ -539,7 +596,10 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
oscmd("mkdir -p dstroot/Panda3D/Panda3D.mpkg/Contents/Resources/en.lproj/")
|
||||
|
||||
pkgs = ["base", "tools", "headers"]
|
||||
if not PkgSkip("PYTHON"): pkgs.append("pythoncode")
|
||||
if python_versions:
|
||||
pkgs.append("pythoncode")
|
||||
for version_info in python_versions:
|
||||
pkgs.append("pybindings" + version_info["version"])
|
||||
if not PkgSkip("FFMPEG"): pkgs.append("ffmpeg")
|
||||
#if not PkgSkip("OPENAL"): pkgs.append("openal")
|
||||
if not PkgSkip("FMODEX"): pkgs.append("fmodex")
|
||||
|
|
@ -581,22 +641,55 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
dist.write(' <title>Panda3D SDK %s</title>\n' % (version))
|
||||
dist.write(' <options customize="always" allow-external-scripts="no" rootVolumeOnly="false"/>\n')
|
||||
dist.write(' <license language="en" mime-type="text/plain">%s</license>\n' % ReadFile("doc/LICENSE"))
|
||||
dist.write(' <script>\n')
|
||||
dist.write(' function isPythonVersionInstalled(version) {\n')
|
||||
dist.write(' return system.files.fileExistsAtPath("/usr/bin/python" + version)\n')
|
||||
dist.write(' || system.files.fileExistsAtPath("/usr/local/bin/python" + version)\n')
|
||||
dist.write(' || system.files.fileExistsAtPath("/opt/local/bin/python" + version)\n')
|
||||
dist.write(' || system.files.fileExistsAtPath("/sw/bin/python" + version)\n')
|
||||
dist.write(' || system.files.fileExistsAtPath("/System/Library/Frameworks/Python.framework/Versions/" + version + "/bin/python")\n')
|
||||
dist.write(' || system.files.fileExistsAtPath("/Library/Frameworks/Python.framework/Versions/" + version + "/bin/python");\n')
|
||||
dist.write(' }\n')
|
||||
dist.write(' </script>\n')
|
||||
dist.write(' <choices-outline>\n')
|
||||
for pkg in pkgs:
|
||||
dist.write(' <line choice="%s"/>\n' % (pkg))
|
||||
dist.write(' <line choice="base"/>\n')
|
||||
if python_versions:
|
||||
dist.write(' <line choice="pythoncode">\n')
|
||||
for version_info in sorted(python_versions, key=lambda info:info["version"], reverse=True):
|
||||
dist.write(' <line choice="pybindings%s"/>\n' % (version_info["version"]))
|
||||
dist.write(' </line>\n')
|
||||
dist.write(' <line choice="tools"/>\n')
|
||||
if os.path.isdir("samples"):
|
||||
dist.write(' <line choice="samples"/>\n')
|
||||
if not PkgSkip("FFMPEG"):
|
||||
dist.write(' <line choice="ffmpeg"/>\n')
|
||||
if not PkgSkip("FMODEX"):
|
||||
dist.write(' <line choice="fmodex"/>\n')
|
||||
dist.write(' <line choice="headers"/>\n')
|
||||
dist.write(' </choices-outline>\n')
|
||||
dist.write(' <choice id="base" title="Panda3D Base Installation" description="This package contains the Panda3D libraries, configuration files and models/textures that are needed to use Panda3D. Location: /Developer/Panda3D/" start_enabled="false">\n')
|
||||
dist.write(' <choice id="base" title="Panda3D Base Installation" description="This package contains the Panda3D libraries, configuration files and models/textures that are needed to use Panda3D. Location: /Developer/Panda3D/" start_enabled="false">\n')
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.base.pkg"/>\n')
|
||||
dist.write(' </choice>\n')
|
||||
dist.write(' <choice id="tools" title="Tools" tooltip="Useful tools and model converters to help with Panda3D development" description="This package contains the various utilities that ship with Panda3D, including packaging tools, model converters, and many more. Location: /Developer/Panda3D/bin/">\n')
|
||||
dist.write(' <choice id="tools" title="Tools" tooltip="Useful tools and model converters to help with Panda3D development" description="This package contains the various utilities that ship with Panda3D, including packaging tools, model converters, and many more. Location: /Developer/Panda3D/bin/">\n')
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.tools.pkg"/>\n')
|
||||
dist.write(' </choice>\n')
|
||||
|
||||
if not PkgSkip("PYTHON"):
|
||||
dist.write(' <choice id="pythoncode" title="Python Support" tooltip="Python bindings for the Panda3D libraries" description="This package contains the \'direct\', \'pandac\' and \'panda3d\' python packages that are needed to do Python development with Panda3D. Location: /Developer/Panda3D/">\n')
|
||||
if python_versions:
|
||||
dist.write(' <choice id="pythoncode" title="Python Support" tooltip="Python bindings for the Panda3D libraries" description="This package contains the \'direct\', \'pandac\' and \'panda3d\' python packages that are needed to do Python development with Panda3D. Location: /Developer/Panda3D/">\n')
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.pythoncode.pkg"/>\n')
|
||||
dist.write(' </choice>\n')
|
||||
|
||||
for version_info in python_versions:
|
||||
pyver = version_info["version"]
|
||||
if pyver == "2.7":
|
||||
# Always install Python 2.7 by default; it's included on macOS.
|
||||
cond = "true"
|
||||
else:
|
||||
cond = "isPythonVersionInstalled('%s')" % (pyver)
|
||||
dist.write(' <choice id="pybindings%s" start_selected="%s" title="Python %s Bindings" tooltip="Python bindings for the Panda3D libraries" description="Support for Python %s.">\n' % (pyver, cond, pyver, pyver))
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.pybindings%s.pkg"/>\n' % (pyver))
|
||||
dist.write(' </choice>\n')
|
||||
|
||||
if not PkgSkip("FFMPEG"):
|
||||
dist.write(' <choice id="ffmpeg" title="FFMpeg Plug-In" tooltip="FFMpeg video and audio decoding plug-in" description="This package contains the FFMpeg plug-in, which is used for decoding video and audio files with OpenAL.')
|
||||
if PkgSkip("VORBIS") and PkgSkip("OPUS"):
|
||||
|
|
@ -621,11 +714,11 @@ def MakeInstallerOSX(version, runtime=False, **kwargs):
|
|||
dist.write(' </choice>\n')
|
||||
|
||||
if os.path.isdir("samples"):
|
||||
dist.write(' <choice id="samples" title="Sample Programs" tooltip="Python sample programs that use Panda3D" description="This package contains the Python sample programs that can help you with learning how to use Panda3D. Location: /Developer/Examples/Panda3D/">\n')
|
||||
dist.write(' <choice id="samples" title="Sample Programs" tooltip="Python sample programs that use Panda3D" description="This package contains the Python sample programs that can help you with learning how to use Panda3D. Location: /Developer/Examples/Panda3D/">\n')
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.samples.pkg"/>\n')
|
||||
dist.write(' </choice>\n')
|
||||
|
||||
dist.write(' <choice id="headers" title="C++ Header Files" tooltip="Header files for C++ development with Panda3D" description="This package contains the C++ header files that are needed in order to do C++ development with Panda3D. You don\'t need this if you want to develop in Python. Location: /Developer/Panda3D/include/" start_selected="false">\n')
|
||||
dist.write(' <choice id="headers" title="C++ Header Files" tooltip="Header files for C++ development with Panda3D" description="This package contains the C++ header files that are needed in order to do C++ development with Panda3D. You don\'t need this if you want to develop in Python. Location: /Developer/Panda3D/include/" start_selected="false">\n')
|
||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.headers.pkg"/>\n')
|
||||
dist.write(' </choice>\n')
|
||||
for pkg in pkgs:
|
||||
|
|
@ -693,7 +786,7 @@ def MakeInstallerFreeBSD(version, runtime=False, **kwargs):
|
|||
manifest_txt = manifest_txt.replace("ARCH", pkg_arch)
|
||||
manifest_txt = manifest_txt.replace("ORIGIN", 'devel/panda3d' if not runtime else 'graphics/panda3d-runtime')
|
||||
manifest_txt = manifest_txt.replace("DEPENDS", dependencies)
|
||||
manifest_txt = manifest_txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024 / 1024))
|
||||
manifest_txt = manifest_txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") // 1024 // 1024))
|
||||
|
||||
WriteFile("pkg-plist", plist_txt)
|
||||
WriteFile("+DESC", INSTALLER_PKG_DESCR_FILE[1:] if not runtime else RUNTIME_INSTALLER_PKG_DESCR_FILE[1:])
|
||||
|
|
@ -889,13 +982,9 @@ def MakeInstaller(version, **kwargs):
|
|||
|
||||
fn += version
|
||||
|
||||
if "PYTHONVERSION" in SDK:
|
||||
pyver = SDK["PYTHONVERSION"][6:9]
|
||||
else:
|
||||
pyver = "%d.%d" % (sys.version_info[:2])
|
||||
|
||||
if not runtime and pyver != "2.7":
|
||||
fn += '-py' + pyver
|
||||
python_versions = kwargs.get('python_versions', [])
|
||||
if not runtime and len(python_versions) == 1 and python_versions[0]["version"] != "2.7":
|
||||
fn += '-py' + python_versions[0]["version"]
|
||||
|
||||
if GetOptimize() <= 2:
|
||||
fn += "-dbg"
|
||||
|
|
@ -961,4 +1050,5 @@ if __name__ == "__main__":
|
|||
compressor=options.compressor,
|
||||
debversion=options.debversion,
|
||||
rpmrelease=options.rpmrelease,
|
||||
runtime=options.runtime)
|
||||
runtime=options.runtime,
|
||||
python_versions=ReadPythonVersionInfoFile())
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ MSVC_VERSION = None
|
|||
BOOUSEINTELCOMPILER = False
|
||||
OPENCV_VER_23 = False
|
||||
PLATFORM = None
|
||||
COPY_PYTHON = True
|
||||
|
||||
if "MACOSX_DEPLOYMENT_TARGET" in os.environ:
|
||||
OSXTARGET=os.environ["MACOSX_DEPLOYMENT_TARGET"]
|
||||
|
|
@ -172,6 +173,7 @@ def parseopts(args):
|
|||
global COMPRESSOR,THREADCOUNT,OSXTARGET,OSX_ARCHS,HOST_URL
|
||||
global DEBVERSION,WHLVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX,RTDIST_VERSION
|
||||
global STRDXSDKVERSION, WINDOWS_SDK, MSVC_VERSION, BOOUSEINTELCOMPILER
|
||||
global COPY_PYTHON
|
||||
|
||||
# Options for which to display a deprecation warning.
|
||||
removedopts = [
|
||||
|
|
@ -185,7 +187,7 @@ def parseopts(args):
|
|||
"version=","lzma","no-python","threads=","outputdir=","override=",
|
||||
"static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=",
|
||||
"directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl",
|
||||
"universal", "target=", "arch=", "git-commit=",
|
||||
"universal", "target=", "arch=", "git-commit=", "no-copy-python",
|
||||
] + removedopts
|
||||
|
||||
anything = 0
|
||||
|
|
@ -251,6 +253,7 @@ def parseopts(args):
|
|||
MSVC_VERSION = value.strip().lower()
|
||||
elif (option=="--use-icl"): BOOUSEINTELCOMPILER = True
|
||||
elif (option=="--clean"): clean_build = True
|
||||
elif (option=="--no-copy-python"): COPY_PYTHON = False
|
||||
elif (option[2:] in removedopts):
|
||||
Warn("Ignoring removed option %s" % (option))
|
||||
else:
|
||||
|
|
@ -3031,7 +3034,7 @@ else:
|
|||
configprc = configprc.replace("aux-display pandadx9", "")
|
||||
|
||||
if (GetTarget() == 'darwin'):
|
||||
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "Library/Caches/Panda3D-%s" % MAJOR_VERSION)
|
||||
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$HOME/Library/Caches/Panda3D-%s" % MAJOR_VERSION)
|
||||
|
||||
# OpenAL is not yet working well on OSX for us, so let's do this for now.
|
||||
configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
|
||||
|
|
@ -3155,7 +3158,8 @@ if tp_dir is not None:
|
|||
CopyFile(GetOutputDir() + "/bin/", fn)
|
||||
|
||||
# Copy the whole Python directory.
|
||||
CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
|
||||
if COPY_PYTHON:
|
||||
CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
|
||||
|
||||
# NB: Python does not always ship with the correct manifest/dll.
|
||||
# Figure out the correct one to ship, and grab it from WinSxS dir.
|
||||
|
|
@ -3164,7 +3168,7 @@ if tp_dir is not None:
|
|||
os.unlink(manifest)
|
||||
oscmd('mt -inputresource:"%s\\python.exe";#1 -out:"%s" -nologo' % (SDK["PYTHON"], manifest), True)
|
||||
|
||||
if os.path.isfile(manifest):
|
||||
if COPY_PYTHON and os.path.isfile(manifest):
|
||||
import xml.etree.ElementTree as ET
|
||||
tree = ET.parse(manifest)
|
||||
idents = tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity')
|
||||
|
|
@ -3194,11 +3198,12 @@ if tp_dir is not None:
|
|||
CopyFile(GetOutputDir() + "/python/", file)
|
||||
|
||||
# Copy python.exe to ppython.exe.
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
|
||||
ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
|
||||
if COPY_PYTHON:
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
|
||||
ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
|
||||
|
||||
# Copy over the MSVC runtime.
|
||||
if GetTarget() == 'windows' and "VISUALSTUDIO" in SDK:
|
||||
|
|
@ -6869,6 +6874,10 @@ if RUNTESTS:
|
|||
cmdstr += " --verbose"
|
||||
oscmd(cmdstr)
|
||||
|
||||
# Write out information about the Python versions in the built dir.
|
||||
python_version_info = GetCurrentPythonVersionInfo()
|
||||
UpdatePythonVersionInfoFile(python_version_info)
|
||||
|
||||
##########################################################################################
|
||||
#
|
||||
# The Installers
|
||||
|
|
@ -6882,10 +6891,16 @@ if RUNTESTS:
|
|||
if INSTALLER:
|
||||
ProgressOutput(100.0, "Building installer")
|
||||
from makepackage import MakeInstaller
|
||||
|
||||
# When using the --installer flag, only install for the current version.
|
||||
python_versions = []
|
||||
if python_version_info:
|
||||
python_versions.append(python_version_info)
|
||||
|
||||
MakeInstaller(version=VERSION, outputdir=GetOutputDir(),
|
||||
optimize=GetOptimize(), compressor=COMPRESSOR,
|
||||
debversion=DEBVERSION, rpmrelease=RPMRELEASE,
|
||||
runtime=RUNTIME)
|
||||
runtime=RUNTIME, python_versions=python_versions)
|
||||
|
||||
if WHEEL:
|
||||
ProgressOutput(100.0, "Building wheel")
|
||||
|
|
|
|||
|
|
@ -1043,7 +1043,7 @@
|
|||
<File RelativePath="..\panda\src\collide\collisionLine.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionHandlerFluidPusher.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\config_collide.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionTube.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionCapsule.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionSegment.cxx"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionBox.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collide_composite1.cxx"></File>
|
||||
|
|
@ -1054,7 +1054,7 @@
|
|||
<File RelativePath="..\panda\src\collide\collisionNode.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionGeom.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionSegment.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionTube.cxx"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionCapsule.cxx"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionHandlerQueue.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionParabola.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionPlane.cxx"></File>
|
||||
|
|
@ -1089,7 +1089,7 @@
|
|||
<File RelativePath="..\panda\src\collide\collisionInvSphere.cxx"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionLine.cxx"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionEntry.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionTube.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionCapsule.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionSolid.h"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionPlane.I"></File>
|
||||
<File RelativePath="..\panda\src\collide\collisionHandlerGravity.cxx"></File>
|
||||
|
|
|
|||
|
|
@ -3383,6 +3383,71 @@ def FindLocation(fn, ipath, pyabi=None):
|
|||
ORIG_EXT[loc] = ext
|
||||
return loc
|
||||
|
||||
|
||||
########################################################################
|
||||
##
|
||||
## These files maintain a python_versions.json file in the built/tmp
|
||||
## directory that can be used by the other scripts in this directory.
|
||||
##
|
||||
########################################################################
|
||||
|
||||
|
||||
def GetCurrentPythonVersionInfo():
|
||||
if PkgSkip("PYTHON"):
|
||||
return
|
||||
|
||||
from distutils.sysconfig import get_python_lib
|
||||
return {
|
||||
"version": SDK["PYTHONVERSION"][6:9],
|
||||
"soabi": GetPythonABI(),
|
||||
"ext_suffix": GetExtensionSuffix(),
|
||||
"executable": sys.executable,
|
||||
"purelib": get_python_lib(False),
|
||||
"platlib": get_python_lib(True),
|
||||
}
|
||||
|
||||
|
||||
def UpdatePythonVersionInfoFile(new_info):
|
||||
import json
|
||||
|
||||
json_file = os.path.join(GetOutputDir(), "tmp", "python_versions.json")
|
||||
json_data = []
|
||||
if os.path.isfile(json_file) and not PkgSkip("PYTHON"):
|
||||
try:
|
||||
json_data = json.load(open(json_file, 'r'))
|
||||
except:
|
||||
json_data = []
|
||||
|
||||
# Prune the list by removing the entries that conflict with our build,
|
||||
# plus the entries that no longer exist
|
||||
for version_info in json_data[:]:
|
||||
core_pyd = os.path.join(GetOutputDir(), "panda3d", "core" + version_info["ext_suffix"])
|
||||
if version_info["ext_suffix"] == new_info["ext_suffix"] or \
|
||||
version_info["soabi"] == new_info["soabi"] or \
|
||||
not os.path.isfile(core_pyd):
|
||||
json_data.remove(version_info)
|
||||
|
||||
if not PkgSkip("PYTHON"):
|
||||
json_data.append(new_info)
|
||||
|
||||
if VERBOSE:
|
||||
print("Writing %s" % (json_file))
|
||||
json.dump(json_data, open(json_file, 'w'), indent=4)
|
||||
|
||||
|
||||
def ReadPythonVersionInfoFile():
|
||||
import json
|
||||
|
||||
json_file = os.path.join(GetOutputDir(), "tmp", "python_versions.json")
|
||||
if os.path.isfile(json_file):
|
||||
try:
|
||||
return json.load(open(json_file, 'r'))
|
||||
except:
|
||||
pass
|
||||
|
||||
return []
|
||||
|
||||
|
||||
########################################################################
|
||||
##
|
||||
## TargetAdd
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "collisionPlane.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionPolygon.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
|
||||
TypeHandle BulletBodyNode::_type_handle;
|
||||
|
||||
|
|
@ -813,12 +813,12 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
|
|||
do_add_shape(BulletBoxShape::make_from_solid(box), ts);
|
||||
}
|
||||
|
||||
// CollisionTube
|
||||
else if (CollisionTube::get_class_type() == type) {
|
||||
CPT(CollisionTube) tube = DCAST(CollisionTube, solid);
|
||||
CPT(TransformState) ts = TransformState::make_pos((tube->get_point_b() + tube->get_point_a()) / 2.0);
|
||||
// CollisionCapsule
|
||||
else if (CollisionCapsule::get_class_type() == type) {
|
||||
CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, solid);
|
||||
CPT(TransformState) ts = TransformState::make_pos((capsule->get_point_b() + capsule->get_point_a()) / 2.0);
|
||||
|
||||
do_add_shape(BulletCapsuleShape::make_from_solid(tube), ts);
|
||||
do_add_shape(BulletCapsuleShape::make_from_solid(capsule), ts);
|
||||
}
|
||||
|
||||
// CollisionPlane
|
||||
|
|
|
|||
|
|
@ -87,16 +87,16 @@ ptr() const {
|
|||
|
||||
/**
|
||||
* Constructs a new BulletCapsuleShape using the information from a
|
||||
* CollisionTube from the builtin collision system.
|
||||
* CollisionCapsule from the builtin collision system.
|
||||
*/
|
||||
BulletCapsuleShape *BulletCapsuleShape::
|
||||
make_from_solid(const CollisionTube *solid) {
|
||||
|
||||
make_from_solid(const CollisionCapsule *solid) {
|
||||
|
||||
PN_stdfloat radius = solid->get_radius();
|
||||
// Get tube's cylinder height: length from point A to point B
|
||||
// Get capsule's cylinder height: length from point A to point B
|
||||
PN_stdfloat height = (solid->get_point_b() - solid->get_point_a()).length();
|
||||
|
||||
// CollisionTubes are always Z-Up.
|
||||
// CollisionCapsules are always Z-Up.
|
||||
return new BulletCapsuleShape(radius, height, Z_up);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "bullet_utils.h"
|
||||
#include "bulletShape.h"
|
||||
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -35,7 +35,7 @@ PUBLISHED:
|
|||
BulletCapsuleShape(const BulletCapsuleShape ©);
|
||||
INLINE ~BulletCapsuleShape();
|
||||
|
||||
static BulletCapsuleShape *make_from_solid(const CollisionTube *solid);
|
||||
static BulletCapsuleShape *make_from_solid(const CollisionCapsule *solid);
|
||||
|
||||
INLINE PN_stdfloat get_radius() const;
|
||||
INLINE PN_stdfloat get_half_height() const;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#import <AppKit/NSOpenGL.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
|
||||
/**
|
||||
* A tiny specialization on GLGraphicsStateGuardian to add some Cocoa-specific
|
||||
|
|
@ -38,14 +39,21 @@ public:
|
|||
CocoaGraphicsStateGuardian *share_with);
|
||||
|
||||
virtual ~CocoaGraphicsStateGuardian();
|
||||
bool setup_vsync();
|
||||
|
||||
INLINE void lock_context();
|
||||
INLINE void unlock_context();
|
||||
|
||||
NSOpenGLContext *_share_context;
|
||||
NSOpenGLContext *_context;
|
||||
NSOpenGLPixelFormat *_format = nullptr;
|
||||
FrameBufferProperties _fbprops;
|
||||
|
||||
CVDisplayLinkRef _display_link = nullptr;
|
||||
TrueMutexImpl _swap_lock;
|
||||
TrueConditionVarImpl _swap_condition;
|
||||
AtomicAdjust::Integer _last_wait_frame = 0;
|
||||
|
||||
protected:
|
||||
virtual void query_gl_version();
|
||||
virtual void *do_get_extension_func(const char *name);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,21 @@
|
|||
#define NSAppKitVersionNumber10_7 1138
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called whenever a display wants a frame. The context argument contains the
|
||||
* applicable CocoaGraphicsStateGuardian.
|
||||
*/
|
||||
static CVReturn
|
||||
display_link_cb(CVDisplayLinkRef link, const CVTimeStamp *now,
|
||||
const CVTimeStamp* output_time, CVOptionFlags flags_in,
|
||||
CVOptionFlags *flags_out, void *context) {
|
||||
CocoaGraphicsStateGuardian *gsg = (CocoaGraphicsStateGuardian *)context;
|
||||
gsg->_swap_lock.lock();
|
||||
gsg->_swap_condition.notify();
|
||||
gsg->_swap_lock.unlock();
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
TypeHandle CocoaGraphicsStateGuardian::_type_handle;
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +51,8 @@ TypeHandle CocoaGraphicsStateGuardian::_type_handle;
|
|||
CocoaGraphicsStateGuardian::
|
||||
CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
CocoaGraphicsStateGuardian *share_with) :
|
||||
GLGraphicsStateGuardian(engine, pipe)
|
||||
GLGraphicsStateGuardian(engine, pipe),
|
||||
_swap_condition(_swap_lock)
|
||||
{
|
||||
_share_context = nil;
|
||||
_context = nil;
|
||||
|
|
@ -52,12 +68,60 @@ CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
*/
|
||||
CocoaGraphicsStateGuardian::
|
||||
~CocoaGraphicsStateGuardian() {
|
||||
if (_format != nil) {
|
||||
[_format release];
|
||||
}
|
||||
if (_display_link != nil) {
|
||||
CVDisplayLinkRelease(_display_link);
|
||||
_display_link = nil;
|
||||
_swap_lock.lock();
|
||||
_swap_condition.notify();
|
||||
_swap_lock.unlock();
|
||||
}
|
||||
if (_context != nil) {
|
||||
[_context clearDrawable];
|
||||
[_context release];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CVDisplayLink, which tells us when the display the window is on
|
||||
* will want a frame.
|
||||
*/
|
||||
bool CocoaGraphicsStateGuardian::
|
||||
setup_vsync() {
|
||||
if (_display_link != nil) {
|
||||
// Already set up.
|
||||
return true;
|
||||
}
|
||||
|
||||
CVReturn result = CVDisplayLinkCreateWithActiveCGDisplays(&_display_link);
|
||||
if (result != kCVReturnSuccess) {
|
||||
cocoadisplay_cat.error() << "Failed to create CVDisplayLink.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
result = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(_display_link, (CGLContextObj)[_context CGLContextObj], (CGLPixelFormatObj)[_format CGLPixelFormatObj]);
|
||||
if (result != kCVReturnSuccess) {
|
||||
cocoadisplay_cat.error() << "Failed to set CVDisplayLink's current display.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
result = CVDisplayLinkSetOutputCallback(_display_link, &display_link_cb, this);
|
||||
if (result != kCVReturnSuccess) {
|
||||
cocoadisplay_cat.error() << "Failed to set CVDisplayLink output callback.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
result = CVDisplayLinkStart(_display_link);
|
||||
if (result != kCVReturnSuccess) {
|
||||
cocoadisplay_cat.error() << "Failed to start the CVDisplayLink.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FrameBufferProperties to match the indicated config.
|
||||
*/
|
||||
|
|
@ -262,15 +326,15 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||
// TODO: print out renderer
|
||||
|
||||
_context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:_share_context];
|
||||
[format release];
|
||||
_format = format;
|
||||
if (_context == nil) {
|
||||
cocoadisplay_cat.error() <<
|
||||
"Failed to create OpenGL context!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Set vsync setting on the context
|
||||
GLint swap = sync_video ? 1 : 0;
|
||||
// Disable vsync via the built-in mechanism, which doesn't work on Mojave
|
||||
GLint swap = 0;
|
||||
[_context setValues:&swap forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#import <AppKit/NSView.h>
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
|
||||
/**
|
||||
* An interface to the Cocoa system for managing OpenGL windows under Mac OS
|
||||
* X.
|
||||
|
|
@ -92,6 +94,7 @@ private:
|
|||
PT(GraphicsWindowInputDevice) _input;
|
||||
bool _mouse_hidden;
|
||||
bool _context_needs_update;
|
||||
bool _vsync_enabled = false;
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
CGDisplayModeRef _fullscreen_mode;
|
||||
|
|
|
|||
|
|
@ -274,6 +274,15 @@ end_flip() {
|
|||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
DCAST_INTO_V(cocoagsg, _gsg);
|
||||
|
||||
if (_vsync_enabled) {
|
||||
AtomicAdjust::Integer cur_frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (AtomicAdjust::set(cocoagsg->_last_wait_frame, cur_frame) != cur_frame) {
|
||||
cocoagsg->_swap_lock.lock();
|
||||
cocoagsg->_swap_condition.wait();
|
||||
cocoagsg->_swap_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
cocoagsg->lock_context();
|
||||
|
||||
// Swap the front and back buffer.
|
||||
|
|
@ -669,6 +678,8 @@ open_window() {
|
|||
mouse_mode_relative();
|
||||
}
|
||||
|
||||
_vsync_enabled = sync_video && cocoagsg->setup_vsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -710,6 +721,8 @@ close_window() {
|
|||
_view = nil;
|
||||
}
|
||||
|
||||
_vsync_enabled = false;
|
||||
|
||||
GraphicsWindow::close_window();
|
||||
}
|
||||
|
||||
|
|
@ -1491,6 +1504,7 @@ handle_close_event() {
|
|||
cocoagsg->unlock_context();
|
||||
}
|
||||
_gsg.clear();
|
||||
_vsync_enabled = false;
|
||||
}
|
||||
|
||||
// Dump the view, too
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "collisionRay.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionHandler.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "config_collide.h"
|
||||
|
|
@ -547,19 +547,19 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Double dispatch point for tube as a FROM object
|
||||
* Double dispatch point for capsule as a FROM object
|
||||
*/
|
||||
PT(CollisionEntry) CollisionBox::
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const {
|
||||
const CollisionTube *tube;
|
||||
DCAST_INTO_R(tube, entry.get_from(), nullptr);
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const {
|
||||
const CollisionCapsule *capsule;
|
||||
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
|
||||
|
||||
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
|
||||
|
||||
LPoint3 from_a = tube->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = tube->get_point_b() * wrt_mat;
|
||||
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
|
||||
LVector3 from_direction = from_b - from_a;
|
||||
PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, tube->get_radius())).length_squared();
|
||||
PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared();
|
||||
PN_stdfloat radius = csqrt(radius_sq);
|
||||
|
||||
LPoint3 box_min = get_min();
|
||||
|
|
@ -620,7 +620,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
LVector3 delta(0);
|
||||
delta[edges[i].axis] = dimensions[edges[i].axis];
|
||||
double u1, u2;
|
||||
CollisionTube::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
|
||||
CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
|
||||
PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
|
||||
if (dist_sq < best_dist_sq) {
|
||||
best_dist_sq = dist_sq;
|
||||
|
|
@ -682,7 +682,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
new_entry->set_interior_point(point - interior_vec * radius);
|
||||
new_entry->set_surface_point(surface_point);
|
||||
|
||||
if (has_effective_normal() && tube->get_respect_effective_normal()) {
|
||||
if (has_effective_normal() && capsule->get_respect_effective_normal()) {
|
||||
new_entry->set_surface_normal(get_effective_normal());
|
||||
} else {
|
||||
new_entry->set_surface_normal(normal);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ protected:
|
|||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const;
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file collisionTube.I
|
||||
* @file collisionCapsule.I
|
||||
* @author drose
|
||||
* @date 2003-09-25
|
||||
*/
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE CollisionTube::
|
||||
CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) :
|
||||
INLINE CollisionCapsule::
|
||||
CollisionCapsule(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) :
|
||||
_a(a), _b(b), _radius(radius)
|
||||
{
|
||||
recalc_internals();
|
||||
|
|
@ -25,8 +25,8 @@ CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) :
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE CollisionTube::
|
||||
CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
|
||||
INLINE CollisionCapsule::
|
||||
CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
|
||||
PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz,
|
||||
PN_stdfloat radius) :
|
||||
_a(ax, ay, az), _b(bx, by, bz), _radius(radius)
|
||||
|
|
@ -36,17 +36,17 @@ CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates an invalid tube. Only used when reading from a bam file.
|
||||
* Creates an invalid capsule. Only used when reading from a bam file.
|
||||
*/
|
||||
INLINE CollisionTube::
|
||||
CollisionTube() {
|
||||
INLINE CollisionCapsule::
|
||||
CollisionCapsule() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE CollisionTube::
|
||||
CollisionTube(const CollisionTube ©) :
|
||||
INLINE CollisionCapsule::
|
||||
CollisionCapsule(const CollisionCapsule ©) :
|
||||
CollisionSolid(copy),
|
||||
_a(copy._a),
|
||||
_b(copy._b),
|
||||
|
|
@ -58,7 +58,7 @@ CollisionTube(const CollisionTube ©) :
|
|||
/**
|
||||
* Flushes the PStatCollectors used during traversal.
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
flush_level() {
|
||||
_volume_pcollector.flush_level();
|
||||
_test_pcollector.flush_level();
|
||||
|
|
@ -67,7 +67,7 @@ flush_level() {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
set_point_a(const LPoint3 &a) {
|
||||
_a = a;
|
||||
recalc_internals();
|
||||
|
|
@ -76,7 +76,7 @@ set_point_a(const LPoint3 &a) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
|
||||
set_point_a(LPoint3(x, y, z));
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE const LPoint3 &CollisionTube::
|
||||
INLINE const LPoint3 &CollisionCapsule::
|
||||
get_point_a() const {
|
||||
return _a;
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ get_point_a() const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
set_point_b(const LPoint3 &b) {
|
||||
_b = b;
|
||||
recalc_internals();
|
||||
|
|
@ -101,7 +101,7 @@ set_point_b(const LPoint3 &b) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
|
||||
set_point_b(LPoint3(x, y, z));
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE const LPoint3 &CollisionTube::
|
||||
INLINE const LPoint3 &CollisionCapsule::
|
||||
get_point_b() const {
|
||||
return _b;
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ get_point_b() const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void CollisionTube::
|
||||
INLINE void CollisionCapsule::
|
||||
set_radius(PN_stdfloat radius) {
|
||||
nassertv(radius >= 0.0f);
|
||||
_radius = radius;
|
||||
|
|
@ -131,7 +131,7 @@ set_radius(PN_stdfloat radius) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
INLINE PN_stdfloat CollisionTube::
|
||||
INLINE PN_stdfloat CollisionCapsule::
|
||||
get_radius() const {
|
||||
return _radius;
|
||||
}
|
||||
|
|
@ -6,12 +6,12 @@
|
|||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file collisionTube.cxx
|
||||
* @file collisionCapsule.cxx
|
||||
* @author drose
|
||||
* @date 2003-09-25
|
||||
*/
|
||||
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionLine.h"
|
||||
#include "collisionRay.h"
|
||||
|
|
@ -35,30 +35,30 @@
|
|||
#include "geomVertexWriter.h"
|
||||
#include "boundingSphere.h"
|
||||
|
||||
PStatCollector CollisionTube::_volume_pcollector("Collision Volumes:CollisionTube");
|
||||
PStatCollector CollisionTube::_test_pcollector("Collision Tests:CollisionTube");
|
||||
TypeHandle CollisionTube::_type_handle;
|
||||
PStatCollector CollisionCapsule::_volume_pcollector("Collision Volumes:CollisionCapsule");
|
||||
PStatCollector CollisionCapsule::_test_pcollector("Collision Tests:CollisionCapsule");
|
||||
TypeHandle CollisionCapsule::_type_handle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CollisionSolid *CollisionTube::
|
||||
CollisionSolid *CollisionCapsule::
|
||||
make_copy() {
|
||||
return new CollisionTube(*this);
|
||||
return new CollisionCapsule(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection(const CollisionEntry &entry) const {
|
||||
return entry.get_into()->test_intersection_from_tube(entry);
|
||||
return entry.get_into()->test_intersection_from_capsule(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the solid by the indicated matrix.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
xform(const LMatrix4 &mat) {
|
||||
_a = _a * mat;
|
||||
_b = _b * mat;
|
||||
|
|
@ -77,7 +77,7 @@ xform(const LMatrix4 &mat) {
|
|||
* collision purposes. The closest intersection point to this origin point is
|
||||
* considered to be the most significant.
|
||||
*/
|
||||
LPoint3 CollisionTube::
|
||||
LPoint3 CollisionCapsule::
|
||||
get_collision_origin() const {
|
||||
return get_point_a();
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ get_collision_origin() const {
|
|||
* Returns a PStatCollector that is used to count the number of bounding
|
||||
* volume tests made against a solid of this type in a given frame.
|
||||
*/
|
||||
PStatCollector &CollisionTube::
|
||||
PStatCollector &CollisionCapsule::
|
||||
get_volume_pcollector() {
|
||||
return _volume_pcollector;
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ get_volume_pcollector() {
|
|||
* Returns a PStatCollector that is used to count the number of intersection
|
||||
* tests made against a solid of this type in a given frame.
|
||||
*/
|
||||
PStatCollector &CollisionTube::
|
||||
PStatCollector &CollisionCapsule::
|
||||
get_test_pcollector() {
|
||||
return _test_pcollector;
|
||||
}
|
||||
|
|
@ -103,15 +103,15 @@ get_test_pcollector() {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
output(std::ostream &out) const {
|
||||
out << "tube, a (" << _a << "), b (" << _b << "), r " << _radius;
|
||||
out << "capsule, a (" << _a << "), b (" << _b << "), r " << _radius;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
PT(BoundingVolume) CollisionTube::
|
||||
PT(BoundingVolume) CollisionCapsule::
|
||||
compute_internal_bounds() const {
|
||||
PT(BoundingVolume) bound = CollisionSolid::compute_internal_bounds();
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ compute_internal_bounds() const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_sphere(const CollisionEntry &entry) const {
|
||||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, entry.get_from(), nullptr);
|
||||
|
|
@ -160,7 +160,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
PN_stdfloat actual_t = 0.0f;
|
||||
|
||||
if (wrt_prev_space != wrt_space) {
|
||||
// If the sphere is moving relative to the tube, it becomes a tube itself.
|
||||
// If the sphere is moving relative to the capsule, it becomes a capsule itself.
|
||||
from_a = sphere->get_center() * wrt_prev_space->get_mat();
|
||||
}
|
||||
|
||||
|
|
@ -195,11 +195,11 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
|
||||
LPoint3 into_intersection_point;
|
||||
if (t2 > 1.0) {
|
||||
// Point b is within the tube. The first intersection point is point b
|
||||
// Point b is within the capsule. The first intersection point is point b
|
||||
// itself.
|
||||
into_intersection_point = from_b;
|
||||
} else {
|
||||
// Point b is outside the tube, and point a is either inside the tube or
|
||||
// Point b is outside the capsule, and point a is either inside the capsule or
|
||||
// beyond it. The first intersection point is at t2.
|
||||
into_intersection_point = from_a + t2 * from_direction;
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_line(const CollisionEntry &entry) const {
|
||||
const CollisionLine *line;
|
||||
DCAST_INTO_R(line, entry.get_from(), nullptr);
|
||||
|
|
@ -269,7 +269,7 @@ test_intersection_from_line(const CollisionEntry &entry) const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_ray(const CollisionEntry &entry) const {
|
||||
const CollisionRay *ray;
|
||||
DCAST_INTO_R(ray, entry.get_from(), nullptr);
|
||||
|
|
@ -299,11 +299,11 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
|
||||
LPoint3 into_intersection_point;
|
||||
if (t1 < 0.0) {
|
||||
// Point a is within the tube. The first intersection point is point a
|
||||
// Point a is within the capsule. The first intersection point is point a
|
||||
// itself.
|
||||
into_intersection_point = from_origin;
|
||||
} else {
|
||||
// Point a is outside the tube. The first intersection point is at t1.
|
||||
// Point a is outside the capsule. The first intersection point is at t1.
|
||||
into_intersection_point = from_origin + t1 * from_direction;
|
||||
}
|
||||
set_intersection_point(new_entry, into_intersection_point, 0.0);
|
||||
|
|
@ -330,7 +330,7 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const {
|
||||
const CollisionSegment *segment;
|
||||
DCAST_INTO_R(segment, entry.get_from(), nullptr);
|
||||
|
|
@ -362,11 +362,11 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
|
||||
LPoint3 into_intersection_point;
|
||||
if (t1 < 0.0) {
|
||||
// Point a is within the tube. The first intersection point is point a
|
||||
// Point a is within the capsule. The first intersection point is point a
|
||||
// itself.
|
||||
into_intersection_point = from_a;
|
||||
} else {
|
||||
// Point a is outside the tube, and point b is either inside the tube or
|
||||
// Point a is outside the capsule, and point b is either inside the capsule or
|
||||
// beyond it. The first intersection point is at t1.
|
||||
into_intersection_point = from_a + t1 * from_direction;
|
||||
}
|
||||
|
|
@ -394,22 +394,22 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const {
|
||||
const CollisionTube *tube;
|
||||
DCAST_INTO_R(tube, entry.get_from(), nullptr);
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const {
|
||||
const CollisionCapsule *capsule;
|
||||
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
|
||||
|
||||
LPoint3 into_a = _a;
|
||||
LVector3 into_direction = _b - into_a;
|
||||
|
||||
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
|
||||
|
||||
LPoint3 from_a = tube->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = tube->get_point_b() * wrt_mat;
|
||||
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
|
||||
LVector3 from_direction = from_b - from_a;
|
||||
|
||||
LVector3 from_radius_v =
|
||||
LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
PN_stdfloat from_radius = length(from_radius_v);
|
||||
|
||||
// Determine the points on each segment with the smallest distance between.
|
||||
|
|
@ -420,7 +420,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
LPoint3 into_closest = into_a + into_direction * into_t;
|
||||
LPoint3 from_closest = from_a + from_direction * from_t;
|
||||
|
||||
// If the distance is greater than the sum of tube radii, the test fails.
|
||||
// If the distance is greater than the sum of capsule radii, the test fails.
|
||||
LVector3 closest_vec = from_closest - into_closest;
|
||||
PN_stdfloat distance = closest_vec.length();
|
||||
if (distance > _radius + from_radius) {
|
||||
|
|
@ -442,7 +442,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
new_entry->set_surface_point(into_closest + surface_normal * _radius);
|
||||
new_entry->set_interior_point(from_closest - surface_normal * from_radius);
|
||||
|
||||
if (has_effective_normal() && tube->get_respect_effective_normal()) {
|
||||
if (has_effective_normal() && capsule->get_respect_effective_normal()) {
|
||||
new_entry->set_surface_normal(get_effective_normal());
|
||||
} else if (distance != 0) {
|
||||
new_entry->set_surface_normal(surface_normal);
|
||||
|
|
@ -458,7 +458,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionTube::
|
||||
PT(CollisionEntry) CollisionCapsule::
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const {
|
||||
const CollisionParabola *parabola;
|
||||
DCAST_INTO_R(parabola, entry.get_from(), nullptr);
|
||||
|
|
@ -510,14 +510,14 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
|
|||
* Fills the _viz_geom GeomNode up with Geoms suitable for rendering this
|
||||
* solid.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
fill_viz_geom() {
|
||||
if (collide_cat.is_debug()) {
|
||||
collide_cat.debug()
|
||||
<< "Recomputing viz for " << *this << "\n";
|
||||
}
|
||||
|
||||
// Generate the vertices such that we draw a tube with one endpoint at (0,
|
||||
// Generate the vertices such that we draw a capsule with one endpoint at (0,
|
||||
// 0, 0), and another at (0, length, 0). Then we'll rotate and translate it
|
||||
// into place with the appropriate look_at matrix.
|
||||
LVector3 direction = (_b - _a);
|
||||
|
|
@ -576,9 +576,9 @@ fill_viz_geom() {
|
|||
|
||||
/**
|
||||
* Should be called internally to recompute the matrix and length when the
|
||||
* properties of the tube have changed.
|
||||
* properties of the capsule have changed.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
recalc_internals() {
|
||||
LVector3 direction = (_b - _a);
|
||||
_length = direction.length();
|
||||
|
|
@ -595,7 +595,7 @@ recalc_internals() {
|
|||
* Calculates a particular vertex on the surface of the first endcap
|
||||
* hemisphere, for use in generating the viz geometry.
|
||||
*/
|
||||
LVertex CollisionTube::
|
||||
LVertex CollisionCapsule::
|
||||
calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices) {
|
||||
PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings;
|
||||
PN_stdfloat s = (PN_stdfloat)si / (PN_stdfloat)num_slices;
|
||||
|
|
@ -620,7 +620,7 @@ calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices) {
|
|||
* Calculates a particular vertex on the surface of the second endcap
|
||||
* hemisphere, for use in generating the viz geometry.
|
||||
*/
|
||||
LVertex CollisionTube::
|
||||
LVertex CollisionCapsule::
|
||||
calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
|
||||
PN_stdfloat length) {
|
||||
PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings;
|
||||
|
|
@ -646,7 +646,7 @@ calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
|
|||
* Given line segments s1 and s2 defined by two points each, computes the
|
||||
* point on each segment with the closest distance between them.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
calc_closest_segment_points(double &t1, double &t2,
|
||||
const LPoint3 &from1, const LVector3 &delta1,
|
||||
const LPoint3 &from2, const LVector3 &delta2) {
|
||||
|
|
@ -717,18 +717,18 @@ calc_closest_segment_points(double &t1, double &t2,
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine the point(s) of intersection of a parametric line with the tube.
|
||||
* Determine the point(s) of intersection of a parametric line with the capsule.
|
||||
* The line is infinite in both directions, and passes through "from" and
|
||||
* from+delta. If the line does not intersect the tube, the function returns
|
||||
* false, and t1 and t2 are undefined. If it does intersect the tube, it
|
||||
* from+delta. If the line does not intersect the capsule, the function returns
|
||||
* false, and t1 and t2 are undefined. If it does intersect the capsule, it
|
||||
* returns true, and t1 and t2 are set to the points along the equation
|
||||
* from+t*delta that correspond to the two points of intersection.
|
||||
*/
|
||||
bool CollisionTube::
|
||||
bool CollisionCapsule::
|
||||
intersects_line(double &t1, double &t2,
|
||||
const LPoint3 &from0, const LVector3 &delta0,
|
||||
PN_stdfloat inflate_radius) const {
|
||||
// Convert the line into our canonical coordinate space: the tube is aligned
|
||||
// Convert the line into our canonical coordinate space: the capsule is aligned
|
||||
// with the y axis.
|
||||
LPoint3 from = from0 * _inv_mat;
|
||||
LVector3 delta = delta0 * _inv_mat;
|
||||
|
|
@ -776,7 +776,7 @@ intersects_line(double &t1, double &t2,
|
|||
}
|
||||
}
|
||||
|
||||
// The point is within the tube!
|
||||
// The point is within the capsule!
|
||||
t1 = t2 = 0.0;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -819,15 +819,15 @@ intersects_line(double &t1, double &t2,
|
|||
PN_stdfloat t2_y = from[1] + t2 * delta[1];
|
||||
|
||||
if (t1_y < -radius && t2_y < -radius) {
|
||||
// Both points are way off the bottom of the tube; no intersection.
|
||||
// Both points are way off the bottom of the capsule; no intersection.
|
||||
return false;
|
||||
} else if (t1_y > _length + radius && t2_y > _length + radius) {
|
||||
// Both points are way off the top of the tube; no intersection.
|
||||
// Both points are way off the top of the capsule; no intersection.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t1_y < 0.0f) {
|
||||
// The starting point is off the bottom of the tube. Test the line
|
||||
// The starting point is off the bottom of the capsule. Test the line
|
||||
// against the first endcap.
|
||||
double t1a, t2a;
|
||||
if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
|
||||
|
|
@ -838,7 +838,7 @@ intersects_line(double &t1, double &t2,
|
|||
t1 = t1a;
|
||||
|
||||
} else if (t1_y > _length) {
|
||||
// The starting point is off the top of the tube. Test the line against
|
||||
// The starting point is off the top of the capsule. Test the line against
|
||||
// the second endcap.
|
||||
double t1b, t2b;
|
||||
if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) {
|
||||
|
|
@ -850,7 +850,7 @@ intersects_line(double &t1, double &t2,
|
|||
}
|
||||
|
||||
if (t2_y < 0.0f) {
|
||||
// The ending point is off the bottom of the tube. Test the line against
|
||||
// The ending point is off the bottom of the capsule. Test the line against
|
||||
// the first endcap.
|
||||
double t1a, t2a;
|
||||
if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
|
||||
|
|
@ -861,7 +861,7 @@ intersects_line(double &t1, double &t2,
|
|||
t2 = t2a;
|
||||
|
||||
} else if (t2_y > _length) {
|
||||
// The ending point is off the top of the tube. Test the line against the
|
||||
// The ending point is off the top of the capsule. Test the line against the
|
||||
// second endcap.
|
||||
double t1b, t2b;
|
||||
if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) {
|
||||
|
|
@ -880,7 +880,7 @@ intersects_line(double &t1, double &t2,
|
|||
* whether it intersects one or the other endcaps. The y parameter specifies
|
||||
* the center of the sphere (and hence the particular endcap).
|
||||
*/
|
||||
bool CollisionTube::
|
||||
bool CollisionCapsule::
|
||||
sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y,
|
||||
const LPoint3 &from, const LVector3 &delta,
|
||||
PN_stdfloat radius) {
|
||||
|
|
@ -917,14 +917,14 @@ sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y,
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine a point of intersection of a parametric parabola with the tube.
|
||||
* Determine a point of intersection of a parametric parabola with the capsule.
|
||||
*
|
||||
* We only consider the segment of the parabola between t1 and t2, which has
|
||||
* already been computed as corresponding to points p1 and p2. If there is an
|
||||
* intersection, t is set to the parametric point of intersection, and true is
|
||||
* returned; otherwise, false is returned.
|
||||
*/
|
||||
bool CollisionTube::
|
||||
bool CollisionCapsule::
|
||||
intersects_parabola(double &t, const LParabola ¶bola,
|
||||
double t1, double t2,
|
||||
const LPoint3 &p1, const LPoint3 &p2) const {
|
||||
|
|
@ -965,11 +965,11 @@ intersects_parabola(double &t, const LParabola ¶bola,
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculates a point that is exactly on the surface of the tube and its
|
||||
* Calculates a point that is exactly on the surface of the capsule and its
|
||||
* corresponding normal, given a point that is supposedly on the surface of
|
||||
* the tube.
|
||||
* the capsule.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
calculate_surface_point_and_normal(const LPoint3 &surface_point,
|
||||
double extra_radius,
|
||||
LPoint3 &result_point,
|
||||
|
|
@ -1015,7 +1015,7 @@ calculate_surface_point_and_normal(const LPoint3 &surface_point,
|
|||
* point in the CollisionEntry, and also compute the relevant normal based on
|
||||
* that point.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
set_intersection_point(CollisionEntry *new_entry,
|
||||
const LPoint3 &into_intersection_point,
|
||||
double extra_radius) const {
|
||||
|
|
@ -1033,16 +1033,16 @@ set_intersection_point(CollisionEntry *new_entry,
|
|||
|
||||
new_entry->set_surface_normal(normal);
|
||||
new_entry->set_surface_point(point);
|
||||
// Also adjust the original point into the tube by the amount of
|
||||
// extra_radius, which should put it on the surface of the tube if our
|
||||
// Also adjust the original point into the capsule by the amount of
|
||||
// extra_radius, which should put it on the surface of the capsule if our
|
||||
// collision was tangential.
|
||||
new_entry->set_interior_point(into_intersection_point - normal * extra_radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BamReader how to create objects of type CollisionTube.
|
||||
* Tells the BamReader how to create objects of type CollisionCapsule.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
|
@ -1051,7 +1051,7 @@ register_with_read_factory() {
|
|||
* Writes the contents of this object to the datagram for shipping out to a
|
||||
* Bam file.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
CollisionSolid::write_datagram(manager, dg);
|
||||
_a.write_datagram(dg);
|
||||
|
|
@ -1061,12 +1061,12 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||
|
||||
/**
|
||||
* This function is called by the BamReader's factory when a new object of
|
||||
* type CollisionTube is encountered in the Bam file. It should create the
|
||||
* CollisionTube and extract its information from the file.
|
||||
* type CollisionCapsule is encountered in the Bam file. It should create the
|
||||
* CollisionCapsule and extract its information from the file.
|
||||
*/
|
||||
TypedWritable *CollisionTube::
|
||||
TypedWritable *CollisionCapsule::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
CollisionTube *node = new CollisionTube();
|
||||
CollisionCapsule *node = new CollisionCapsule();
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
|
|
@ -1078,9 +1078,9 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
|
||||
/**
|
||||
* This internal function is called by make_from_bam to read in all of the
|
||||
* relevant data from the BamFile for the new CollisionTube.
|
||||
* relevant data from the BamFile for the new CollisionCapsule.
|
||||
*/
|
||||
void CollisionTube::
|
||||
void CollisionCapsule::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
CollisionSolid::fillin(scan, manager);
|
||||
_a.read_datagram(scan);
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* 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 collisionCapsule.h
|
||||
* @author drose
|
||||
* @date 2003-09-25
|
||||
*/
|
||||
|
||||
#ifndef COLLISIONCAPSULE_H
|
||||
#define COLLISIONCAPSULE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "collisionSolid.h"
|
||||
#include "parabola.h"
|
||||
|
||||
/**
|
||||
* This implements a solid consisting of a cylinder with hemispherical endcaps,
|
||||
* also known as a capsule or a spherocylinder.
|
||||
*
|
||||
* This shape was previously erroneously called CollisionTube.
|
||||
*/
|
||||
class EXPCL_PANDA_COLLIDE CollisionCapsule : public CollisionSolid {
|
||||
PUBLISHED:
|
||||
INLINE explicit CollisionCapsule(const LPoint3 &a, const LPoint3 &db,
|
||||
PN_stdfloat radius);
|
||||
INLINE explicit CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
|
||||
PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz,
|
||||
PN_stdfloat radius);
|
||||
|
||||
virtual LPoint3 get_collision_origin() const;
|
||||
|
||||
private:
|
||||
INLINE CollisionCapsule();
|
||||
|
||||
public:
|
||||
INLINE CollisionCapsule(const CollisionCapsule ©);
|
||||
virtual CollisionSolid *make_copy();
|
||||
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void xform(const LMatrix4 &mat);
|
||||
|
||||
virtual PStatCollector &get_volume_pcollector();
|
||||
virtual PStatCollector &get_test_pcollector();
|
||||
|
||||
virtual void output(std::ostream &out) const;
|
||||
|
||||
INLINE static void flush_level();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE void set_point_a(const LPoint3 &a);
|
||||
INLINE void set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE const LPoint3 &get_point_a() const;
|
||||
|
||||
INLINE void set_point_b(const LPoint3 &b);
|
||||
INLINE void set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE const LPoint3 &get_point_b() const;
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_sphere(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_line(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_ray(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void fill_viz_geom();
|
||||
|
||||
private:
|
||||
void recalc_internals();
|
||||
|
||||
LVertex calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices);
|
||||
LVertex calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
|
||||
PN_stdfloat length);
|
||||
|
||||
static void calc_closest_segment_points(double &t1, double &t2,
|
||||
const LPoint3 &from1, const LVector3 &delta1,
|
||||
const LPoint3 &from2, const LVector3 &delta2);
|
||||
bool intersects_line(double &t1, double &t2,
|
||||
const LPoint3 &from, const LVector3 &delta,
|
||||
PN_stdfloat inflate_radius) const;
|
||||
static bool sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y,
|
||||
const LPoint3 &from, const LVector3 &delta,
|
||||
PN_stdfloat radius);
|
||||
bool intersects_parabola(double &t, const LParabola ¶bola,
|
||||
double t1, double t2,
|
||||
const LPoint3 &p1, const LPoint3 &p2) const;
|
||||
void calculate_surface_point_and_normal(const LPoint3 &surface_point,
|
||||
double extra_radius,
|
||||
LPoint3 &result_point,
|
||||
LVector3 &result_normal) const;
|
||||
void set_intersection_point(CollisionEntry *new_entry,
|
||||
const LPoint3 &into_intersection_point,
|
||||
double extra_radius) const;
|
||||
|
||||
private:
|
||||
LPoint3 _a, _b;
|
||||
PN_stdfloat _radius;
|
||||
|
||||
// These are derived from the above.
|
||||
LMatrix4 _mat;
|
||||
LMatrix4 _inv_mat;
|
||||
PN_stdfloat _length;
|
||||
|
||||
static PStatCollector _volume_pcollector;
|
||||
static PStatCollector _test_pcollector;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CollisionSolid::init_type();
|
||||
register_type(_type_handle, "CollisionCapsule",
|
||||
CollisionSolid::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CollisionBox;
|
||||
};
|
||||
|
||||
#include "collisionCapsule.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -72,7 +72,7 @@ handle_entries() {
|
|||
PosB = collider's current position
|
||||
M = movement vector (PosB - PosA)
|
||||
BV = bounding sphere that includes collider at PosA and PosB
|
||||
CS = 'collision set', all 'collidables' within BV (collision polys, tubes, etc)
|
||||
CS = 'collision set', all 'collidables' within BV (collision polys, capsules, etc)
|
||||
|
||||
VARIABLES
|
||||
N = movement vector since most recent collision (or start of frame)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "collisionLine.h"
|
||||
#include "collisionRay.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionParabola.h"
|
||||
#include "config_collide.h"
|
||||
#include "pointerToArray.h"
|
||||
|
|
@ -298,16 +298,16 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionPlane::
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const {
|
||||
const CollisionTube *tube;
|
||||
DCAST_INTO_R(tube, entry.get_from(), nullptr);
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const {
|
||||
const CollisionCapsule *capsule;
|
||||
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
|
||||
|
||||
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
|
||||
|
||||
LPoint3 from_a = tube->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = tube->get_point_b() * wrt_mat;
|
||||
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
|
||||
LVector3 from_radius_v =
|
||||
LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
PN_stdfloat from_radius = length(from_radius_v);
|
||||
|
||||
PN_stdfloat dist_a = _plane.dist_to_plane(from_a);
|
||||
|
|
@ -325,7 +325,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
}
|
||||
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
|
||||
|
||||
LVector3 normal = (has_effective_normal() && tube->get_respect_effective_normal()) ? get_effective_normal() : get_normal();
|
||||
LVector3 normal = (has_effective_normal() && capsule->get_respect_effective_normal()) ? get_effective_normal() : get_normal();
|
||||
new_entry->set_surface_normal(normal);
|
||||
|
||||
PN_stdfloat t;
|
||||
|
|
@ -339,17 +339,17 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
new_entry->set_surface_point(from_a - get_normal() * dist_a);
|
||||
|
||||
} else {
|
||||
// Within the tube! Yay, that means we have a surface point.
|
||||
// Within the capsule! Yay, that means we have a surface point.
|
||||
new_entry->set_surface_point(from_a + t * from_direction);
|
||||
}
|
||||
} else {
|
||||
// If it's completely parallel, pretend it's colliding in the center of
|
||||
// the tube.
|
||||
// the capsule.
|
||||
new_entry->set_surface_point(from_a + 0.5f * from_direction - get_normal() * dist_a);
|
||||
}
|
||||
|
||||
if (IS_NEARLY_EQUAL(dist_a, dist_b)) {
|
||||
// Let's be fair and choose the center of the tube.
|
||||
// Let's be fair and choose the center of the capsule.
|
||||
new_entry->set_interior_point(from_a + 0.5f * from_direction - get_normal() * from_radius);
|
||||
|
||||
} else if (dist_a < dist_b) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ protected:
|
|||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const;
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "collisionLine.h"
|
||||
#include "collisionRay.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionParabola.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionEntry.h"
|
||||
|
|
@ -240,11 +240,11 @@ test_intersection_from_segment(const CollisionEntry &) const {
|
|||
|
||||
/**
|
||||
* This is part of the double-dispatch implementation of test_intersection().
|
||||
* It is called when the "from" object is a tube.
|
||||
* It is called when the "from" object is a capsule.
|
||||
*/
|
||||
PT(CollisionEntry) CollisionSolid::
|
||||
test_intersection_from_tube(const CollisionEntry &) const {
|
||||
report_undefined_intersection_test(CollisionTube::get_class_type(),
|
||||
test_intersection_from_capsule(const CollisionEntry &) const {
|
||||
report_undefined_intersection_test(CollisionCapsule::get_class_type(),
|
||||
get_type());
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ protected:
|
|||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const;
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
|
|
@ -177,7 +177,7 @@ private:
|
|||
friend class CollisionLine;
|
||||
friend class CollisionRay;
|
||||
friend class CollisionSegment;
|
||||
friend class CollisionTube;
|
||||
friend class CollisionCapsule;
|
||||
friend class CollisionParabola;
|
||||
friend class CollisionHandlerFluidPusher;
|
||||
friend class CollisionBox;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "collisionHandler.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionParabola.h"
|
||||
#include "collisionBox.h"
|
||||
#include "config_collide.h"
|
||||
|
|
@ -444,18 +444,18 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
*
|
||||
*/
|
||||
PT(CollisionEntry) CollisionSphere::
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const {
|
||||
const CollisionTube *tube;
|
||||
DCAST_INTO_R(tube, entry.get_from(), nullptr);
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const {
|
||||
const CollisionCapsule *capsule;
|
||||
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
|
||||
|
||||
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
|
||||
|
||||
LPoint3 from_a = tube->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = tube->get_point_b() * wrt_mat;
|
||||
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
|
||||
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
|
||||
LVector3 from_direction = from_b - from_a;
|
||||
|
||||
LVector3 from_radius_v =
|
||||
LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||
PN_stdfloat from_radius = length(from_radius_v);
|
||||
|
||||
double t1, t2;
|
||||
|
|
@ -465,8 +465,8 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
}
|
||||
|
||||
if (t2 < 0.0 || t1 > 1.0) {
|
||||
// Both intersection points are before the start of the tube or after
|
||||
// the end of the tube.
|
||||
// Both intersection points are before the start of the capsule or after
|
||||
// the end of the capsule.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -487,7 +487,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
|
|||
new_entry->set_surface_point(get_center() + normal * get_radius());
|
||||
new_entry->set_interior_point(inner_point - normal * from_radius);
|
||||
|
||||
if (has_effective_normal() && tube->get_respect_effective_normal()) {
|
||||
if (has_effective_normal() && capsule->get_respect_effective_normal()) {
|
||||
new_entry->set_surface_normal(get_effective_normal());
|
||||
} else {
|
||||
new_entry->set_surface_normal(normal);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ protected:
|
|||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const;
|
||||
test_intersection_from_capsule(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "collisionVisualizer.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionPolygon.h"
|
||||
#include "collisionPlane.h"
|
||||
#include "config_collide.h"
|
||||
|
|
@ -345,7 +345,7 @@ traverse(const NodePath &root) {
|
|||
_geom_volume_pcollector.flush_level();
|
||||
|
||||
CollisionSphere::flush_level();
|
||||
CollisionTube::flush_level();
|
||||
CollisionCapsule::flush_level();
|
||||
CollisionPolygon::flush_level();
|
||||
CollisionPlane::flush_level();
|
||||
CollisionBox::flush_level();
|
||||
|
|
|
|||
|
|
@ -7,154 +7,21 @@
|
|||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file collisionTube.h
|
||||
* @author drose
|
||||
* @date 2003-09-25
|
||||
* @author rdb
|
||||
* @date 2018-12-23
|
||||
*/
|
||||
|
||||
#ifndef COLLISIONTUBE_H
|
||||
#define COLLISIONTUBE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "collisionSolid.h"
|
||||
#include "parabola.h"
|
||||
#include "collisionCapsule.h"
|
||||
|
||||
BEGIN_PUBLISH
|
||||
/**
|
||||
* This implements a solid roughly in cylindrical shape. It's not called a
|
||||
* CollisionCylinder because it's not a true cylinder; specifically, it has
|
||||
* rounded ends instead of flat ends. It looks more like a Contac pill.
|
||||
* Alias for backward compatibility.
|
||||
* @deprecated use CollisionCapsule instead.
|
||||
*/
|
||||
class EXPCL_PANDA_COLLIDE CollisionTube : public CollisionSolid {
|
||||
PUBLISHED:
|
||||
INLINE explicit CollisionTube(const LPoint3 &a, const LPoint3 &db,
|
||||
PN_stdfloat radius);
|
||||
INLINE explicit CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
|
||||
PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz,
|
||||
PN_stdfloat radius);
|
||||
|
||||
virtual LPoint3 get_collision_origin() const;
|
||||
|
||||
private:
|
||||
INLINE CollisionTube();
|
||||
|
||||
public:
|
||||
INLINE CollisionTube(const CollisionTube ©);
|
||||
virtual CollisionSolid *make_copy();
|
||||
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void xform(const LMatrix4 &mat);
|
||||
|
||||
virtual PStatCollector &get_volume_pcollector();
|
||||
virtual PStatCollector &get_test_pcollector();
|
||||
|
||||
virtual void output(std::ostream &out) const;
|
||||
|
||||
INLINE static void flush_level();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE void set_point_a(const LPoint3 &a);
|
||||
INLINE void set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE const LPoint3 &get_point_a() const;
|
||||
|
||||
INLINE void set_point_b(const LPoint3 &b);
|
||||
INLINE void set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE const LPoint3 &get_point_b() const;
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_sphere(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_line(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_ray(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_tube(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void fill_viz_geom();
|
||||
|
||||
private:
|
||||
void recalc_internals();
|
||||
|
||||
LVertex calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices);
|
||||
LVertex calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
|
||||
PN_stdfloat length);
|
||||
|
||||
static void calc_closest_segment_points(double &t1, double &t2,
|
||||
const LPoint3 &from1, const LVector3 &delta1,
|
||||
const LPoint3 &from2, const LVector3 &delta2);
|
||||
bool intersects_line(double &t1, double &t2,
|
||||
const LPoint3 &from, const LVector3 &delta,
|
||||
PN_stdfloat inflate_radius) const;
|
||||
static bool sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y,
|
||||
const LPoint3 &from, const LVector3 &delta,
|
||||
PN_stdfloat radius);
|
||||
bool intersects_parabola(double &t, const LParabola ¶bola,
|
||||
double t1, double t2,
|
||||
const LPoint3 &p1, const LPoint3 &p2) const;
|
||||
void calculate_surface_point_and_normal(const LPoint3 &surface_point,
|
||||
double extra_radius,
|
||||
LPoint3 &result_point,
|
||||
LVector3 &result_normal) const;
|
||||
void set_intersection_point(CollisionEntry *new_entry,
|
||||
const LPoint3 &into_intersection_point,
|
||||
double extra_radius) const;
|
||||
|
||||
private:
|
||||
LPoint3 _a, _b;
|
||||
PN_stdfloat _radius;
|
||||
|
||||
// These are derived from the above.
|
||||
LMatrix4 _mat;
|
||||
LMatrix4 _inv_mat;
|
||||
PN_stdfloat _length;
|
||||
|
||||
static PStatCollector _volume_pcollector;
|
||||
static PStatCollector _test_pcollector;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CollisionSolid::init_type();
|
||||
register_type(_type_handle, "CollisionTube",
|
||||
CollisionSolid::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CollisionBox;
|
||||
};
|
||||
|
||||
#include "collisionTube.I"
|
||||
typedef CollisionCapsule CollisionTube;
|
||||
END_PUBLISH
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "config_collide.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "collisionHandler.h"
|
||||
#include "collisionHandlerEvent.h"
|
||||
|
|
@ -38,7 +39,6 @@
|
|||
#include "collisionSolid.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionTraverser.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionVisualizer.h"
|
||||
#include "dconfig.h"
|
||||
|
||||
|
|
@ -126,6 +126,7 @@ init_libcollide() {
|
|||
initialized = true;
|
||||
|
||||
CollisionBox::init_type();
|
||||
CollisionCapsule::init_type();
|
||||
CollisionEntry::init_type();
|
||||
CollisionHandler::init_type();
|
||||
CollisionHandlerEvent::init_type();
|
||||
|
|
@ -150,14 +151,18 @@ init_libcollide() {
|
|||
CollisionSolid::init_type();
|
||||
CollisionSphere::init_type();
|
||||
CollisionTraverser::init_type();
|
||||
CollisionTube::init_type();
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
CollisionRecorder::init_type();
|
||||
CollisionVisualizer::init_type();
|
||||
#endif
|
||||
|
||||
// Record the old name for CollisionCapsule for backwards compatibility.
|
||||
BamWriter::record_obsolete_type_name(CollisionCapsule::get_class_type(),
|
||||
"CollisionTube", 6, 44);
|
||||
|
||||
CollisionBox::register_with_read_factory();
|
||||
CollisionCapsule::register_with_read_factory();
|
||||
CollisionInvSphere::register_with_read_factory();
|
||||
CollisionLine::register_with_read_factory();
|
||||
CollisionNode::register_with_read_factory();
|
||||
|
|
@ -168,5 +173,4 @@ init_libcollide() {
|
|||
CollisionRay::register_with_read_factory();
|
||||
CollisionSegment::register_with_read_factory();
|
||||
CollisionSphere::register_with_read_factory();
|
||||
CollisionTube::register_with_read_factory();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "config_collide.cxx"
|
||||
#include "collisionBox.cxx"
|
||||
#include "collisionCapsule.cxx"
|
||||
#include "collisionEntry.cxx"
|
||||
#include "collisionGeom.cxx"
|
||||
#include "collisionHandler.cxx"
|
||||
|
|
@ -12,5 +13,3 @@
|
|||
#include "collisionHandlerFluidPusher.cxx"
|
||||
#include "collisionHandlerQueue.cxx"
|
||||
#include "collisionInvSphere.cxx"
|
||||
#include "collisionLevelStateBase.cxx"
|
||||
#include "collisionLevelState.cxx"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include "collisionLevelStateBase.cxx"
|
||||
#include "collisionLevelState.cxx"
|
||||
#include "collisionLine.cxx"
|
||||
#include "collisionNode.cxx"
|
||||
#include "collisionParabola.cxx"
|
||||
|
|
@ -10,5 +12,4 @@
|
|||
#include "collisionSolid.cxx"
|
||||
#include "collisionSphere.cxx"
|
||||
#include "collisionTraverser.cxx"
|
||||
#include "collisionTube.cxx"
|
||||
#include "collisionVisualizer.cxx"
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ PStatCollector GraphicsEngine::_volume_sphere_pcollector("Collision Volumes:Coll
|
|||
PStatCollector GraphicsEngine::_test_sphere_pcollector("Collision Tests:CollisionSphere");
|
||||
PStatCollector GraphicsEngine::_volume_box_pcollector("Collision Volumes:CollisionBox");
|
||||
PStatCollector GraphicsEngine::_test_box_pcollector("Collision Tests:CollisionBox");
|
||||
PStatCollector GraphicsEngine::_volume_tube_pcollector("Collision Volumes:CollisionTube");
|
||||
PStatCollector GraphicsEngine::_test_tube_pcollector("Collision Tests:CollisionTube");
|
||||
PStatCollector GraphicsEngine::_volume_capsule_pcollector("Collision Volumes:CollisionCapsule");
|
||||
PStatCollector GraphicsEngine::_test_capsule_pcollector("Collision Tests:CollisionCapsule");
|
||||
PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:CollisionInvSphere");
|
||||
PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere");
|
||||
PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom");
|
||||
|
|
@ -875,8 +875,8 @@ render_frame() {
|
|||
_test_sphere_pcollector.clear_level();
|
||||
_volume_box_pcollector.clear_level();
|
||||
_test_box_pcollector.clear_level();
|
||||
_volume_tube_pcollector.clear_level();
|
||||
_test_tube_pcollector.clear_level();
|
||||
_volume_capsule_pcollector.clear_level();
|
||||
_test_capsule_pcollector.clear_level();
|
||||
_volume_inv_sphere_pcollector.clear_level();
|
||||
_test_inv_sphere_pcollector.clear_level();
|
||||
_volume_geom_pcollector.clear_level();
|
||||
|
|
|
|||
|
|
@ -401,8 +401,8 @@ private:
|
|||
static PStatCollector _test_sphere_pcollector;
|
||||
static PStatCollector _volume_box_pcollector;
|
||||
static PStatCollector _test_box_pcollector;
|
||||
static PStatCollector _volume_tube_pcollector;
|
||||
static PStatCollector _test_tube_pcollector;
|
||||
static PStatCollector _volume_capsule_pcollector;
|
||||
static PStatCollector _test_capsule_pcollector;
|
||||
static PStatCollector _volume_inv_sphere_pcollector;
|
||||
static PStatCollector _test_inv_sphere_pcollector;
|
||||
static PStatCollector _volume_geom_pcollector;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ camera-collide: for things that the camera should avoid
|
|||
trigger: for things (usually not barriers or floors) that should trigger an
|
||||
event when avatars intersect with them
|
||||
sphere: for things that should have a collision sphere around them
|
||||
tube: for things that should have a collision tube (cylinder) around them
|
||||
tube: for things that should have a collision capsule around them
|
||||
|
||||
NOTES
|
||||
|
||||
|
|
|
|||
|
|
@ -30,14 +30,12 @@ ConfigureFn(config_dxml) {
|
|||
init_libdxml();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libdxml
|
||||
// Description: Initializes the library. This must be called at
|
||||
// least once before any of the functions or classes in
|
||||
// this library can be used. Normally it will be
|
||||
// called by the static initializers and need not be
|
||||
// called explicitly, but special cases exist.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes the library. This must be called at least once before any of
|
||||
* the functions or classes in this library can be used. Normally it will be
|
||||
* called by the static initializers and need not be called explicitly, but
|
||||
* special cases exist.
|
||||
*/
|
||||
void
|
||||
init_libdxml() {
|
||||
static bool initialized = false;
|
||||
|
|
@ -48,11 +46,10 @@ init_libdxml() {
|
|||
}
|
||||
|
||||
BEGIN_PUBLISH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: read_xml_stream
|
||||
// Description: Reads an XML document from the indicated stream.
|
||||
// Returns the document, or NULL on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Reads an XML document from the indicated stream.
|
||||
* @returns the document, or NULL on error.
|
||||
*/
|
||||
TiXmlDocument *
|
||||
read_xml_stream(std::istream &in) {
|
||||
TiXmlDocument *doc = new TiXmlDocument;
|
||||
|
|
@ -67,10 +64,9 @@ read_xml_stream(std::istream &in) {
|
|||
END_PUBLISH
|
||||
|
||||
BEGIN_PUBLISH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: write_xml_stream
|
||||
// Description: Writes an XML document to the indicated stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Writes an XML document to the indicated stream.
|
||||
*/
|
||||
void
|
||||
write_xml_stream(std::ostream &out, TiXmlDocument *doc) {
|
||||
out << *doc;
|
||||
|
|
@ -78,10 +74,9 @@ write_xml_stream(std::ostream &out, TiXmlDocument *doc) {
|
|||
END_PUBLISH
|
||||
|
||||
BEGIN_PUBLISH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: print_xml
|
||||
// Description: Writes an XML object to stdout, with formatting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Writes an XML object to stdout, with formatting.
|
||||
*/
|
||||
void
|
||||
print_xml(TiXmlNode *xnode) {
|
||||
xnode->Print(stdout, 0);
|
||||
|
|
@ -89,12 +84,10 @@ print_xml(TiXmlNode *xnode) {
|
|||
END_PUBLISH
|
||||
|
||||
BEGIN_PUBLISH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: print_xml_to_file
|
||||
// Description: Writes an XML object to the indicated file, with
|
||||
// formatting. Unfortunately the VFS cannot be
|
||||
// supported; the file must be a real filename on disk.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Writes an XML object to the indicated file, with formatting. Unfortunately
|
||||
* the VFS cannot be supported; the file must be a real filename on disk.
|
||||
*/
|
||||
void
|
||||
print_xml_to_file(const Filename &filename, TiXmlNode *xnode) {
|
||||
std::string os_name = filename.to_os_specific();
|
||||
|
|
|
|||
|
|
@ -897,7 +897,8 @@ string_cs_type(const string &strval) {
|
|||
} else if (cmp_nocase_uh(strval, "inv-sphere") == 0 ||
|
||||
cmp_nocase_uh(strval, "invsphere") == 0) {
|
||||
return CST_inv_sphere;
|
||||
} else if (cmp_nocase_uh(strval, "tube") == 0) {
|
||||
} else if (cmp_nocase_uh(strval, "tube") == 0 ||
|
||||
cmp_nocase_uh(strval, "capsule") == 0) {
|
||||
return CST_tube;
|
||||
} else if (cmp_nocase_uh(strval, "floor-mesh") == 0 ||
|
||||
cmp_nocase_uh(strval, "floormesh") == 0) {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
#include "collisionNode.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionInvSphere.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "collisionPlane.h"
|
||||
#include "collisionPolygon.h"
|
||||
#include "collisionFloorMesh.h"
|
||||
|
|
@ -2865,7 +2865,7 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group,
|
|||
break;
|
||||
|
||||
case EggGroup::CST_tube:
|
||||
make_collision_tube(egg_group, cnode, start_group->get_collide_flags());
|
||||
make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
|
||||
break;
|
||||
|
||||
case EggGroup::CST_floor_mesh:
|
||||
|
|
@ -3045,12 +3045,12 @@ make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode,
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a single CollisionTube corresponding to the polygons associated
|
||||
* Creates a single CollisionCapsule corresponding to the polygons associated
|
||||
* with this group.
|
||||
*/
|
||||
void EggLoader::
|
||||
make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags) {
|
||||
make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags) {
|
||||
EggGroup *geom_group = find_collision_geometry(egg_group, flags);
|
||||
if (geom_group != nullptr) {
|
||||
// Collect all of the vertices.
|
||||
|
|
@ -3175,7 +3175,7 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
|||
|
||||
// Transform all of the points so that the major axis is along the Y
|
||||
// axis, and the origin is the center. This is very similar to the
|
||||
// CollisionTube's idea of its canonical orientation (although not
|
||||
// CollisionCapsule's idea of its canonical orientation (although not
|
||||
// exactly the same, since it is centered on the origin instead of
|
||||
// having point_a on the origin). It makes it easier to determine the
|
||||
// length and radius of the cylinder.
|
||||
|
|
@ -3230,11 +3230,11 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
|||
LPoint3d point_a = center - half;
|
||||
LPoint3d point_b = center + half;
|
||||
|
||||
CollisionTube *cstube =
|
||||
new CollisionTube(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
|
||||
CollisionCapsule *cscapsule =
|
||||
new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
|
||||
radius);
|
||||
apply_collision_flags(cstube, flags);
|
||||
cnode->add_solid(cstube);
|
||||
apply_collision_flags(cscapsule, flags);
|
||||
cnode->add_solid(cscapsule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@ private:
|
|||
EggGroup::CollideFlags flags);
|
||||
void make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags);
|
||||
void make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags);
|
||||
void make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags);
|
||||
void make_collision_floor_mesh(EggGroup *egg_group, CollisionNode *cnode,
|
||||
EggGroup::CollideFlags flags);
|
||||
void apply_collision_flags(CollisionSolid *solid,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "collisionSphere.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionInvSphere.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionCapsule.h"
|
||||
#include "textureStage.h"
|
||||
#include "geomNode.h"
|
||||
#include "geom.h"
|
||||
|
|
@ -620,13 +620,13 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
|
|||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev0));
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
|
||||
|
||||
} else if (child->is_of_type(CollisionTube::get_class_type())) {
|
||||
CPT(CollisionTube) tube = DCAST(CollisionTube, child);
|
||||
LPoint3 point_a = tube->get_point_a();
|
||||
LPoint3 point_b = tube->get_point_b();
|
||||
} else if (child->is_of_type(CollisionCapsule::get_class_type())) {
|
||||
CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, child);
|
||||
LPoint3 point_a = capsule->get_point_a();
|
||||
LPoint3 point_b = capsule->get_point_b();
|
||||
LPoint3 centroid = (point_a + point_b) * 0.5f;
|
||||
|
||||
// Also get an arbitrary vector perpendicular to the tube.
|
||||
// Also get an arbitrary vector perpendicular to the capsule.
|
||||
LVector3 axis = point_b - point_a;
|
||||
LVector3 sideways;
|
||||
if (std::fabs(axis[2]) > std::fabs(axis[1])) {
|
||||
|
|
@ -635,18 +635,18 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
|
|||
sideways = axis.cross(LVector3(0, 0, 1));
|
||||
}
|
||||
sideways.normalize();
|
||||
sideways *= tube->get_radius();
|
||||
LVector3 extend = axis.normalized() * tube->get_radius();
|
||||
sideways *= capsule->get_radius();
|
||||
LVector3 extend = axis.normalized() * capsule->get_radius();
|
||||
|
||||
EggGroup *egg_tube;
|
||||
EggGroup *egg_capsule;
|
||||
if (num_solids == 1) {
|
||||
egg_tube = egg_group;
|
||||
egg_capsule = egg_group;
|
||||
} else {
|
||||
egg_tube = new EggGroup;
|
||||
egg_group->add_child(egg_tube);
|
||||
egg_capsule = new EggGroup;
|
||||
egg_group->add_child(egg_capsule);
|
||||
}
|
||||
egg_tube->set_cs_type(EggGroup::CST_tube);
|
||||
egg_tube->set_collide_flags(flags);
|
||||
egg_capsule->set_cs_type(EggGroup::CST_tube);
|
||||
egg_capsule->set_collide_flags(flags);
|
||||
|
||||
// Add two points for the endcaps, and then two points around the
|
||||
// centroid to indicate the radius.
|
||||
|
|
@ -657,7 +657,7 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
|
|||
ev3.set_pos(LCAST(double, (centroid - sideways) * net_mat));
|
||||
|
||||
EggPolygon *egg_poly = new EggPolygon;
|
||||
egg_tube->add_child(egg_poly);
|
||||
egg_capsule->add_child(egg_poly);
|
||||
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev0));
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
|
||||
|
|
|
|||
|
|
@ -79,8 +79,6 @@ init_from(FfmpegVideo *source) {
|
|||
return;
|
||||
}
|
||||
|
||||
ReMutexHolder av_holder(_av_lock);
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101)
|
||||
_frame = av_frame_alloc();
|
||||
_frame_out = av_frame_alloc();
|
||||
|
|
@ -109,6 +107,8 @@ init_from(FfmpegVideo *source) {
|
|||
_eof_known = false;
|
||||
_eof_frame = 0;
|
||||
|
||||
ReMutexHolder av_holder(_av_lock);
|
||||
|
||||
// Check if we got an alpha format. Please note that some video codecs
|
||||
// (eg. libvpx) change the pix_fmt after decoding the first frame, which is
|
||||
// why we didn't do this earlier.
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@
|
|||
*/
|
||||
INLINE CLP(BufferContext)::
|
||||
CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
PreparedGraphicsObjects *pgo) :
|
||||
BufferContext(&pgo->_sbuffer_residency),
|
||||
PreparedGraphicsObjects *pgo,
|
||||
TypedWritableReferenceCount *object) :
|
||||
BufferContext(&pgo->_sbuffer_residency, object),
|
||||
AdaptiveLruPage(0),
|
||||
_glgsg(glgsg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
class EXPCL_GL CLP(BufferContext) : public BufferContext, public AdaptiveLruPage {
|
||||
public:
|
||||
INLINE CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
PreparedGraphicsObjects *pgo);
|
||||
PreparedGraphicsObjects *pgo,
|
||||
TypedWritableReferenceCount *object);
|
||||
ALLOC_DELETED_CHAIN(CLP(BufferContext));
|
||||
|
||||
virtual void evict_lru();
|
||||
|
|
|
|||
|
|
@ -1413,7 +1413,7 @@ open_buffer() {
|
|||
}
|
||||
|
||||
if (_rb_context == nullptr) {
|
||||
_rb_context = new BufferContext(&(glgsg->_renderbuffer_residency));
|
||||
_rb_context = new BufferContext(&(glgsg->_renderbuffer_residency), nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -6519,7 +6519,7 @@ prepare_shader_buffer(ShaderBuffer *data) {
|
|||
if (_supports_shader_buffers) {
|
||||
PStatGPUTimer timer(this, _prepare_shader_buffer_pcollector);
|
||||
|
||||
CLP(BufferContext) *gbc = new CLP(BufferContext)(this, _prepared_objects);
|
||||
CLP(BufferContext) *gbc = new CLP(BufferContext)(this, _prepared_objects, data);
|
||||
_glGenBuffers(1, &gbc->_index);
|
||||
|
||||
if (GLCAT.is_debug() && gl_debug_buffers) {
|
||||
|
|
@ -7049,6 +7049,16 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z,
|
|||
} else {
|
||||
format = Texture::F_srgb;
|
||||
}
|
||||
} else if (_current_properties->get_float_color()) {
|
||||
if (_current_properties->get_alpha_bits()) {
|
||||
format = Texture::F_rgba32;
|
||||
} else if (_current_properties->get_blue_bits()) {
|
||||
format = Texture::F_rgb32;
|
||||
} else if (_current_properties->get_green_bits()) {
|
||||
format = Texture::F_rg32;
|
||||
} else {
|
||||
format = Texture::F_r32;
|
||||
}
|
||||
} else {
|
||||
if (_current_properties->get_alpha_bits()) {
|
||||
format = Texture::F_rgba;
|
||||
|
|
@ -7058,7 +7068,11 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z,
|
|||
}
|
||||
if (_current_properties->get_float_color()) {
|
||||
component_type = Texture::T_float;
|
||||
} else if (_current_properties->get_color_bits() <= 24) {
|
||||
} else if (_current_properties->get_color_bits() <= 24
|
||||
&& _current_properties->get_red_bits() <= 8
|
||||
&& _current_properties->get_green_bits() <= 8
|
||||
&& _current_properties->get_blue_bits() <= 8
|
||||
&& _current_properties->get_alpha_bits() <= 8) {
|
||||
component_type = Texture::T_unsigned_byte;
|
||||
} else {
|
||||
component_type = Texture::T_unsigned_short;
|
||||
|
|
|
|||
|
|
@ -2797,14 +2797,24 @@ update_shader_texture_bindings(ShaderContext *prev) {
|
|||
}
|
||||
|
||||
if (tex->get_texture_type() != spec._desired_type) {
|
||||
if (id != nullptr) {
|
||||
switch (spec._part) {
|
||||
case Shader::STO_named_input:
|
||||
GLCAT.error()
|
||||
<< "Sampler type of GLSL shader input '" << *id << "' does not "
|
||||
"match type of texture " << *tex << ".\n";
|
||||
} else {
|
||||
break;
|
||||
|
||||
case Shader::STO_stage_i:
|
||||
GLCAT.error()
|
||||
<< "Sampler type of GLSL shader input p3d_Texture" << spec._stage
|
||||
<< " does not match type of texture " << *tex << ".\n";
|
||||
break;
|
||||
|
||||
case Shader::STO_light_i_shadow_map:
|
||||
GLCAT.error()
|
||||
<< "Sampler type of GLSL shader input p3d_LightSource[" << spec._stage
|
||||
<< "].shadowMap does not match type of texture " << *tex << ".\n";
|
||||
break;
|
||||
}
|
||||
// TODO: also check whether shadow sampler textures have shadow filter
|
||||
// enabled.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@
|
|||
* @date 2006-03-16
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the associated object.
|
||||
*/
|
||||
INLINE TypedWritableReferenceCount *BufferContext::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes previously reported for the data object. This
|
||||
* is used to track changes in the data object's allocated size; if it changes
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ TypeHandle BufferContext::_type_handle;
|
|||
*
|
||||
*/
|
||||
BufferContext::
|
||||
BufferContext(BufferResidencyTracker *residency) :
|
||||
BufferContext(BufferResidencyTracker *residency, TypedWritableReferenceCount *object) :
|
||||
_object(object),
|
||||
_residency(residency),
|
||||
_residency_state(0),
|
||||
_data_size_bytes(0),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "bufferResidencyTracker.h"
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
class TypedWritableReferenceCount;
|
||||
|
||||
/**
|
||||
* This is a base class for those kinds of SavedContexts that occupy an
|
||||
|
|
@ -36,15 +37,19 @@ class PreparedGraphicsObjects;
|
|||
*/
|
||||
class EXPCL_PANDA_GOBJ BufferContext : public SavedContext, private LinkedListNode {
|
||||
public:
|
||||
BufferContext(BufferResidencyTracker *residency);
|
||||
BufferContext(BufferResidencyTracker *residency, TypedWritableReferenceCount *object);
|
||||
virtual ~BufferContext();
|
||||
|
||||
INLINE TypedWritableReferenceCount *get_object() const;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE size_t get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
INLINE bool get_active() const;
|
||||
INLINE bool get_resident() const;
|
||||
|
||||
MAKE_PROPERTY(object, get_object);
|
||||
|
||||
MAKE_PROPERTY(data_size_bytes, get_data_size_bytes);
|
||||
MAKE_PROPERTY(modified, get_modified);
|
||||
MAKE_PROPERTY(active, get_active);
|
||||
|
|
@ -62,6 +67,11 @@ public:
|
|||
private:
|
||||
void set_owning_chain(BufferContextChain *chain);
|
||||
|
||||
protected:
|
||||
// This cannot be a PT(), because the object and the GSG both own their
|
||||
// BufferContexts! That would create a circular reference count.
|
||||
TypedWritableReferenceCount *_object;
|
||||
|
||||
private:
|
||||
BufferResidencyTracker *_residency;
|
||||
int _residency_state;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@
|
|||
*/
|
||||
INLINE IndexBufferContext::
|
||||
IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
||||
BufferContext(&pgo->_ibuffer_residency),
|
||||
AdaptiveLruPage(0),
|
||||
_data(data)
|
||||
BufferContext(&pgo->_ibuffer_residency, data),
|
||||
AdaptiveLruPage(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +26,7 @@ IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
|||
*/
|
||||
INLINE GeomPrimitive *IndexBufferContext::
|
||||
get_data() const {
|
||||
return _data;
|
||||
return (GeomPrimitive *)_object;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +35,7 @@ get_data() const {
|
|||
*/
|
||||
INLINE bool IndexBufferContext::
|
||||
changed_size(const GeomPrimitivePipelineReader *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +45,7 @@ changed_size(const GeomPrimitivePipelineReader *reader) const {
|
|||
*/
|
||||
INLINE bool IndexBufferContext::
|
||||
changed_usage_hint(const GeomPrimitivePipelineReader *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return _usage_hint != reader->get_usage_hint();
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ changed_usage_hint(const GeomPrimitivePipelineReader *reader) const {
|
|||
*/
|
||||
INLINE bool IndexBufferContext::
|
||||
was_modified(const GeomPrimitivePipelineReader *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return get_modified() != reader->get_modified();
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +75,7 @@ update_data_size_bytes(size_t new_data_size_bytes) {
|
|||
*/
|
||||
INLINE void IndexBufferContext::
|
||||
mark_loaded(const GeomPrimitivePipelineReader *reader) {
|
||||
nassertv(reader->get_object() == _data);
|
||||
nassertv(reader->get_object() == get_data());
|
||||
update_data_size_bytes(reader->get_data_size_bytes());
|
||||
update_modified(reader->get_modified());
|
||||
_usage_hint = reader->get_usage_hint();
|
||||
|
|
|
|||
|
|
@ -50,9 +50,6 @@ public:
|
|||
virtual void write(std::ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
// This cannot be a PT(GeomPrimitive), because the data and the GSG both own
|
||||
// their IndexBufferContexts! That would create a circular reference count.
|
||||
GeomPrimitive *_data;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -270,11 +270,11 @@ void PreparedGraphicsObjects::
|
|||
release_texture(TextureContext *tc) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
tc->_texture->clear_prepared(tc->get_view(), this);
|
||||
tc->get_texture()->clear_prepared(tc->get_view(), this);
|
||||
|
||||
// We have to set the Texture pointer to NULL at this point, since the
|
||||
// Texture itself might destruct at any time after it has been released.
|
||||
tc->_texture = nullptr;
|
||||
tc->_object = nullptr;
|
||||
|
||||
bool removed = (_prepared_textures.erase(tc) != 0);
|
||||
nassertv(removed);
|
||||
|
|
@ -307,8 +307,8 @@ release_all_textures() {
|
|||
tci != _prepared_textures.end();
|
||||
++tci) {
|
||||
TextureContext *tc = (*tci);
|
||||
tc->_texture->clear_prepared(tc->get_view(), this);
|
||||
tc->_texture = nullptr;
|
||||
tc->get_texture()->clear_prepared(tc->get_view(), this);
|
||||
tc->_object = nullptr;
|
||||
|
||||
_released_textures.insert(tc);
|
||||
}
|
||||
|
|
@ -946,14 +946,14 @@ void PreparedGraphicsObjects::
|
|||
release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
vbc->_data->clear_prepared(this);
|
||||
vbc->get_data()->clear_prepared(this);
|
||||
|
||||
size_t data_size_bytes = vbc->_data->get_data_size_bytes();
|
||||
GeomEnums::UsageHint usage_hint = vbc->_data->get_usage_hint();
|
||||
size_t data_size_bytes = vbc->get_data()->get_data_size_bytes();
|
||||
GeomEnums::UsageHint usage_hint = vbc->get_data()->get_usage_hint();
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since the Data
|
||||
// itself might destruct at any time after it has been released.
|
||||
vbc->_data = nullptr;
|
||||
vbc->_object = nullptr;
|
||||
|
||||
bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
|
||||
nassertv(removed);
|
||||
|
|
@ -985,8 +985,8 @@ release_all_vertex_buffers() {
|
|||
vbci != _prepared_vertex_buffers.end();
|
||||
++vbci) {
|
||||
VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
|
||||
vbc->_data->clear_prepared(this);
|
||||
vbc->_data = nullptr;
|
||||
vbc->get_data()->clear_prepared(this);
|
||||
vbc->_object = nullptr;
|
||||
|
||||
_released_vertex_buffers.insert(vbc);
|
||||
}
|
||||
|
|
@ -1061,7 +1061,7 @@ prepare_vertex_buffer_now(GeomVertexArrayData *data, GraphicsStateGuardianBase *
|
|||
_vertex_buffer_cache, _vertex_buffer_cache_lru,
|
||||
_vertex_buffer_cache_size);
|
||||
if (vbc != nullptr) {
|
||||
vbc->_data = data;
|
||||
vbc->_object = data;
|
||||
|
||||
} else {
|
||||
// Ask the GSG to create a brand new VertexBufferContext. There might be
|
||||
|
|
@ -1144,14 +1144,14 @@ void PreparedGraphicsObjects::
|
|||
release_index_buffer(IndexBufferContext *ibc) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
ibc->_data->clear_prepared(this);
|
||||
ibc->get_data()->clear_prepared(this);
|
||||
|
||||
size_t data_size_bytes = ibc->_data->get_data_size_bytes();
|
||||
GeomEnums::UsageHint usage_hint = ibc->_data->get_usage_hint();
|
||||
size_t data_size_bytes = ibc->get_data()->get_data_size_bytes();
|
||||
GeomEnums::UsageHint usage_hint = ibc->get_data()->get_usage_hint();
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since the Data
|
||||
// itself might destruct at any time after it has been released.
|
||||
ibc->_data = nullptr;
|
||||
ibc->_object = nullptr;
|
||||
|
||||
bool removed = (_prepared_index_buffers.erase(ibc) != 0);
|
||||
nassertv(removed);
|
||||
|
|
@ -1183,8 +1183,8 @@ release_all_index_buffers() {
|
|||
ibci != _prepared_index_buffers.end();
|
||||
++ibci) {
|
||||
IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
|
||||
ibc->_data->clear_prepared(this);
|
||||
ibc->_data = nullptr;
|
||||
ibc->get_data()->clear_prepared(this);
|
||||
ibc->_object = nullptr;
|
||||
|
||||
_released_index_buffers.insert(ibc);
|
||||
}
|
||||
|
|
@ -1258,7 +1258,7 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
|
|||
_index_buffer_cache, _index_buffer_cache_lru,
|
||||
_index_buffer_cache_size);
|
||||
if (ibc != nullptr) {
|
||||
ibc->_data = data;
|
||||
ibc->_object = data;
|
||||
|
||||
} else {
|
||||
// Ask the GSG to create a brand new IndexBufferContext. There might be
|
||||
|
|
@ -1341,6 +1341,13 @@ void PreparedGraphicsObjects::
|
|||
release_shader_buffer(BufferContext *bc) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
ShaderBuffer *buffer = (ShaderBuffer *)bc->_object;
|
||||
buffer->clear_prepared(this);
|
||||
|
||||
// We have to set the ShaderBuffer pointer to NULL at this point, since the
|
||||
// buffer itself might destruct at any time after it has been released.
|
||||
bc->_object = nullptr;
|
||||
|
||||
bool removed = (_prepared_shader_buffers.erase(bc) != 0);
|
||||
nassertv(removed);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,31 @@ release_all() {
|
|||
return num_freed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the indicated PreparedGraphicsObjects table from the buffer's
|
||||
* table, without actually releasing the texture. This is intended to be
|
||||
* called only from PreparedGraphicsObjects::release_shader_buffer(); it
|
||||
* should never be called by user code.
|
||||
*/
|
||||
void ShaderBuffer::
|
||||
clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
nassertv(_contexts != nullptr);
|
||||
|
||||
Contexts::iterator ci;
|
||||
ci = _contexts->find(prepared_objects);
|
||||
if (ci != _contexts->end()) {
|
||||
_contexts->erase(ci);
|
||||
if (_contexts->empty()) {
|
||||
delete _contexts;
|
||||
_contexts = nullptr;
|
||||
}
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a prepared_objects
|
||||
// which the data array didn't know about.
|
||||
nassert_raise("unknown PreparedGraphicsObjects");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BamReader how to create objects of type ParamValue.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ PUBLISHED:
|
|||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
private:
|
||||
uint64_t _data_size_bytes;
|
||||
UsageHint _usage_hint;
|
||||
|
|
@ -91,6 +94,8 @@ public:
|
|||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
INLINE std::ostream &operator << (std::ostream &out, const ShaderBuffer &m) {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@
|
|||
*/
|
||||
INLINE TextureContext::
|
||||
TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
|
||||
BufferContext(&pgo->_texture_residency),
|
||||
BufferContext(&pgo->_texture_residency, tex),
|
||||
AdaptiveLruPage(0),
|
||||
_texture(tex),
|
||||
_view(view)
|
||||
{
|
||||
}
|
||||
|
|
@ -28,7 +27,7 @@ TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
|
|||
*/
|
||||
INLINE Texture *TextureContext::
|
||||
get_texture() const {
|
||||
return _texture;
|
||||
return (Texture *)_object;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +55,7 @@ was_modified() const {
|
|||
*/
|
||||
INLINE bool TextureContext::
|
||||
was_properties_modified() const {
|
||||
return _properties_modified != _texture->get_properties_modified();
|
||||
return _properties_modified != get_texture()->get_properties_modified();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -65,7 +64,7 @@ was_properties_modified() const {
|
|||
*/
|
||||
INLINE bool TextureContext::
|
||||
was_image_modified() const {
|
||||
return _image_modified != _texture->get_image_modified();
|
||||
return _image_modified != get_texture()->get_image_modified();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,7 +73,7 @@ was_image_modified() const {
|
|||
*/
|
||||
INLINE bool TextureContext::
|
||||
was_simple_image_modified() const {
|
||||
return _simple_image_modified != _texture->get_simple_image_modified();
|
||||
return _simple_image_modified != get_texture()->get_simple_image_modified();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,8 +120,8 @@ update_data_size_bytes(size_t new_data_size_bytes) {
|
|||
INLINE void TextureContext::
|
||||
mark_loaded() {
|
||||
// _data_size_bytes = _data->get_texture_size_bytes();
|
||||
_properties_modified = _texture->get_properties_modified();
|
||||
_image_modified = _texture->get_image_modified();
|
||||
_properties_modified = get_texture()->get_properties_modified();
|
||||
_image_modified = get_texture()->get_image_modified();
|
||||
update_modified(std::max(_properties_modified, _image_modified));
|
||||
|
||||
// Assume the texture is now resident.
|
||||
|
|
@ -135,8 +134,8 @@ mark_loaded() {
|
|||
*/
|
||||
INLINE void TextureContext::
|
||||
mark_simple_loaded() {
|
||||
_properties_modified = _texture->get_properties_modified();
|
||||
_simple_image_modified = _texture->get_simple_image_modified();
|
||||
_properties_modified = get_texture()->get_properties_modified();
|
||||
_simple_image_modified = get_texture()->get_simple_image_modified();
|
||||
update_modified(std::max(_properties_modified, _simple_image_modified));
|
||||
|
||||
// The texture's not exactly resident now, but some part of it is.
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ public:
|
|||
virtual void write(std::ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
// This cannot be a PT(Texture), because the texture and the GSG both own
|
||||
// their TextureContexts! That would create a circular reference count.
|
||||
Texture *_texture;
|
||||
int _view;
|
||||
UpdateSeq _properties_modified;
|
||||
UpdateSeq _image_modified;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,12 @@ TexturePeeker(Texture *tex, Texture::CData *cdata) {
|
|||
_get_texel = get_texel_la;
|
||||
break;
|
||||
|
||||
case Texture::F_rg16:
|
||||
case Texture::F_rg32:
|
||||
case Texture::F_rg:
|
||||
_get_texel = get_texel_rg;
|
||||
break;
|
||||
|
||||
case Texture::F_rgb:
|
||||
case Texture::F_rgb5:
|
||||
case Texture::F_rgb8:
|
||||
|
|
@ -148,6 +154,7 @@ TexturePeeker(Texture *tex, Texture::CData *cdata) {
|
|||
case Texture::F_rgb332:
|
||||
case Texture::F_r11_g11_b10:
|
||||
case Texture::F_rgb9_e5:
|
||||
case Texture::F_rgb32:
|
||||
_get_texel = get_texel_rgb;
|
||||
break;
|
||||
|
||||
|
|
@ -582,6 +589,18 @@ get_texel_la(LColor &color, const unsigned char *&p, GetComponentFunc *get_compo
|
|||
color[3] = (*get_component)(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color of the texel at byte p, given that the texture is in format
|
||||
* F_rg or similar.
|
||||
*/
|
||||
void TexturePeeker::
|
||||
get_texel_rg(LColor &color, const unsigned char *&p, GetComponentFunc *get_component) {
|
||||
color[0] = (*get_component)(p);
|
||||
color[1] = (*get_component)(p);
|
||||
color[2] = 0.0f;
|
||||
color[3] = 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color of the texel at byte p, given that the texture is in format
|
||||
* F_rgb or similar.
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ private:
|
|||
static void get_texel_a(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_l(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_la(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_rg(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_rgb(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_rgba(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
static void get_texel_srgb(LColor &color, const unsigned char *&p, GetComponentFunc *get_component);
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@
|
|||
*/
|
||||
INLINE VertexBufferContext::
|
||||
VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
|
||||
BufferContext(&pgo->_vbuffer_residency),
|
||||
AdaptiveLruPage(0),
|
||||
_data(data)
|
||||
BufferContext(&pgo->_vbuffer_residency, data),
|
||||
AdaptiveLruPage(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +26,7 @@ VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
|
|||
*/
|
||||
INLINE GeomVertexArrayData *VertexBufferContext::
|
||||
get_data() const {
|
||||
return _data;
|
||||
return (GeomVertexArrayData *)_object;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +35,7 @@ get_data() const {
|
|||
*/
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_size(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +45,7 @@ changed_size(const GeomVertexArrayDataHandle *reader) const {
|
|||
*/
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return _usage_hint != reader->get_usage_hint();
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
|
|||
*/
|
||||
INLINE bool VertexBufferContext::
|
||||
was_modified(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
nassertr(reader->get_object() == get_data(), false);
|
||||
return get_modified() != reader->get_modified();
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +76,7 @@ update_data_size_bytes(size_t new_data_size_bytes) {
|
|||
*/
|
||||
INLINE void VertexBufferContext::
|
||||
mark_loaded(const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == _data);
|
||||
nassertv(reader->get_object() == get_data());
|
||||
update_data_size_bytes(reader->get_data_size_bytes());
|
||||
update_modified(reader->get_modified());
|
||||
_usage_hint = reader->get_usage_hint();
|
||||
|
|
|
|||
|
|
@ -51,10 +51,6 @@ public:
|
|||
virtual void write(std::ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
// This cannot be a PT(GeomVertexArrayData), because the data and the GSG
|
||||
// both own their VertexBufferContexts! That would create a circular
|
||||
// reference count.
|
||||
GeomVertexArrayData *_data;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -280,13 +280,10 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Camera::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Receives an array of pointers, one for each time manager->read_pointer()
|
||||
* was called in fillin(). Returns the number of pointers processed.
|
||||
*/
|
||||
int Camera::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = LensNode::complete_pointers(p_list, manager);
|
||||
|
|
|
|||
|
|
@ -1084,6 +1084,8 @@ set_effects(const RenderEffects *effects, Thread *current_thread) {
|
|||
*/
|
||||
void PandaNode::
|
||||
set_transform(const TransformState *transform, Thread *current_thread) {
|
||||
nassertv(!transform->is_invalid());
|
||||
|
||||
// Need to have this held before we grab any other locks.
|
||||
LightMutexHolder holder(_dirty_prev_transforms._lock);
|
||||
|
||||
|
|
@ -1120,6 +1122,8 @@ set_transform(const TransformState *transform, Thread *current_thread) {
|
|||
*/
|
||||
void PandaNode::
|
||||
set_prev_transform(const TransformState *transform, Thread *current_thread) {
|
||||
nassertv(!transform->is_invalid());
|
||||
|
||||
// Need to have this held before we grab any other locks.
|
||||
LightMutexHolder holder(_dirty_prev_transforms._lock);
|
||||
|
||||
|
|
@ -3510,12 +3514,12 @@ update_cached(bool update_bounds, int pipeline_stage, PandaNode::CDLockedStageRe
|
|||
const BoundingVolume **child_begin = &child_volumes[0];
|
||||
const BoundingVolume **child_end = child_begin + child_volumes_i;
|
||||
((BoundingVolume *)gbv)->around(child_begin, child_end);
|
||||
}
|
||||
|
||||
// If we have a transform, apply it to the bounding volume we just
|
||||
// computed.
|
||||
if (!transform->is_identity()) {
|
||||
gbv->xform(transform->get_mat());
|
||||
// If we have a transform, apply it to the bounding volume we just
|
||||
// computed.
|
||||
if (!transform->is_identity()) {
|
||||
gbv->xform(transform->get_mat());
|
||||
}
|
||||
}
|
||||
|
||||
cdataw->_external_bounds = gbv;
|
||||
|
|
@ -3849,6 +3853,9 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
// Mark the bounds stale.
|
||||
++_next_update;
|
||||
|
||||
nassertr(!_transform->is_invalid(), pi);
|
||||
nassertr(!_prev_transform->is_invalid(), pi);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue