mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
dd50d7d206
@ -220,7 +220,7 @@ get_unicode_char(size_t index) const {
|
|||||||
* according to set_encoding().
|
* according to set_encoding().
|
||||||
*/
|
*/
|
||||||
INLINE void TextEncoder::
|
INLINE void TextEncoder::
|
||||||
set_unicode_char(size_t index, int character) {
|
set_unicode_char(size_t index, char32_t character) {
|
||||||
get_wtext();
|
get_wtext();
|
||||||
if (index < _wtext.length()) {
|
if (index < _wtext.length()) {
|
||||||
_wtext[index] = character;
|
_wtext[index] = character;
|
||||||
@ -283,7 +283,7 @@ reencode_text(const std::string &text, TextEncoder::Encoding from,
|
|||||||
* otherwise. This is akin to ctype's isalpha(), extended to Unicode.
|
* otherwise. This is akin to ctype's isalpha(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_isalpha(int character) {
|
unicode_isalpha(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
@ -297,7 +297,7 @@ unicode_isalpha(int character) {
|
|||||||
* otherwise. This is akin to ctype's isdigit(), extended to Unicode.
|
* otherwise. This is akin to ctype's isdigit(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_isdigit(int character) {
|
unicode_isdigit(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
// The digits aren't actually listed in the map.
|
// The digits aren't actually listed in the map.
|
||||||
@ -312,7 +312,7 @@ unicode_isdigit(int character) {
|
|||||||
* otherwise. This is akin to ctype's ispunct(), extended to Unicode.
|
* otherwise. This is akin to ctype's ispunct(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_ispunct(int character) {
|
unicode_ispunct(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
// Some punctuation marks aren't listed in the map.
|
// Some punctuation marks aren't listed in the map.
|
||||||
@ -326,7 +326,7 @@ unicode_ispunct(int character) {
|
|||||||
* otherwise. This is akin to ctype's isupper(), extended to Unicode.
|
* otherwise. This is akin to ctype's isupper(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_isupper(int character) {
|
unicode_isupper(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
@ -339,7 +339,7 @@ unicode_isupper(int character) {
|
|||||||
* otherwise. This is akin to ctype's isspace(), extended to Unicode.
|
* otherwise. This is akin to ctype's isspace(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_isspace(int character) {
|
unicode_isspace(char32_t character) {
|
||||||
switch (character) {
|
switch (character) {
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
@ -356,7 +356,7 @@ unicode_isspace(int character) {
|
|||||||
* otherwise. This is akin to ctype's islower(), extended to Unicode.
|
* otherwise. This is akin to ctype's islower(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE bool TextEncoder::
|
INLINE bool TextEncoder::
|
||||||
unicode_islower(int character) {
|
unicode_islower(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
@ -369,7 +369,7 @@ unicode_islower(int character) {
|
|||||||
* akin to ctype's toupper(), extended to Unicode.
|
* akin to ctype's toupper(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE int TextEncoder::
|
INLINE int TextEncoder::
|
||||||
unicode_toupper(int character) {
|
unicode_toupper(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
return character;
|
return character;
|
||||||
@ -382,7 +382,7 @@ unicode_toupper(int character) {
|
|||||||
* akin to ctype's tolower(), extended to Unicode.
|
* akin to ctype's tolower(), extended to Unicode.
|
||||||
*/
|
*/
|
||||||
INLINE int TextEncoder::
|
INLINE int TextEncoder::
|
||||||
unicode_tolower(int character) {
|
unicode_tolower(char32_t character) {
|
||||||
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
return character;
|
return character;
|
||||||
|
@ -23,7 +23,7 @@ class StringDecoder;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class can be used to convert text between multiple representations,
|
* This class can be used to convert text between multiple representations,
|
||||||
* e.g. utf-8 to Unicode. You may use it as a static class object, passing
|
* e.g. UTF-8 to UTF-16. You may use it as a static class object, passing
|
||||||
* the encoding each time, or you may create an instance and use that object,
|
* the encoding each time, or you may create an instance and use that object,
|
||||||
* which will record the current encoding and retain the current string.
|
* which will record the current encoding and retain the current string.
|
||||||
*
|
*
|
||||||
@ -78,21 +78,21 @@ PUBLISHED:
|
|||||||
INLINE void append_unicode_char(char32_t character);
|
INLINE void append_unicode_char(char32_t character);
|
||||||
INLINE size_t get_num_chars() const;
|
INLINE size_t get_num_chars() const;
|
||||||
INLINE int get_unicode_char(size_t index) const;
|
INLINE int get_unicode_char(size_t index) const;
|
||||||
INLINE void set_unicode_char(size_t index, int character);
|
INLINE void set_unicode_char(size_t index, char32_t character);
|
||||||
INLINE std::string get_encoded_char(size_t index) const;
|
INLINE std::string get_encoded_char(size_t index) const;
|
||||||
INLINE std::string get_encoded_char(size_t index, Encoding encoding) const;
|
INLINE std::string get_encoded_char(size_t index, Encoding encoding) const;
|
||||||
INLINE std::string get_text_as_ascii() const;
|
INLINE std::string get_text_as_ascii() const;
|
||||||
|
|
||||||
INLINE static std::string reencode_text(const std::string &text, Encoding from, Encoding to);
|
INLINE static std::string reencode_text(const std::string &text, Encoding from, Encoding to);
|
||||||
|
|
||||||
INLINE static bool unicode_isalpha(int character);
|
INLINE static bool unicode_isalpha(char32_t character);
|
||||||
INLINE static bool unicode_isdigit(int character);
|
INLINE static bool unicode_isdigit(char32_t character);
|
||||||
INLINE static bool unicode_ispunct(int character);
|
INLINE static bool unicode_ispunct(char32_t character);
|
||||||
INLINE static bool unicode_islower(int character);
|
INLINE static bool unicode_islower(char32_t character);
|
||||||
INLINE static bool unicode_isupper(int character);
|
INLINE static bool unicode_isupper(char32_t character);
|
||||||
INLINE static bool unicode_isspace(int character);
|
INLINE static bool unicode_isspace(char32_t character);
|
||||||
INLINE static int unicode_toupper(int character);
|
INLINE static int unicode_toupper(char32_t character);
|
||||||
INLINE static int unicode_tolower(int character);
|
INLINE static int unicode_tolower(char32_t character);
|
||||||
|
|
||||||
INLINE static std::string upper(const std::string &source);
|
INLINE static std::string upper(const std::string &source);
|
||||||
INLINE static std::string upper(const std::string &source, Encoding encoding);
|
INLINE static std::string upper(const std::string &source, Encoding encoding);
|
||||||
|
@ -1378,7 +1378,7 @@ static const wchar_t combining_accent_map[] = {
|
|||||||
* Returns the Entry associated with the indicated character, if there is one.
|
* Returns the Entry associated with the indicated character, if there is one.
|
||||||
*/
|
*/
|
||||||
const UnicodeLatinMap::Entry *UnicodeLatinMap::
|
const UnicodeLatinMap::Entry *UnicodeLatinMap::
|
||||||
look_up(wchar_t character) {
|
look_up(char32_t character) {
|
||||||
if (!_initialized) {
|
if (!_initialized) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -112,17 +112,17 @@ public:
|
|||||||
|
|
||||||
class Entry {
|
class Entry {
|
||||||
public:
|
public:
|
||||||
wchar_t _character;
|
char32_t _character;
|
||||||
CharType _char_type;
|
CharType _char_type;
|
||||||
char _ascii_equiv;
|
char _ascii_equiv;
|
||||||
char _ascii_additional;
|
char _ascii_additional;
|
||||||
wchar_t _tolower_character;
|
char32_t _tolower_character;
|
||||||
wchar_t _toupper_character;
|
char32_t _toupper_character;
|
||||||
AccentType _accent_type;
|
AccentType _accent_type;
|
||||||
int _additional_flags;
|
int _additional_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Entry *look_up(wchar_t character);
|
static const Entry *look_up(char32_t character);
|
||||||
|
|
||||||
static wchar_t get_combining_accent(AccentType accent);
|
static wchar_t get_combining_accent(AccentType accent);
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ private:
|
|||||||
static void init();
|
static void init();
|
||||||
static bool _initialized;
|
static bool _initialized;
|
||||||
|
|
||||||
typedef phash_map<wchar_t, const Entry *, integer_hash<wchar_t> > ByCharacter;
|
typedef phash_map<char32_t, const Entry *, integer_hash<char32_t> > ByCharacter;
|
||||||
static ByCharacter *_by_character;
|
static ByCharacter *_by_character;
|
||||||
enum { max_direct_chars = 256 };
|
enum { max_direct_chars = 256 };
|
||||||
static const Entry *_direct_chars[max_direct_chars];
|
static const Entry *_direct_chars[max_direct_chars];
|
||||||
|
@ -82,26 +82,6 @@ is_debug() const {
|
|||||||
// Instruct the compiler to optimize for the usual case.
|
// Instruct the compiler to optimize for the usual case.
|
||||||
return UNLIKELY(is_on(NS_debug));
|
return UNLIKELY(is_on(NS_debug));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* When NOTIFY_DEBUG is not defined, the categories are never set to "spam" or
|
|
||||||
* "debug" severities, and these methods are redefined to be static to make it
|
|
||||||
* more obvious to the compiler.
|
|
||||||
*/
|
|
||||||
constexpr bool NotifyCategory::
|
|
||||||
is_spam() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When NOTIFY_DEBUG is not defined, the categories are never set to "spam" or
|
|
||||||
* "debug" severities, and these methods are redefined to be static to make it
|
|
||||||
* more obvious to the compiler.
|
|
||||||
*/
|
|
||||||
constexpr bool NotifyCategory::
|
|
||||||
is_debug() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +55,8 @@ PUBLISHED:
|
|||||||
INLINE bool is_spam() const;
|
INLINE bool is_spam() const;
|
||||||
INLINE bool is_debug() const;
|
INLINE bool is_debug() const;
|
||||||
#else
|
#else
|
||||||
constexpr static bool is_spam();
|
constexpr static bool is_spam() { return false; }
|
||||||
constexpr static bool is_debug();
|
constexpr static bool is_debug() { return false; }
|
||||||
#endif
|
#endif
|
||||||
INLINE bool is_info() const;
|
INLINE bool is_info() const;
|
||||||
INLINE bool is_warning() const;
|
INLINE bool is_warning() const;
|
||||||
|
@ -72,12 +72,6 @@ is_spam() {
|
|||||||
// Instruct the compiler to optimize for the usual case.
|
// Instruct the compiler to optimize for the usual case.
|
||||||
return UNLIKELY(get_unsafe_ptr()->is_spam());
|
return UNLIKELY(get_unsafe_ptr()->is_spam());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<class GetCategory>
|
|
||||||
constexpr bool NotifyCategoryProxy<GetCategory>::
|
|
||||||
is_spam() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,12 +84,6 @@ is_debug() {
|
|||||||
// Instruct the compiler to optimize for the usual case.
|
// Instruct the compiler to optimize for the usual case.
|
||||||
return UNLIKELY(get_unsafe_ptr()->is_debug());
|
return UNLIKELY(get_unsafe_ptr()->is_debug());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<class GetCategory>
|
|
||||||
constexpr bool NotifyCategoryProxy<GetCategory>::
|
|
||||||
is_debug() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,8 +75,8 @@ public:
|
|||||||
INLINE bool is_spam();
|
INLINE bool is_spam();
|
||||||
INLINE bool is_debug();
|
INLINE bool is_debug();
|
||||||
#else
|
#else
|
||||||
constexpr static bool is_spam();
|
constexpr static bool is_spam() { return false; }
|
||||||
constexpr static bool is_debug();
|
constexpr static bool is_debug() { return false; }
|
||||||
#endif
|
#endif
|
||||||
INLINE bool is_info();
|
INLINE bool is_info();
|
||||||
INLINE bool is_warning();
|
INLINE bool is_warning();
|
||||||
|
@ -1254,7 +1254,7 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
|
|||||||
|
|
||||||
if (geom->get_primitive_type() == Geom::PT_polygons) {
|
if (geom->get_primitive_type() == Geom::PT_polygons) {
|
||||||
Thread *current_thread = Thread::get_current_thread();
|
Thread *current_thread = Thread::get_current_thread();
|
||||||
CPT(GeomVertexData) data = geom->get_vertex_data()->animate_vertices(true, current_thread);
|
CPT(GeomVertexData) data = geom->get_animated_vertex_data(true, current_thread);
|
||||||
GeomVertexReader vertex(data, InternalName::get_vertex());
|
GeomVertexReader vertex(data, InternalName::get_vertex());
|
||||||
|
|
||||||
int num_primitives = geom->get_num_primitives();
|
int num_primitives = geom->get_num_primitives();
|
||||||
|
@ -484,8 +484,7 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
|
|||||||
const LMatrix4 &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv;
|
const LMatrix4 &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv;
|
||||||
|
|
||||||
// Iterate through all the vertices in the Geom.
|
// Iterate through all the vertices in the Geom.
|
||||||
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
|
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(true, current_thread);
|
||||||
vdata = vdata->animate_vertices(true, current_thread);
|
|
||||||
|
|
||||||
CPT(GeomVertexFormat) vformat = vdata->get_format();
|
CPT(GeomVertexFormat) vformat = vdata->get_format();
|
||||||
if (!vformat->has_column(_texcoord_name) || (_texcoord_3d && vformat->get_column(_texcoord_name)->get_num_components() < 3)) {
|
if (!vformat->has_column(_texcoord_name) || (_texcoord_3d && vformat->get_column(_texcoord_name)->get_num_components() < 3)) {
|
||||||
@ -507,7 +506,7 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
|
|||||||
PT(GeomVertexData) modify_vdata = geom->modify_vertex_data();
|
PT(GeomVertexData) modify_vdata = geom->modify_vertex_data();
|
||||||
|
|
||||||
// Maybe the vdata has animation that we should consider.
|
// Maybe the vdata has animation that we should consider.
|
||||||
CPT(GeomVertexData) animated_vdata = geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread);
|
CPT(GeomVertexData) animated_vdata = geom->get_animated_vertex_data(true, current_thread);
|
||||||
|
|
||||||
GeomVertexWriter texcoord(modify_vdata, _texcoord_name, current_thread);
|
GeomVertexWriter texcoord(modify_vdata, _texcoord_name, current_thread);
|
||||||
GeomVertexWriter color(modify_vdata, current_thread);
|
GeomVertexWriter color(modify_vdata, current_thread);
|
||||||
@ -674,9 +673,8 @@ make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4 &rel_mat) {
|
|||||||
|
|
||||||
Thread *current_thread = Thread::get_current_thread();
|
Thread *current_thread = Thread::get_current_thread();
|
||||||
PT(Geom) new_geom = geom->make_copy();
|
PT(Geom) new_geom = geom->make_copy();
|
||||||
|
new_geom->set_vertex_data(new_geom->get_animated_vertex_data(false, current_thread));
|
||||||
PT(GeomVertexData) vdata = new_geom->modify_vertex_data();
|
PT(GeomVertexData) vdata = new_geom->modify_vertex_data();
|
||||||
new_geom->set_vertex_data(vdata->animate_vertices(false, current_thread));
|
|
||||||
vdata = new_geom->modify_vertex_data();
|
|
||||||
GeomVertexRewriter vertex(vdata, InternalName::get_vertex());
|
GeomVertexRewriter vertex(vdata, InternalName::get_vertex());
|
||||||
while (!vertex.is_at_end()) {
|
while (!vertex.is_at_end()) {
|
||||||
LVertex vert = vertex.get_data3();
|
LVertex vert = vertex.get_data3();
|
||||||
|
@ -286,6 +286,28 @@ make_nonindexed(bool composite_only) {
|
|||||||
return num_changed;
|
return num_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a GeomVertexData that represents the results of computing the
|
||||||
|
* vertex animation on the CPU for this Geom's vertex data.
|
||||||
|
*
|
||||||
|
* If there is no CPU-defined vertex animation on this object, this just
|
||||||
|
* returns the original object.
|
||||||
|
*
|
||||||
|
* If there is vertex animation, but the VertexTransform values have not
|
||||||
|
* changed since last time, this may return the same pointer it returned
|
||||||
|
* previously. Even if the VertexTransform values have changed, it may still
|
||||||
|
* return the same pointer, but with its contents modified (this is preferred,
|
||||||
|
* since it allows the graphics backend to update vertex buffers optimally).
|
||||||
|
*
|
||||||
|
* If force is false, this method may return immediately with stale data, if
|
||||||
|
* the vertex data is not completely resident. If force is true, this method
|
||||||
|
* will never return stale data, but may block until the data is available.
|
||||||
|
*/
|
||||||
|
CPT(GeomVertexData) Geom::
|
||||||
|
get_animated_vertex_data(bool force, Thread *current_thread) const {
|
||||||
|
return get_vertex_data()->animate_vertices(force, current_thread);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the ith GeomPrimitive object stored within the Geom with the new
|
* Replaces the ith GeomPrimitive object stored within the Geom with the new
|
||||||
* object.
|
* object.
|
||||||
@ -1311,8 +1333,7 @@ compute_internal_bounds(Geom::CData *cdata, Thread *current_thread) const {
|
|||||||
int num_vertices = 0;
|
int num_vertices = 0;
|
||||||
|
|
||||||
// Get the vertex data, after animation.
|
// Get the vertex data, after animation.
|
||||||
CPT(GeomVertexData) vertex_data = cdata->_data.get_read_pointer(current_thread);
|
CPT(GeomVertexData) vertex_data = get_animated_vertex_data(true, current_thread);
|
||||||
vertex_data = vertex_data->animate_vertices(true, current_thread);
|
|
||||||
|
|
||||||
// Now actually compute the bounding volume. We do this by using
|
// Now actually compute the bounding volume. We do this by using
|
||||||
// calc_tight_bounds to determine our box first.
|
// calc_tight_bounds to determine our box first.
|
||||||
|
@ -85,6 +85,8 @@ PUBLISHED:
|
|||||||
void offset_vertices(const GeomVertexData *data, int offset);
|
void offset_vertices(const GeomVertexData *data, int offset);
|
||||||
int make_nonindexed(bool composite_only);
|
int make_nonindexed(bool composite_only);
|
||||||
|
|
||||||
|
CPT(GeomVertexData) get_animated_vertex_data(bool force, Thread *current_thread) const;
|
||||||
|
|
||||||
INLINE bool is_empty() const;
|
INLINE bool is_empty() const;
|
||||||
|
|
||||||
INLINE size_t get_num_primitives() const;
|
INLINE size_t get_num_primitives() const;
|
||||||
|
@ -45,7 +45,9 @@ has_column(const InternalName *name) const {
|
|||||||
*/
|
*/
|
||||||
INLINE int GeomVertexArrayData::
|
INLINE int GeomVertexArrayData::
|
||||||
get_num_rows() const {
|
get_num_rows() const {
|
||||||
return get_handle()->get_num_rows();
|
CDReader cdata(_cycler);
|
||||||
|
nassertr(_array_format->get_stride() != 0, 0);
|
||||||
|
return cdata->_buffer.get_size() / _array_format->get_stride();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,9 +60,20 @@ has_column(const InternalName *name) const {
|
|||||||
*/
|
*/
|
||||||
INLINE int GeomVertexData::
|
INLINE int GeomVertexData::
|
||||||
get_num_rows() const {
|
get_num_rows() const {
|
||||||
GeomVertexDataPipelineReader reader(this, Thread::get_current_thread());
|
CPT(GeomVertexArrayData) array;
|
||||||
reader.check_array_readers();
|
{
|
||||||
return reader.get_num_rows();
|
CDReader cdata(_cycler);
|
||||||
|
nassertr(cdata->_format->get_num_arrays() == cdata->_arrays.size(), 0);
|
||||||
|
|
||||||
|
if (cdata->_arrays.size() == 0) {
|
||||||
|
// No arrays means no rows. Weird but legal.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
array = cdata->_arrays[0].get_read_pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array->get_num_rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -621,13 +621,26 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||||||
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
|
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
|
||||||
LVecBase4 weights = LVecBase4::zero();
|
LVecBase4 weights = LVecBase4::zero();
|
||||||
LVecBase4i indices(0, 0, 0, 0);
|
LVecBase4i indices(0, 0, 0, 0);
|
||||||
nassertv(blend.get_num_transforms() <= 4);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
|
if (blend.get_num_transforms() <= 4) {
|
||||||
weights[i] = blend.get_weight(i);
|
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
|
||||||
indices[i] = add_transform(transform_table, blend.get_transform(i),
|
weights[i] = blend.get_weight(i);
|
||||||
already_added);
|
indices[i] = add_transform(transform_table, blend.get_transform(i),
|
||||||
|
already_added);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Limit the number of blends to the four with highest weights.
|
||||||
|
TransformBlend blend2(blend);
|
||||||
|
blend2.limit_transforms(4);
|
||||||
|
blend2.normalize_weights();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
weights[i] = blend2.get_weight(i);
|
||||||
|
indices[i] = add_transform(transform_table, blend2.get_transform(i),
|
||||||
|
already_added);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weight.has_column()) {
|
if (weight.has_column()) {
|
||||||
weight.set_data4(weights);
|
weight.set_data4(weights);
|
||||||
}
|
}
|
||||||
|
@ -866,7 +866,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
|
|||||||
PT(Geom) geom = orig_geom->make_copy();
|
PT(Geom) geom = orig_geom->make_copy();
|
||||||
|
|
||||||
// Ensure that any vertex animation has been applied.
|
// Ensure that any vertex animation has been applied.
|
||||||
geom->set_vertex_data(geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread));
|
geom->set_vertex_data(geom->get_animated_vertex_data(true, current_thread));
|
||||||
|
|
||||||
// Now get a modifiable pointer to the vertex data in the new Geom. This
|
// Now get a modifiable pointer to the vertex data in the new Geom. This
|
||||||
// will actually perform a deep copy of the vertex data.
|
// will actually perform a deep copy of the vertex data.
|
||||||
|
@ -376,8 +376,7 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
|
|||||||
geom = transformer.premunge_geom(geom, munger);
|
geom = transformer.premunge_geom(geom, munger);
|
||||||
|
|
||||||
// Prepare each of the vertex arrays in the munged Geom.
|
// Prepare each of the vertex arrays in the munged Geom.
|
||||||
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
|
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(false, current_thread);
|
||||||
vdata = vdata->animate_vertices(false, current_thread);
|
|
||||||
GeomVertexDataPipelineReader vdata_reader(vdata, current_thread);
|
GeomVertexDataPipelineReader vdata_reader(vdata, current_thread);
|
||||||
int num_arrays = vdata_reader.get_num_arrays();
|
int num_arrays = vdata_reader.get_num_arrays();
|
||||||
for (int i = 0; i < num_arrays; ++i) {
|
for (int i = 0; i < num_arrays; ++i) {
|
||||||
@ -474,7 +473,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
|
|||||||
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
|
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
|
||||||
CPT(Geom) geom = (*gi)._geom.get_read_pointer();
|
CPT(Geom) geom = (*gi)._geom.get_read_pointer();
|
||||||
geom->calc_tight_bounds(min_point, max_point, found_any,
|
geom->calc_tight_bounds(min_point, max_point, found_any,
|
||||||
geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread),
|
geom->get_animated_vertex_data(true, current_thread),
|
||||||
!next_transform->is_identity(), mat,
|
!next_transform->is_identity(), mat,
|
||||||
current_thread);
|
current_thread);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user