Merge branch 'master' into cmake

This commit is contained in:
Sam Edwards 2018-10-28 05:11:14 -06:00
commit 58c065d970
98 changed files with 560 additions and 10989 deletions

View File

@ -77,7 +77,10 @@ class FunctionInterval(Interval.Interval):
@staticmethod
def makeUniqueName(func, suffix = ''):
name = 'Func-%s-%d' % (getattr(func, '__name__', str(func)), FunctionInterval.functionIntervalNum)
func_name = getattr(func, '__name__', None)
if func_name is None:
func_name = str(func)
name = 'Func-%s-%d' % (func_name, FunctionInterval.functionIntervalNum)
FunctionInterval.functionIntervalNum += 1
if suffix:
name = '%s-%s' % (name, str(suffix))

View File

@ -1,20 +0,0 @@
HOW TO INSTALL MAX PANDA PLUGINS.
Step 1. Install the visual studio 2008 runtime by
running "vcredist_x86-sp1.exe" as administrator.
As a convenience, this installer is included with panda.
Step 2. Make sure that there is only one copy of panda
in your system PATH. If you only have one copy of panda
installed, you can skip this step.
Step 3. Copy the relevant DLLs for your version
of max from the panda plugins directory to the
max plugins directory. For instance, if you are
using Max 9, copy maxegg9.dlo and maxeggimport9.dlo
HOW TO INSTALL MAYA PANDA PLUGINS.
(To be written)

View File

@ -1,183 +0,0 @@
------------------------ RELEASE 1.0.0 ---------------------------------
* We now have working exporters for Max5, Max6, Max7, Maya5, Maya6
* The Max exporter is dramatically improved:
- it now includes support for character studio.
- the polygon winding bug has been fixed.
* Panda no longer requires any registry keys or environment
variables. This means it is now possible to:
- run panda directly from a compact disc
- install multiple copies of panda on a single machine
- install panda by copying the tree from another computer
Note that the installer does add the panda 'bin' directory to
your PATH, and it does store an uninstall key in the registry,
but neither of these is needed for panda to function.
* The 'makepanda' build system is now capable of building
prepackaged games for Windows. These prepackaged games are simply
copies of panda with the game code included, some of the
unnecessary stuff stripped out, and some changes to the start
menu. See "Airblade - Installer" on the panda downloads page
for an example.
* All of the sample programs have been tested. The ones that didn't
work have been removed, the ones that do work have been (lightly)
documented.
* This is the first release to include not just a binary installer
for windows, but:
- a binary installer (RPM) for Fedora 2
- a binary installer (RPM) for Fedora 3
- a binary installer (RPM) for Redhat 9
- a binary installer for windows, as always
- a source tar-ball for linux
- a source zip-file for windows
------------------------ RELEASE 2004-12-13 ---------------------------------
* Basic server-client networking support is back in Panda3D. There is a
networking sample in the samples directory. This uses the Panda3d
distributed object system.The README file will explain how to run this.
Documentation of this if forthcoming.
* Panda3d now reduces the number of environment variables such that only 2
are needed now - PRC_PATH and PLAYER.
* GraphicsChannel and GraphicsLayer class have been removed from the
panda/src/display directory. Most Panda applications won't need to be
changed, since most applications simply use ShowBase.py (which has been
adjustedappropriately) to open a window and do the initial setup. For
those rare applications where you need to create your own DisplayRegions,
the makeDisplayRegion() interface has been moved from GraphicsLayer to
GraphicsWindow (actually, to GraphicsOutput, which is the base class of
GraphicsWindow). You can modify your application to call
base.win.makeDisplayRegion() accordingly. If you have something like
displayRegion.getLayer(), replace it with displayRegion.getWindow()
instead.
* Effective with the current version of Panda, the way that HPR angles are
calculated will be changing. The change will make a difference to existing
code or databases that store a hard-coded rotation as a HPR, but only when
R is involved, or both H and P are involved together. That is to say more
precisely, HPR angles with (R != 0 || (H != 0 && P != 0)) now represent a
different rotation than they used to. If you find some legacy code that no
longer works correctly (e.g. it introduces crazy rotations), try putting
the following in your Config.prc file:
temp-hpr-fix 0
To turn off the correct behavior and return to the old, broken behavior.
Note that a longer-term solution will be to represent the HPR angles
correctly in all legacy code. The function oldToNewHpr() is provided to
aid this transition.
* PandaNode definition has been changed to support setting an
into_collide_mask for any arbitrary node, in particular for any GeomNode.
It used to be that only CollisionNodes had an into_collide_mask. This
change obviates the need for CollisionNode::set_collide_geom(), which is
now a deprecated interface and will be removed at some point in the future.
Details:
There's now a NodePath::set_collide_mask() and
NodePath::get_collide_mask(), which operate on all CollisionNodes and
GeomNodes at and below the current node. By default, set_collide_mask()
will replace the entire collide mask, but you may also specify (via a
second parameter) the subset of bits that are to be changed; other bits
will be left alone. You can also specify a particular type of node to
modify via a third parameter, e.g. you can adjust the masks for GeomNodes
or CollisionNodes only.
The NodePath set_collide_mask() interface changes the into_collide_mask.
Those familiar with the collision system will recall that a CollisionNode
(but only a CollisionNode) also has a from_collide_mask. The
from_collide_mask of the active mover is compared with the into_collide_mask
of each object in the world; a collision is only possible if there are some
bits in common.
It used to be that only other CollisionNodes had an into_collide_mask. A
mover would only test for collisions with CollisionNodes that matched its
collide_mask. If you wanted to make your mover detect collisions with
visible geometry which had no into_collide_mask, you had to call
set_collide_geom(1). This allowed the mover to detect collisions with *all*
visible geometry; it was either an all-or-none thing.
Now that GeomNodes also have an into_collide_mask, there's no longer a need
for set_collide_geom(). A mover will detect collisions with any
CollisionNodes or GeomNodes that match its collide_mask. This means, for
the purposes of collision detection, you can use CollisionNodes and
GeomNodes pretty much interchangeably; simply set the appropriate bits on
the objects you want to collide with, regardless of whether they are
invisible collision solids or visible geometry.
(This should not be taken as a license to avoid using CollisionNodes
altogether. The intersection computation with visible geometry is still
less efficient than the same computation with collision solids. And visible
geometry tends to be many times more complex than is strictly necessary for
collisions.)
There's one more detail: every GeomNode, by default, has one bit set on in
its collide_mask, unless it is explicitly turned off. This bit is
GeomNode::get_default_collide_mask(). This bit is provided for the
convenience of programmers who still want the old behavior of
set_collide_geom(): it allows you to easily create a CollisionNode that
will collide with all visible geometry in the world.
Along the same lines, there's also CollisionNode::get_default_collide_mask(),
which is 0x000fffff. This is the default mask that is created for a new
CollisionNode (and it does not include the bit reserved for GeomNodes,
above). Previously, a new CollisionNode would have all bits on by default.
------------------------ RELEASE 2004-11-11 -----------------------------------
* Multiple mice can now be used with Panda3D. showbase has a list called
pointerWatcherNodes. The first mouse on this list is the system mouse. The
getMouseX() and getMouseY() will return coordinates relative to the
application window. The rest of the mice on the list will give raw mouse
positions and will change when they are moved on the screen.
In addition there are new events for mouse buttons. Each mouse will be have
a corresponding event. mouse1 will send mousedev1-mouse1, mousedev1-mouse2
and mousedev1-mouse3 events. mouse2 and any other mouse attached
will send similar events mousedev2-mouse1 etc.
The old mouse buttons work too. mouse1, mouse2, mouse3 events will be
triggered if that button is pressed on any mouse
------------------------ RELEASE 2004-10-13 -----------------------------------
General
* Release notes: Each release will now have an entry associated with
it in this document. This will be updated in reverse-chronological order.
Panda3D
* Distributed with this release is a working version of the SceneEditor
created in Spring 2004 at the ETC. Documentation will be forthcoming on the
website. This can be found in <InstallPath>/SceneEditor
* The latest version of FMOD is distributed with this release. The latest
version is 3.73.
* AudioSound object now allows more types of sound. These include wma and
ogg vorbis formats. This is valid when using the fmod sound system. Midi,
Mod, s3m, it, xm and such sequencer type file formats are not supported.
Exception - Midi files can be played. This is not fully implemented.
* A bug in SoundInterval is fixed. SoundInterval looping would incorrectly
add a minimum of 1.5 seconds to the sound. This has been fixed. Sound
looping problems in general should be fixed. Midi's still don't support
looping through the AudioSound object. They should loop through
SoundIntervals though.
* Cg support has been added to Panda3D. Documentation for this is
forthcoming.

View File

@ -62,4 +62,12 @@ default_thread_consider_yield() {
void (*global_thread_yield)() = default_thread_yield;
void (*global_thread_consider_yield)() = default_thread_consider_yield;
#ifdef HAVE_PYTHON
static PyThreadState *
default_thread_state_swap(PyThreadState *state) {
return nullptr;
}
PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate) = default_thread_state_swap;
#endif // HAVE_PYTHON
#endif // HAVE_THREADS && SIMPLE_THREADS

View File

@ -63,8 +63,10 @@
/* Windows likes to define min() and max() macros, which will conflict with
std::min() and std::max() respectively, unless we do this: */
#ifdef WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0

View File

@ -233,6 +233,15 @@ INLINE void thread_consider_yield() {
(*global_thread_consider_yield)();
}
#ifdef HAVE_PYTHON
typedef struct _ts PyThreadState;
extern EXPCL_DTOOL_DTOOLBASE PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate);
INLINE PyThreadState *thread_state_swap(PyThreadState *tstate) {
return (*global_thread_state_swap)(tstate);
}
#endif // HAVE_PYTHON
#else
INLINE void thread_yield() {

View File

@ -220,7 +220,7 @@ get_unicode_char(size_t index) const {
* according to set_encoding().
*/
INLINE void TextEncoder::
set_unicode_char(size_t index, int character) {
set_unicode_char(size_t index, char32_t character) {
get_wtext();
if (index < _wtext.length()) {
_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.
*/
INLINE bool TextEncoder::
unicode_isalpha(int character) {
unicode_isalpha(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -297,7 +297,7 @@ unicode_isalpha(int character) {
* otherwise. This is akin to ctype's isdigit(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isdigit(int character) {
unicode_isdigit(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
// The digits aren't actually listed in the map.
@ -312,11 +312,11 @@ unicode_isdigit(int character) {
* otherwise. This is akin to ctype's ispunct(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_ispunct(int character) {
unicode_ispunct(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
// Some punctuation marks aren't listed in the map.
return (character >= 0 && character < 128 && ispunct(character));
return (character < 128 && ispunct(character));
}
return entry->_char_type == UnicodeLatinMap::CT_punct;
}
@ -326,7 +326,7 @@ unicode_ispunct(int character) {
* otherwise. This is akin to ctype's isupper(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isupper(int character) {
unicode_isupper(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -339,7 +339,7 @@ unicode_isupper(int character) {
* otherwise. This is akin to ctype's isspace(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isspace(int character) {
unicode_isspace(char32_t character) {
switch (character) {
case ' ':
case '\t':
@ -356,7 +356,7 @@ unicode_isspace(int character) {
* otherwise. This is akin to ctype's islower(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_islower(int character) {
unicode_islower(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -369,7 +369,7 @@ unicode_islower(int character) {
* akin to ctype's toupper(), extended to Unicode.
*/
INLINE int TextEncoder::
unicode_toupper(int character) {
unicode_toupper(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return character;
@ -382,7 +382,7 @@ unicode_toupper(int character) {
* akin to ctype's tolower(), extended to Unicode.
*/
INLINE int TextEncoder::
unicode_tolower(int character) {
unicode_tolower(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return character;

View File

@ -23,7 +23,7 @@ class StringDecoder;
/**
* 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,
* 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 size_t get_num_chars() 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, Encoding encoding) 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 bool unicode_isalpha(int character);
INLINE static bool unicode_isdigit(int character);
INLINE static bool unicode_ispunct(int character);
INLINE static bool unicode_islower(int character);
INLINE static bool unicode_isupper(int character);
INLINE static bool unicode_isspace(int character);
INLINE static int unicode_toupper(int character);
INLINE static int unicode_tolower(int character);
INLINE static bool unicode_isalpha(char32_t character);
INLINE static bool unicode_isdigit(char32_t character);
INLINE static bool unicode_ispunct(char32_t character);
INLINE static bool unicode_islower(char32_t character);
INLINE static bool unicode_isupper(char32_t character);
INLINE static bool unicode_isspace(char32_t character);
INLINE static int unicode_toupper(char32_t 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, Encoding encoding);

View File

@ -94,7 +94,12 @@ append_text(PyObject *text) {
#if PY_VERSION_HEX >= 0x03030000
Py_ssize_t len;
const char *str = PyUnicode_AsUTF8AndSize(text, &len);
_this->append_text(std::string(str, len));
std::string text_str(str, len);
if (_this->get_encoding() == TextEncoder::E_utf8) {
_this->append_text(text_str);
} else {
_this->append_wtext(TextEncoder::decode_text(text_str, TextEncoder::E_utf8));
}
#else
Py_ssize_t len = PyUnicode_GET_SIZE(text);
wchar_t *str = (wchar_t *)alloca(sizeof(wchar_t) * (len + 1));

View File

@ -1378,7 +1378,7 @@ static const wchar_t combining_accent_map[] = {
* Returns the Entry associated with the indicated character, if there is one.
*/
const UnicodeLatinMap::Entry *UnicodeLatinMap::
look_up(wchar_t character) {
look_up(char32_t character) {
if (!_initialized) {
init();
}

View File

@ -112,17 +112,17 @@ public:
class Entry {
public:
wchar_t _character;
char32_t _character;
CharType _char_type;
char _ascii_equiv;
char _ascii_additional;
wchar_t _tolower_character;
wchar_t _toupper_character;
char32_t _tolower_character;
char32_t _toupper_character;
AccentType _accent_type;
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);
@ -130,7 +130,7 @@ private:
static void init();
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;
enum { max_direct_chars = 256 };
static const Entry *_direct_chars[max_direct_chars];

View File

@ -722,7 +722,10 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
// Extract the __file__ attribute, if present.
Filename main_dir;
PyObject *file_attr = PyObject_GetAttrString(main_module, "__file__");
PyObject *file_attr = nullptr;
if (main_module != nullptr) {
file_attr = PyObject_GetAttrString(main_module, "__file__");
}
if (file_attr == nullptr) {
// Must be running in the interactive interpreter. Use the CWD.
main_dir = ExecutionEnvironment::get_cwd();
@ -752,6 +755,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
PyErr_Clear();
initialized_main_dir = true;
// Also, while we are at it, initialize the thread swap hook.
#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
global_thread_state_swap = PyThreadState_Swap;
#endif
}
PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);

View File

@ -28,7 +28,7 @@ typedef _typeobject PyTypeObject;
typedef struct {} PyStringObject;
typedef struct {} PyUnicodeObject;
class PyThreadState;
typedef struct _ts PyThreadState;
typedef int Py_ssize_t;
typedef struct bufferinfo Py_buffer;

View File

@ -82,26 +82,6 @@ is_debug() const {
// Instruct the compiler to optimize for the usual case.
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
/**

View File

@ -55,8 +55,8 @@ PUBLISHED:
INLINE bool is_spam() const;
INLINE bool is_debug() const;
#else
constexpr static bool is_spam();
constexpr static bool is_debug();
constexpr static bool is_spam() { return false; }
constexpr static bool is_debug() { return false; }
#endif
INLINE bool is_info() const;
INLINE bool is_warning() const;

View File

@ -72,12 +72,6 @@ is_spam() {
// Instruct the compiler to optimize for the usual case.
return UNLIKELY(get_unsafe_ptr()->is_spam());
}
#else
template<class GetCategory>
constexpr bool NotifyCategoryProxy<GetCategory>::
is_spam() {
return false;
}
#endif
/**
@ -90,12 +84,6 @@ is_debug() {
// Instruct the compiler to optimize for the usual case.
return UNLIKELY(get_unsafe_ptr()->is_debug());
}
#else
template<class GetCategory>
constexpr bool NotifyCategoryProxy<GetCategory>::
is_debug() {
return false;
}
#endif
/**

View File

@ -75,8 +75,8 @@ public:
INLINE bool is_spam();
INLINE bool is_debug();
#else
constexpr static bool is_spam();
constexpr static bool is_debug();
constexpr static bool is_spam() { return false; }
constexpr static bool is_debug() { return false; }
#endif
INLINE bool is_info();
INLINE bool is_warning();

View File

@ -680,6 +680,9 @@ if (COMPILER == "MSVC"):
IncDirectory("FCOLLADA", GetThirdpartyDir() + "fcollada/include/FCollada")
if (PkgSkip("ASSIMP")==0):
LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/assimp.lib")
path = GetThirdpartyDir() + "assimp/lib/IrrXML.lib"
if os.path.isfile(path):
LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/IrrXML.lib")
IncDirectory("ASSIMP", GetThirdpartyDir() + "assimp/include/assimp")
if (PkgSkip("SQUISH")==0):
if GetOptimize() <= 2:
@ -946,8 +949,6 @@ if (COMPILER=="GCC"):
if GetTarget() == 'darwin':
LibName("ALWAYS", "-framework AppKit")
if (PkgSkip("OPENCV")==0):
LibName("OPENCV", "-framework QuickTime")
LibName("AGL", "-framework AGL")
LibName("CARBON", "-framework Carbon")
LibName("COCOA", "-framework Cocoa")
@ -1334,9 +1335,10 @@ def CompileCxx(obj,src,opts):
# Work around Apple compiler bug.
cmd += " -U__EXCEPTIONS"
if 'RTTI' not in opts:
target = GetTarget()
if 'RTTI' not in opts and target != "darwin":
# We always disable RTTI on Android for memory usage reasons.
if optlevel >= 4 or GetTarget() == "android":
if optlevel >= 4 or target == "android":
cmd += " -fno-rtti"
if ('SSE2' in opts or not PkgSkip("SSE2")) and not arch.startswith("arm") and arch != 'aarch64':
@ -1596,6 +1598,8 @@ def CompileLib(lib, obj, opts):
else:
cmd = GetAR() + ' cru ' + BracketNameWithQuotes(lib)
for x in obj:
if GetLinkAllStatic() and x.endswith('.a'):
continue
cmd += ' ' + BracketNameWithQuotes(x)
oscmd(cmd)
@ -3159,10 +3163,10 @@ CopyAllHeaders('panda/src/movies')
CopyAllHeaders('panda/src/pgraphnodes')
CopyAllHeaders('panda/src/pgraph')
CopyAllHeaders('panda/src/cull')
CopyAllHeaders('panda/src/display')
CopyAllHeaders('panda/src/chan')
CopyAllHeaders('panda/src/char')
CopyAllHeaders('panda/src/dgraph')
CopyAllHeaders('panda/src/display')
CopyAllHeaders('panda/src/device')
CopyAllHeaders('panda/src/pnmtext')
CopyAllHeaders('panda/src/text')
@ -3295,7 +3299,6 @@ if (PkgSkip("PANDATOOL")==0):
CopyAllHeaders('pandatool/src/ptloader')
CopyAllHeaders('pandatool/src/miscprogs')
CopyAllHeaders('pandatool/src/pstatserver')
CopyAllHeaders('pandatool/src/softprogs')
CopyAllHeaders('pandatool/src/text-stats')
CopyAllHeaders('pandatool/src/vrmlprogs')
CopyAllHeaders('pandatool/src/win-stats')
@ -3816,7 +3819,7 @@ if (not RUNTIME):
if (not RUNTIME):
OPTS=['DIR:panda/src/gobj', 'BUILDING:PANDA', 'NVIDIACG', 'ZLIB', 'SQUISH']
TargetAdd('p3gobj_composite1.obj', opts=OPTS, input='p3gobj_composite1.cxx')
TargetAdd('p3gobj_composite2.obj', opts=OPTS, input='p3gobj_composite2.cxx')
TargetAdd('p3gobj_composite2.obj', opts=OPTS+['BIGOBJ'], input='p3gobj_composite2.cxx')
OPTS=['DIR:panda/src/gobj', 'NVIDIACG', 'ZLIB', 'SQUISH', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/gobj', ["*.h", "*_composite*.cxx"])
@ -3875,6 +3878,31 @@ if (not RUNTIME):
TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull'])
TargetAdd('libp3cull_igate.obj', input='libp3cull.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/display/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/display', 'BUILDING:PANDA']
TargetAdd('p3display_graphicsStateGuardian.obj', opts=OPTS, input='graphicsStateGuardian.cxx')
TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx')
TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx')
OPTS=['DIR:panda/src/display', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"])
IGATEFILES.remove("renderBuffer.h")
TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3display.in', opts=['IMOD:panda3d.core', 'ILIB:libp3display', 'SRCDIR:panda/src/display'])
TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"])
TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx')
TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx')
TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx')
if RTDIST and GetTarget() == 'darwin':
OPTS=['DIR:panda/src/display']
TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx')
TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj')
#
# DIRECTORY: panda/src/chan/
#
@ -3922,30 +3950,6 @@ if (not RUNTIME):
TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph'])
TargetAdd('libp3dgraph_igate.obj', input='libp3dgraph.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/display/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/display', 'BUILDING:PANDA']
TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx')
TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx')
OPTS=['DIR:panda/src/display', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"])
IGATEFILES.remove("renderBuffer.h")
TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3display.in', opts=['IMOD:panda3d.core', 'ILIB:libp3display', 'SRCDIR:panda/src/display'])
TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"])
TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx')
TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx')
TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx')
if RTDIST and GetTarget() == 'darwin':
OPTS=['DIR:panda/src/display']
TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx')
TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj')
#
# DIRECTORY: panda/src/device/
#
@ -4167,6 +4171,7 @@ if (not RUNTIME):
TargetAdd('libpanda.dll', input='p3device_composite2.obj')
TargetAdd('libpanda.dll', input='p3dgraph_composite1.obj')
TargetAdd('libpanda.dll', input='p3dgraph_composite2.obj')
TargetAdd('libpanda.dll', input='p3display_graphicsStateGuardian.obj')
TargetAdd('libpanda.dll', input='p3display_composite1.obj')
TargetAdd('libpanda.dll', input='p3display_composite2.obj')
TargetAdd('libpanda.dll', input='p3pipeline_composite1.obj')
@ -6346,21 +6351,6 @@ if (PkgSkip("PANDATOOL")==0):
TargetAdd('p3pstatserver_composite1.obj', opts=OPTS, input='p3pstatserver_composite1.cxx')
TargetAdd('libp3pstatserver.lib', input='p3pstatserver_composite1.obj')
#
# DIRECTORY: pandatool/src/softprogs/
#
if (PkgSkip("PANDATOOL")==0):
OPTS=['DIR:pandatool/src/softprogs', 'OPENSSL']
TargetAdd('softcvs_softCVS.obj', opts=OPTS, input='softCVS.cxx')
TargetAdd('softcvs_softFilename.obj', opts=OPTS, input='softFilename.cxx')
TargetAdd('softcvs.exe', input='softcvs_softCVS.obj')
TargetAdd('softcvs.exe', input='softcvs_softFilename.obj')
TargetAdd('softcvs.exe', input='libp3progbase.lib')
TargetAdd('softcvs.exe', input='libp3pandatoolbase.lib')
TargetAdd('softcvs.exe', input=COMMON_PANDA_LIBS)
TargetAdd('softcvs.exe', opts=['ADVAPI'])
#
# DIRECTORY: pandatool/src/text-stats/
#

View File

@ -4770,12 +4770,6 @@
<File RelativePath="..\pandatool\src\ptloader\config_ptloader.h"></File>
<File RelativePath="..\pandatool\src\ptloader\loaderFileTypePandatool.h"></File>
</Filter>
<Filter Name="softprogs">
<File RelativePath="..\pandatool\src\softprogs\softCVS.cxx"></File>
<File RelativePath="..\pandatool\src\softprogs\softFilename.h"></File>
<File RelativePath="..\pandatool\src\softprogs\softCVS.h"></File>
<File RelativePath="..\pandatool\src\softprogs\softFilename.cxx"></File>
</Filter>
<Filter Name="imageprogs">
<File RelativePath="..\pandatool\src\imageprogs\imageTrans.h"></File>
<File RelativePath="..\pandatool\src\imageprogs\imageTransformColors.cxx"></File>
@ -5305,20 +5299,6 @@
<File RelativePath="..\pandatool\src\lwo\lwoSurfaceBlockImage.h"></File>
<File RelativePath="..\pandatool\src\lwo\lwoSurfaceBlockCoordSys.cxx"></File>
</Filter>
<Filter Name="softegg">
<File RelativePath="..\pandatool\src\softegg\soft2Egg.c"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeTree.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeDesc.h"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.I"></File>
<File RelativePath="..\pandatool\src\softegg\config_softegg.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softToEggConverter.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeTree.h"></File>
<File RelativePath="..\pandatool\src\softegg\config_softegg.h"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeDesc.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softToEggConverter.h"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.h"></File>
</Filter>
<Filter Name="xfileprogs">
<File RelativePath="..\pandatool\src\xfileprogs\eggToX.cxx"></File>
<File RelativePath="..\pandatool\src\xfileprogs\xFileTrans.cxx"></File>

View File

@ -32,14 +32,14 @@ AnimControl(const std::string &name, PartBundle *part,
Namable(name),
_pending_lock(name),
_pending_cvar(_pending_lock),
_bound_joints(BitArray::all_on())
_bound_joints(BitArray::all_on()),
_part(part)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
#endif
_pending = true;
_part = part;
_anim = nullptr;
_channel_index = -1;
set_frame_rate(frame_rate);

View File

@ -39,6 +39,8 @@ class EXPCL_PANDA_CHAN AnimControl : public TypedReferenceCount, public AnimInte
public:
AnimControl(const std::string &name, PartBundle *part,
double frame_rate, int num_frames);
AnimControl(const AnimControl &copy) = delete;
void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
const BitArray &bound_joints);
void set_bound_joints(const BitArray &bound_joints);
@ -82,7 +84,7 @@ private:
// This is a PT(PartGroup) instead of a PT(PartBundle), just because we
// can't include partBundle.h for circular reasons. But it actually keeps a
// pointer to a PartBundle.
PT(PartGroup) _part;
const PT(PartGroup) _part;
PT(AnimBundle) _anim;
int _channel_index;

View File

@ -556,8 +556,15 @@ control_removed(AnimControl *control) {
CDStageWriter cdata(_cycler, pipeline_stage);
ChannelBlend::iterator cbi = cdata->_blend.find(control);
if (cbi != cdata->_blend.end()) {
cdata->_net_blend -= cbi->second;
cdata->_blend.erase(cbi);
cdata->_anim_changed = true;
// We need to make sure that any _effective_channel pointers that point
// to this control are cleared.
if (pipeline_stage == 0) {
determine_effective_channels(cdata);
}
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);

View File

@ -1254,7 +1254,7 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
if (geom->get_primitive_type() == Geom::PT_polygons) {
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());
int num_primitives = geom->get_num_primitives();

View File

@ -753,7 +753,7 @@ render_frame() {
// frames, so we won't have to recompute it each frame.
int num_drs = win->get_num_active_display_regions();
for (int i = 0; i < num_drs; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
NodePath camera_np = dr->get_camera(current_thread);
if (!camera_np.is_empty()) {
@ -1359,7 +1359,7 @@ is_scene_root(const PandaNode *node) {
if (win->is_active() && win->get_gsg()->is_active()) {
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
NodePath camera = dr->get_camera();
if (camera.is_empty()) {
@ -1435,7 +1435,7 @@ cull_and_draw_together(GraphicsEngine::Windows wlist,
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
cull_and_draw_together(win, dr, current_thread);
}
@ -1539,7 +1539,7 @@ cull_to_bins(GraphicsEngine::Windows wlist, Thread *current_thread) {
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
PT(SceneSetup) scene_setup;
PT(CullResult) cull_result;
@ -1659,7 +1659,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
}
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
do_draw(win, gsg, dr, current_thread);
}

View File

@ -697,9 +697,6 @@ void GraphicsOutput::
remove_all_display_regions() {
LightMutexHolder holder(_lock);
CDWriter cdata(_cycler, true);
cdata->_active_display_regions_stale = true;
TotalDisplayRegions::iterator dri;
for (dri = _total_display_regions.begin();
dri != _total_display_regions.end();
@ -713,6 +710,12 @@ remove_all_display_regions() {
}
_total_display_regions.clear();
_total_display_regions.push_back(_overlay_display_region);
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
cdata->_active_display_regions_stale = true;
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
/**
@ -740,13 +743,8 @@ set_overlay_display_region(DisplayRegion *display_region) {
*/
int GraphicsOutput::
get_num_display_regions() const {
determine_display_regions();
int result;
{
LightMutexHolder holder(_lock);
result = _total_display_regions.size();
}
return result;
LightMutexHolder holder(_lock);
return _total_display_regions.size();
}
/**
@ -1504,13 +1502,15 @@ do_remove_display_region(DisplayRegion *display_region) {
find(_total_display_regions.begin(), _total_display_regions.end(), drp);
if (dri != _total_display_regions.end()) {
// Let's aggressively clean up the display region too.
CDWriter cdata(_cycler, true);
display_region->cleanup();
display_region->_window = nullptr;
_total_display_regions.erase(dri);
cdata->_active_display_regions_stale = true;
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
cdata->_active_display_regions_stale = true;
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
return true;
}

View File

@ -394,6 +394,7 @@ protected:
typedef CycleDataLockedReader<CData> CDLockedReader;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageWriter<CData> CDStageWriter;
protected:
int _creation_flags;

View File

@ -18,7 +18,6 @@
#include "load_dso.h"
#include "config_display.h"
#include "typeRegistry.h"
#include "pset.h"
#include "config_putil.h"
#include <algorithm>
@ -61,8 +60,8 @@ GraphicsPipeSelection() : _lock("GraphicsPipeSelection") {
// Also get the set of modules named in the various aux-display Config
// variables. We'll want to know this when we call load_modules() later.
int num_aux = aux_display.get_num_unique_values();
for (int i = 0; i < num_aux; i++) {
size_t num_aux = aux_display.get_num_unique_values();
for (size_t i = 0; i < num_aux; ++i) {
string name = aux_display.get_unique_value(i);
if (name != _default_display_module) {
_display_modules.push_back(name);
@ -124,9 +123,7 @@ print_pipe_types() const {
LightMutexHolder holder(_lock);
nout << "Known pipe types:" << std::endl;
PipeTypes::const_iterator pi;
for (pi = _pipe_types.begin(); pi != _pipe_types.end(); ++pi) {
const PipeType &pipe_type = (*pi);
for (const PipeType &pipe_type : _pipe_types) {
nout << " " << pipe_type._type << "\n";
}
if (_display_modules.empty()) {
@ -187,11 +184,9 @@ make_pipe(const string &type_name, const string &module_name) {
PT(GraphicsPipe) GraphicsPipeSelection::
make_pipe(TypeHandle type) {
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
// First, look for an exact match of the requested type.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type == type) {
// Here's an exact match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -202,8 +197,7 @@ make_pipe(TypeHandle type) {
}
// Now look for a more-specific type.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type.is_derived_from(type)) {
// Here's an approximate match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -215,8 +209,7 @@ make_pipe(TypeHandle type) {
// Couldn't find any match; load the default module and try again.
load_default_module();
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type.is_derived_from(type)) {
// Here's an approximate match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -260,13 +253,11 @@ make_default_pipe() {
load_default_module();
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
if (!_default_pipe_name.empty()) {
// First, look for an exact match of the default type name from the
// Configrc file (excepting case and hyphenunderscore).
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (cmp_nocase_uh(ptype._type.get_name(), _default_pipe_name) == 0) {
// Here's an exact match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -278,8 +269,7 @@ make_default_pipe() {
// No match; look for a substring match.
string preferred_name = downcase(_default_pipe_name);
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
string ptype_name = downcase(ptype._type.get_name());
if (ptype_name.find(preferred_name) != string::npos) {
// Here's a substring match.
@ -292,8 +282,7 @@ make_default_pipe() {
}
// Couldn't find a matching pipe type; choose the first one on the list.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
PT(GraphicsPipe) pipe = (*ptype._constructor)();
if (pipe != nullptr) {
return pipe;
@ -310,9 +299,8 @@ make_default_pipe() {
*/
void GraphicsPipeSelection::
load_aux_modules() {
DisplayModules::iterator di;
for (di = _display_modules.begin(); di != _display_modules.end(); ++di) {
load_named_module(*di);
for (const string &module : _display_modules) {
load_named_module(module);
}
_display_modules.clear();
@ -337,9 +325,7 @@ add_pipe_type(TypeHandle type, PipeConstructorFunc *func) {
// First, make sure we don't already have a GraphicsPipe of this type.
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type == type) {
display_cat->warning()
<< "Attempt to register GraphicsPipe type " << type
@ -375,8 +361,8 @@ do_load_default_module() {
load_named_module(_default_display_module);
DisplayModules::iterator di =
find(_display_modules.begin(), _display_modules.end(),
_default_display_module);
std::find(_display_modules.begin(), _display_modules.end(),
_default_display_module);
if (di != _display_modules.end()) {
_display_modules.erase(di);
}

View File

@ -24,7 +24,6 @@
#include "renderBuffer.h"
#include "light.h"
#include "planeNode.h"
#include "ambientLight.h"
#include "throw_event.h"
#include "clockObject.h"
#include "pStatTimer.h"
@ -60,7 +59,6 @@
#include "fogAttrib.h"
#include "config_pstatclient.h"
#include <algorithm>
#include <limits.h>
using std::string;
@ -932,12 +930,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
case Shader::SMO_frame_time: {
PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
return &t;
}
case Shader::SMO_frame_delta: {
PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
return &t;
}
case Shader::SMO_texpad_x: {
@ -949,7 +947,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
double cx = (sx * 0.5) / tex->get_x_size();
double cy = (sy * 0.5) / tex->get_y_size();
double cz = (sz * 0.5) / tex->get_z_size();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
return &t;
}
case Shader::SMO_texpix_x: {
@ -958,7 +956,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
double px = 1.0 / tex->get_x_size();
double py = 1.0 / tex->get_y_size();
double pz = 1.0 / tex->get_z_size();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
return &t;
}
case Shader::SMO_attr_material: {
@ -966,7 +964,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
// Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
if (target_material->is_off()) {
t = LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
}
Material *m = target_material->get_material();
@ -975,17 +973,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
LVecBase4 const &emm = m->get_emission();
LVecBase4 spc = m->get_specular();
spc[3] = m->get_shininess();
t = LMatrix4(amb[0],amb[1],amb[2],amb[3],
dif[0],dif[1],dif[2],dif[3],
emm[0],emm[1],emm[2],emm[3],
spc[0],spc[1],spc[2],spc[3]);
t.set(amb[0], amb[1], amb[2], amb[3],
dif[0], dif[1], dif[2], dif[3],
emm[0], emm[1], emm[2], emm[3],
spc[0], spc[1], spc[2], spc[3]);
return &t;
}
case Shader::SMO_attr_material2: {
const MaterialAttrib *target_material = (const MaterialAttrib *)
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
if (target_material->is_off()) {
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
return &t;
}
Material *m = target_material->get_material();
@ -1000,7 +998,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 c = target_color->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_attr_colorscale: {
@ -1010,7 +1008,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 cs = target_color->get_scale();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
return &t;
}
case Shader::SMO_attr_fog: {
@ -1022,7 +1020,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
PN_stdfloat start, end;
fog->get_linear_range(start, end);
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->get_exp_density(),start,end,1.0f/(end-start));
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fog->get_exp_density(), start, end, 1.0f / (end - start));
return &t;
}
case Shader::SMO_attr_fogcolor: {
@ -1033,7 +1032,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 c = fog->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_alight_x: {
@ -1042,7 +1041,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
AmbientLight *lt;
DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
LColor const &c = lt->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_satten_x: {
@ -1052,7 +1051,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat());
LVecBase3 const &a = lt->get_attenuation();
PN_stdfloat x = lt->get_exponent();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
return &t;
}
case Shader::SMO_dlight_x: {
@ -1069,7 +1068,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
d.normalize();
LVecBase3 h = d + LVecBase3(0,-1,0);
h.normalize();
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],c[3],d[0],d[1],d[2],0,h[0],h[1],h[2],0);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], c[3],
d[0], d[1], d[2], 0,
h[0], h[1], h[2], 0);
return &t;
}
case Shader::SMO_plight_x: {
@ -1087,7 +1089,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
Lens *lens = lt->get_lens(0);
PN_stdfloat lnear = lens->get_near();
PN_stdfloat lfar = lens->get_far();
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],lnear,a[0],a[1],a[2],lfar);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], s[3],
p[0], p[1], p[2], lnear,
a[0], a[1], a[2], lfar);
return &t;
}
case Shader::SMO_slight_x: {
@ -1105,7 +1110,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
_scene_setup->get_world_transform()->get_mat();
LVecBase3 p = t.xform_point(lens->get_nodal_point());
LVecBase3 d = -(t.xform_vec(lens->get_view_vector()));
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], s[3],
p[0], p[1], p[2], 0,
d[0], d[1], d[2], cutoff);
return &t;
}
case Shader::SMO_light_ambient: {
@ -1149,7 +1157,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
index < ta->get_num_on_stages()) {
LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
return &t;
} else {
return &LMatrix4::ident_mat();
@ -1173,7 +1181,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
index < ta->get_num_on_stages()) {
TextureStage *ts = ta->get_on_stage(index);
PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha);
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,v,v,v,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
return &t;
} else {
return &LMatrix4::zeros_mat();
@ -1185,7 +1193,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
const PlaneNode *plane_node;
DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
LPlane p = plane_node->get_plane();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
return &t;
}
case Shader::SMO_clipplane_x: {
@ -1235,10 +1243,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
case Shader::SMO_vec_constant_x: {
const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
const PN_stdfloat *data = input.get_data();
t = LMatrix4(data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3]);
t.set(data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3]);
return &t;
}
case Shader::SMO_world_to_view: {
@ -1394,10 +1402,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
// There is an input specifying precisely this whole thing, with dot and
// all. Support this, even if only for backward compatibility.
const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
t = LMatrix4(data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3]);
t.set(data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3]);
return &t;
}
@ -1578,11 +1586,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
} else if (attrib == IN_position) {
if (np.is_empty()) {
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no position.
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
@ -1591,7 +1599,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
LVector3 dir = -(light->get_direction() * transform->get_mat());
dir *= _scene_setup->get_cs_world_transform()->get_mat();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
return &t;
} else {
LightLensNode *light;
@ -1611,11 +1619,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
} else if (attrib == IN_halfVector) {
if (np.is_empty()) {
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no half-vector.
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
@ -1627,7 +1635,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
dir.normalize();
dir += LVector3(0, 0, 1);
dir.normalize();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
return &t;
} else {
LightLensNode *light;
@ -1644,7 +1652,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
pos.normalize();
pos += LVector3(0, 0, 1);
pos.normalize();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
return &t;
}

View File

@ -1,5 +1,4 @@
#include "graphicsPipeSelection.cxx"
#include "graphicsStateGuardian.cxx"
#include "graphicsThreadingModel.cxx"
#include "graphicsWindow.cxx"
#include "graphicsWindowProc.cxx"

View File

@ -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;
// Iterate through all the vertices in the Geom.
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
vdata = vdata->animate_vertices(true, current_thread);
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(true, current_thread);
CPT(GeomVertexFormat) vformat = vdata->get_format();
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();
// 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 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();
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();
new_geom->set_vertex_data(vdata->animate_vertices(false, current_thread));
vdata = new_geom->modify_vertex_data();
GeomVertexRewriter vertex(vdata, InternalName::get_vertex());
while (!vertex.is_at_end()) {
LVertex vert = vertex.get_data3();

View File

@ -5240,9 +5240,9 @@ calc_fb_properties(DWORD cformat, DWORD dformat,
#define GAMMA_1 (255.0 * 256.0)
static bool _gamma_table_initialized = false;
static unsigned short _orignial_gamma_table [256 * 3];
static unsigned short _original_gamma_table [256 * 3];
void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
void _create_gamma_table_dx9 (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
int i;
double gamma_correction;
@ -5304,7 +5304,7 @@ get_gamma_table(void) {
HDC hdc = GetDC(nullptr);
if (hdc) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _original_gamma_table)) {
_gamma_table_initialized = true;
get = true;
}
@ -5329,10 +5329,10 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
unsigned short ramp [256 * 3];
if (restore && _gamma_table_initialized) {
_create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_dx9 (gamma, &_original_gamma_table [0], &_original_gamma_table [256], &_original_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
}
else {
_create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_dx9 (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
}
if (SetDeviceGammaRamp (hdc, ramp)) {

View File

@ -51,7 +51,7 @@
// OpenGL ES 2 has no fixed-function pipeline.
#undef SUPPORT_FIXED_FUNCTION
#ifdef IS_OSX
#ifdef BUILD_IPHONE
#include <OpenGLES/ES2/gl.h>
// #include <OpenGLESES2glext.h>
#else

View File

@ -54,7 +54,7 @@
#define __glext_h_
#define ES1_GLEXT_H_GUARD
#ifdef IS_OSX
#ifdef BUILD_IPHONE
#include <OpenGLES/ES1/gl.h>
// #include <OpenGLESES1glext.h>
#else

View File

@ -226,12 +226,14 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
if (!resource) {
resource = "unknown";
}
GLCAT.error()
<< "Could not find Cg varying " << cgGetParameterName(p);
if (attribname) {
GLCAT.error(false) << " : " << attribname;
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Could not find Cg varying " << cgGetParameterName(p);
if (attribname) {
GLCAT.debug(false) << " : " << attribname;
}
GLCAT.debug(false) << " (" << resource << ") in the compiled GLSL program.\n";
}
GLCAT.error(false) << " (" << resource << ") in the compiled GLSL program.\n";
} else if (loc != 0 && bind._id._name == "vtx_position") {
// We really have to bind the vertex position to attribute 0, since
@ -312,10 +314,10 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
GLCAT.debug(false)
<< " is bound to a conventional attribute (" << resource << ")\n";
}
}
if (loc == CA_unknown) {
// Suggest fix to developer.
GLCAT.error() << "Try using a different semantic.\n";
if (loc == CA_unknown) {
// Suggest fix to developer.
GLCAT.debug() << "Try using a different semantic.\n";
}
}
#endif

View File

@ -1097,6 +1097,15 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot,
#endif
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rbm[slot]);
GLuint format = GL_DEPTH_COMPONENT;
#ifndef OPENGLES
if (_fb_properties.get_float_depth()) {
if (!glgsg->_use_remapped_depth_range) {
format = GL_DEPTH_COMPONENT32F;
} else {
format = GL_DEPTH_COMPONENT32F_NV;
}
} else
#endif
if (tex) {
switch (tex->get_format()) {
case Texture::F_depth_component16:

View File

@ -8925,6 +8925,9 @@ get_panda_wrap_mode(GLenum wm) {
case GL_REPEAT:
return SamplerState::WM_repeat;
case GL_MIRRORED_REPEAT:
return SamplerState::WM_mirror;
#ifndef OPENGLES
case GL_MIRROR_CLAMP_EXT:
case GL_MIRROR_CLAMP_TO_EDGE_EXT:

View File

@ -286,6 +286,28 @@ make_nonindexed(bool composite_only) {
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
* object.
@ -1311,8 +1333,7 @@ compute_internal_bounds(Geom::CData *cdata, Thread *current_thread) const {
int num_vertices = 0;
// Get the vertex data, after animation.
CPT(GeomVertexData) vertex_data = cdata->_data.get_read_pointer(current_thread);
vertex_data = vertex_data->animate_vertices(true, current_thread);
CPT(GeomVertexData) vertex_data = get_animated_vertex_data(true, current_thread);
// Now actually compute the bounding volume. We do this by using
// calc_tight_bounds to determine our box first.

View File

@ -85,6 +85,8 @@ PUBLISHED:
void offset_vertices(const GeomVertexData *data, int offset);
int make_nonindexed(bool composite_only);
CPT(GeomVertexData) get_animated_vertex_data(bool force, Thread *current_thread) const;
INLINE bool is_empty() const;
INLINE size_t get_num_primitives() const;

View File

@ -45,7 +45,9 @@ has_column(const InternalName *name) const {
*/
INLINE int GeomVertexArrayData::
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();
}
/**

View File

@ -60,9 +60,20 @@ has_column(const InternalName *name) const {
*/
INLINE int GeomVertexData::
get_num_rows() const {
GeomVertexDataPipelineReader reader(this, Thread::get_current_thread());
reader.check_array_readers();
return reader.get_num_rows();
CPT(GeomVertexArrayData) array;
{
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();
}
/**
@ -761,7 +772,9 @@ set_object(const GeomVertexData *object) {
_cdata = (GeomVertexData::CData *)_object->_cycler.read_unlocked(_current_thread);
_got_array_readers = false;
#ifdef DO_PIPELINING
_cdata->ref();
#endif // DO_PIPELINING
}
/**

View File

@ -621,13 +621,26 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
LVecBase4 weights = LVecBase4::zero();
LVecBase4i indices(0, 0, 0, 0);
nassertv(blend.get_num_transforms() <= 4);
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
weights[i] = blend.get_weight(i);
indices[i] = add_transform(transform_table, blend.get_transform(i),
already_added);
if (blend.get_num_transforms() <= 4) {
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
weights[i] = blend.get_weight(i);
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()) {
weight.set_data4(weights);
}

View File

@ -1619,8 +1619,8 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
++qsi) {
Shader *shader = qsi->first;
ShaderContext *sc = shader->prepare_now(this, gsg);
if (qti->second != nullptr) {
qti->second->set_result(sc);
if (qsi->second != nullptr) {
qsi->second->set_result(sc);
}
}

View File

@ -40,7 +40,7 @@ do_task() {
// become a kind of a leak (if the texture is never rendered again on
// this GSG, we'll just end up carrying the texture memory in RAM
// forever, instead of dumping it as soon as it gets prepared).
_texture->prepare(_pgo);
_pgo->enqueue_texture(_texture);
}
}

View File

@ -866,7 +866,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
PT(Geom) geom = orig_geom->make_copy();
// 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
// will actually perform a deep copy of the vertex data.

View File

@ -445,7 +445,7 @@ do_flush() {
if (data_sent > 0) {
total_sent += data_sent;
}
double last_report = 0;
while (!okflag && tcp->Active() &&
(data_sent > 0 || tcp->GetLastError() == LOCAL_BLOCKING_ERROR)) {
if (data_sent == 0) {

View File

@ -54,6 +54,9 @@ apply_transform_and_state(CullTraverser *trav) {
CPT(TransformState) node_transform = _node_reader.get_transform();
node_effects->cull_callback(trav, *this, node_transform, node_state);
apply_transform(node_transform);
// The cull callback may have changed the node properties.
_node_reader.check_cached(false);
}
if (!node_state->is_empty()) {

View File

@ -376,8 +376,7 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
geom = transformer.premunge_geom(geom, munger);
// Prepare each of the vertex arrays in the munged Geom.
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
vdata = vdata->animate_vertices(false, current_thread);
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(false, current_thread);
GeomVertexDataPipelineReader vdata_reader(vdata, current_thread);
int num_arrays = vdata_reader.get_num_arrays();
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) {
CPT(Geom) geom = (*gi)._geom.get_read_pointer();
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,
current_thread);
}

View File

@ -211,7 +211,7 @@ garbage_collect() {
}
num_this_pass = std::min(num_this_pass, size);
size_t stop_at_element = (_garbage_index + num_this_pass) % size;
size_t stop_at_element = (si + num_this_pass) % size;
do {
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
@ -229,6 +229,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -950,6 +950,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -1216,6 +1216,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -11,14 +11,6 @@
* @date 2007-06-20
*/
/**
*
*/
INLINE BlockerSimple::
BlockerSimple() {
_flags = 0;
}
/**
*
*/

View File

@ -28,7 +28,7 @@
*/
class EXPCL_PANDA_PIPELINE BlockerSimple {
protected:
INLINE BlockerSimple();
constexpr BlockerSimple() = default;
INLINE ~BlockerSimple();
protected:
@ -38,7 +38,7 @@ protected:
F_has_waiters = 0x40000000,
};
unsigned int _flags;
unsigned int _flags = 0;
friend class ThreadSimpleManager;
};

View File

@ -71,7 +71,10 @@ init_libpipeline() {
}
initialized = true;
#ifdef DO_PIPELINING
CycleData::init_type();
#endif
MainThread::init_type();
ExternalThread::init_type();
GenericThread::init_type();

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_longjmp_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_longjmp_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
setmp() / longjmp(). This is the hackier implementation,
@ -90,14 +89,14 @@ void
cs_longjmp(cs_jmp_buf env) {
_asm {
mov eax, env;
mov ebx, [eax + 0];
mov edi, [eax + 4];
mov esi, [eax + 8];
mov ebp, [eax + 12];
mov esp, [eax + 16];
mov edx, [eax + 20];
frstor [eax + 24]; /* restore floating-point state */
mov eax, 1; /* return 1 from setjmp: pass 2 return */
@ -251,7 +250,7 @@ setup_context_1(void) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
/* Copy all of the input parameters to static variables, then begin
@ -263,7 +262,7 @@ init_thread_context(struct ThreadContext *context,
st_data = data;
setup_context_1();
}
}
void
save_thread_context(struct ThreadContext *context,

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_posix_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_posix_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
posix threads to manage the different execution contexts. This
@ -44,7 +43,7 @@ struct ThreadContext {
pthread_mutex_t _ready_mutex;
pthread_cond_t _ready_cvar;
int _ready_flag;
/* This is set FALSE while the thread is alive, and TRUE if the
thread is to be terminated when it next wakes up. */
int _terminated;
@ -83,19 +82,19 @@ thread_main(void *data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
context->_thread_func = thread_func;
context->_data = data;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stack_size);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&(context->_thread), &attr, thread_main, context);
pthread_attr_destroy(&attr);
pthread_create(&(context->_thread), &attr, thread_main, context);
pthread_attr_destroy(&attr);
}
void
@ -142,7 +141,7 @@ switch_to_thread_context(struct ThreadContext *from_context,
/* We've been rudely terminated. Exit gracefully. */
pthread_exit(NULL);
}
/* Now we have been signaled again, and we're ready to resume the
thread. */
longjmp(from_context->_jmp_context, 1);
@ -164,7 +163,7 @@ alloc_thread_context() {
pthread_mutexattr_init(&attr);
// The symbol PTHREAD_MUTEX_DEFAULT isn't always available?
// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
int result = pthread_mutex_init(&context->_ready_mutex, &attr);
pthread_mutex_init(&context->_ready_mutex, &attr);
pthread_mutexattr_destroy(&attr);
pthread_cond_init(&context->_ready_cvar, NULL);

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_ucontext_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_ucontext_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
getcontext() / setcontext(). This is the preferred implementation,
@ -43,7 +42,7 @@ begin_context(ThreadFunction *thread_func, void *data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
if (getcontext(&context->_ucontext) != 0) {

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_windows_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_windows_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
native Windows threading constructs to manage the different
@ -37,7 +36,7 @@ struct ThreadContext {
/* This event is in the signaled state when the thread is ready to
roll. */
HANDLE _ready;
/* This is set FALSE while the thread is alive, and TRUE if the
thread is to be terminated when it next wakes up. */
int _terminated;
@ -71,13 +70,13 @@ thread_main(LPVOID data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
context->_thread_func = thread_func;
context->_data = data;
context->_thread = CreateThread(NULL, stack_size,
context->_thread = CreateThread(NULL, stack_size,
thread_main, context, 0, NULL);
}
@ -117,7 +116,7 @@ switch_to_thread_context(struct ThreadContext *from_context,
/* We've been rudely terminated. Exit gracefully. */
ExitThread(1);
}
/* Now we have been signaled again, and we're ready to resume the
thread. */
longjmp(from_context->_jmp_context, 1);

View File

@ -54,6 +54,9 @@ public:
INLINE CycleData(const CycleData &copy) = default;
virtual ~CycleData();
CycleData &operator = (CycleData &&from) = default;
CycleData &operator = (const CycleData &copy) = default;
virtual CycleData *make_copy() const=0;
virtual void write_datagram(BamWriter *, Datagram &) const;

View File

@ -45,6 +45,19 @@ CycleDataLockedReader(const CycleDataLockedReader<CycleDataType> &copy) :
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedReader<CycleDataType>::
CycleDataLockedReader(CycleDataLockedReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -61,19 +74,6 @@ operator = (const CycleDataLockedReader<CycleDataType> &copy) {
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedReader<CycleDataType>::
CycleDataLockedReader(CycleDataLockedReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -177,6 +177,18 @@ operator = (const CycleDataLockedReader<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataLockedReader<CycleDataType>::
operator = (CycleDataLockedReader<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
*
*/

View File

@ -47,6 +47,20 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader<CycleDataType> &copy
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer),
_stage(from._stage)
{
from._pointer = nullptr;
}
/**
*
*/
@ -64,20 +78,6 @@ operator = (const CycleDataLockedStageReader<CycleDataType> &copy) {
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer),
_stage(from._stage)
{
from._pointer = nullptr;
}
/**
*
*/
@ -174,6 +174,17 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader<CycleDataType> &copy
{
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_pointer(from._cycler)
{
from._pointer = nullptr;
}
/**
*
*/
@ -183,6 +194,18 @@ operator = (const CycleDataLockedStageReader<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataLockedStageReader<CycleDataType>::
operator = (CycleDataLockedStageReader<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
*
*/

View File

@ -62,23 +62,6 @@ CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy) :
_cycler->increment_write(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (const CycleDataStageWriter<CycleDataType> &copy) {
nassertv(_pointer == nullptr);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
_stage = copy._stage;
nassertv(_pointer != nullptr);
_cycler->increment_write(_pointer);
}
/**
* This flavor of the constructor elevates the pointer from the
* CycleDataLockedStageReader from a read to a write pointer (and invalidates
@ -128,6 +111,23 @@ CycleDataStageWriter(CycleDataStageWriter<CycleDataType> &&from) noexcept :
from._pointer = nullptr;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (const CycleDataStageWriter<CycleDataType> &copy) {
nassertv(_pointer == nullptr);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
_stage = copy._stage;
nassertv(_pointer != nullptr);
_cycler->increment_write(_pointer);
}
/**
*
*/
@ -227,6 +227,17 @@ CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy) :
{
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(CycleDataStageWriter<CycleDataType> &&from) noexcept :
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -236,6 +247,18 @@ operator = (const CycleDataStageWriter<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (CycleDataStageWriter<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
* This flavor of the constructor elevates the pointer from the
* CycleDataLockedStageReader from a read to a write pointer (and invalidates

View File

@ -225,7 +225,7 @@ call_python_func(PyObject *function, PyObject *args) {
} else {
// No exception. Restore the thread state normally.
PyThreadState *state = PyThreadState_Swap(orig_thread_state);
PyThreadState_Swap(orig_thread_state);
thread_states.push_back(new_thread_state);
// PyThreadState_Clear(new_thread_state);
// PyThreadState_Delete(new_thread_state);

View File

@ -51,14 +51,6 @@ is_threading_supported() {
return true;
}
/**
*
*/
INLINE bool ThreadSimpleImpl::
is_true_threads() {
return (is_os_threads != 0);
}
/**
*
*/

View File

@ -141,8 +141,8 @@ start(ThreadPriority priority, bool joinable) {
#ifdef HAVE_PYTHON
// Query the current Python thread state.
_python_state = PyThreadState_Swap(nullptr);
PyThreadState_Swap(_python_state);
_python_state = thread_state_swap(nullptr);
thread_state_swap(_python_state);
#endif // HAVE_PYTHON
init_thread_context(_context, _stack, _stack_size, st_begin_thread, this);
@ -201,6 +201,14 @@ prepare_for_exit() {
manager->prepare_for_exit();
}
/**
*
*/
bool ThreadSimpleImpl::
is_true_threads() {
return (is_os_threads != 0);
}
/**
*
*/
@ -238,7 +246,7 @@ st_begin_thread(void *data) {
void ThreadSimpleImpl::
begin_thread() {
#ifdef HAVE_PYTHON
PyThreadState_Swap(_python_state);
thread_state_swap(_python_state);
#endif // HAVE_PYTHON
#ifdef HAVE_POSIX_THREADS

View File

@ -63,7 +63,7 @@ public:
INLINE static void bind_thread(Thread *thread);
INLINE static bool is_threading_supported();
INLINE static bool is_true_threads();
static bool is_true_threads();
INLINE static bool is_simple_threads();
INLINE static void sleep(double seconds);
INLINE static void yield();

View File

@ -20,7 +20,9 @@
#include "mainThread.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
@ -235,7 +237,7 @@ next_context() {
#ifdef HAVE_PYTHON
// Save the current Python thread state.
_current_thread->_python_state = PyThreadState_Swap(nullptr);
_current_thread->_python_state = thread_state_swap(nullptr);
#endif // HAVE_PYTHON
#ifdef DO_PSTATS
@ -256,7 +258,7 @@ next_context() {
#endif // DO_PSTATS
#ifdef HAVE_PYTHON
PyThreadState_Swap(_current_thread->_python_state);
thread_state_swap(_current_thread->_python_state);
#endif // HAVE_PYTHON
}
@ -468,16 +470,6 @@ init_pointers() {
_pointers_initialized = true;
_global_ptr = new ThreadSimpleManager;
Thread::get_main_thread();
#ifdef HAVE_PYTHON
// Ensure that the Python threading system is initialized and ready to go.
#if PY_VERSION_HEX >= 0x03020000
Py_Initialize();
#endif
PyEval_InitThreads();
#endif
}
}

View File

@ -291,8 +291,8 @@ output(std::ostream &out) const {
*/
void TextNode::
write(std::ostream &out, int indent_level) const {
MutexHolder holder(_lock);
PandaNode::write(out, indent_level);
MutexHolder holder(_lock);
TextProperties::write(out, indent_level + 2);
indent(out, indent_level + 2)
<< "transform is: " << *TransformState::make_mat(_transform) << "\n";

View File

@ -778,9 +778,9 @@ register_twindow_class() {
#define GAMMA_1 (255.0 * 256.0)
static bool _gamma_table_initialized = false;
static unsigned short _orignial_gamma_table [256 * 3];
static unsigned short _original_gamma_table [256 * 3];
void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
void _create_gamma_table_wgl (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
int i;
double gamma_correction;
@ -842,7 +842,7 @@ get_gamma_table(void) {
HDC hdc = GetDC(nullptr);
if (hdc) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _original_gamma_table)) {
_gamma_table_initialized = true;
get = true;
}
@ -867,10 +867,10 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
unsigned short ramp [256 * 3];
if (restore && _gamma_table_initialized) {
_create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_wgl (gamma, &_original_gamma_table [0], &_original_gamma_table [256], &_original_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
}
else {
_create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_wgl (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
}
if (SetDeviceGammaRamp (hdc, ramp)) {

View File

@ -293,13 +293,29 @@ set_properties_now(WindowProperties &properties) {
_properties.set_fixed_size(properties.get_fixed_size());
properties.clear_fixed_size();
}
// When switching undecorated mode, Windows will keep the window at the
// current outer size, whereas we want to keep it with the configured
// inner size. Store the current size and origin.
LPoint2i top_left = _properties.get_origin();
LPoint2i bottom_right = top_left + _properties.get_size();
DWORD window_style = make_style(_properties);
SetWindowLong(_hWnd, GWL_STYLE, window_style);
// Now calculate the proper size and origin with the new window style.
RECT view_rect;
SetRect(&view_rect, top_left[0], top_left[1],
bottom_right[0], bottom_right[1]);
WINDOWINFO wi;
GetWindowInfo(_hWnd, &wi);
AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
// We need to call this to ensure that the style change takes effect.
SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE |
SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
view_rect.right - view_rect.left,
view_rect.bottom - view_rect.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
}
if (properties.has_title()) {

View File

@ -13,6 +13,8 @@
#include "eggBackPointer.h"
#include "pnotify.h"
TypeHandle EggBackPointer::_type_handle;

View File

@ -29,6 +29,7 @@
*/
class EggJointPointer;
class LMatrix4d;
/**
* This class is used during joint optimization or restructuring to store the

View File

@ -12,6 +12,8 @@
*/
#include "eggJointData.h"
#include "eggCharacterDb.h"
#include "eggJointNodePointer.h"
#include "eggMatrixTablePointer.h"
#include "pvector.h"

View File

@ -14,8 +14,9 @@
#include "eggJointNodePointer.h"
#include "dcast.h"
#include "eggObject.h"
#include "eggCharacterDb.h"
#include "eggGroup.h"
#include "eggObject.h"
#include "pointerTo.h"

View File

@ -12,7 +12,9 @@
*/
#include "eggMatrixTablePointer.h"
#include "dcast.h"
#include "eggCharacterDb.h"
#include "eggSAnimData.h"
#include "eggXfmAnimData.h"
#include "eggXfmSAnim.h"

View File

@ -17,6 +17,7 @@
#include "textureImage.h"
#include "palettizer.h"
#include "paletteImage.h"
#include "sourceTextureImage.h"
#include "indent.h"
#include "datagram.h"

View File

@ -1,55 +0,0 @@
/**
* 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 config_softegg.cxx
* @author masad
* @date 2003-09-25
*/
#include "config_softegg.h"
#include "softEggGroupUserData.h"
#include "softNodeDesc.h"
#include "dconfig.h"
Configure(config_softegg);
NotifyCategoryDef(softegg, ":soft");
ConfigureFn(config_softegg) {
init_libsoftegg();
}
// These control the default behavior of the softegg converter, but not
// necessarily the default behavior of the soft2egg command-line tool (which
// has its own defaults).
// Should we respect the Soft? double-sided flag (true) or ignore it and
// assume everything is single-sided (false)?
ConfigVariableBool soft_default_double_sided("soft-default-double-sided", false);
// Should we apply vertex color even when a texture is applied (true) or only
// when no texture is applied or the vertex-color egg flag is set (false)?
ConfigVariableBool soft_default_vertex_color("soft-default-vertex-color", true);
/**
* 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_libsoftegg() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
SoftEggGroupUserData::init_type();
SoftNodeDesc::init_type();
}

View File

@ -1,28 +0,0 @@
/**
* 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 config_softegg.h
* @author masad
* @date 2003-09-25
*/
#ifndef CONFIG_SOFTEGG_H
#define CONFIG_SOFTEGG_H
#include "pandatoolbase.h"
#include "notifyCategoryProxy.h"
#include "configVariableBool.h"
NotifyCategoryDeclNoExport(softegg);
extern ConfigVariableBool soft_default_double_sided;
extern ConfigVariableBool soft_default_vertex_color;
extern void init_libsoftegg();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
/**
* 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 softEggGroupUserData.I
* @author masad
* @date 2003-09-25
*/
/**
*
*/
INLINE SoftEggGroupUserData::
SoftEggGroupUserData() {
_vertex_color = false;
_double_sided = false;
}
/**
*
*/
INLINE SoftEggGroupUserData::
SoftEggGroupUserData(const SoftEggGroupUserData &copy) :
EggUserData(copy),
_vertex_color(copy._vertex_color),
_double_sided(copy._double_sided)
{
}
/**
*
*/
INLINE void SoftEggGroupUserData::
operator = (const SoftEggGroupUserData &copy) {
EggUserData::operator = (copy);
_vertex_color = copy._vertex_color;
_double_sided = copy._double_sided;
}

View File

@ -1,16 +0,0 @@
/**
* 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 softEggGroupUserData.cxx
* @author masad
* @date 2003-09-25
*/
#include "softEggGroupUserData.h"
TypeHandle SoftEggGroupUserData::_type_handle;

View File

@ -1,53 +0,0 @@
/**
* 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 softEggGroupUserData.h
* @author masad
* @date 2003-09-25
*/
#ifndef SOFTEGGGROUPUSERDATA_H
#define SOFTEGGGROUPUSERDATA_H
#include "pandatoolbase.h"
#include "eggUserData.h"
/**
* This class contains extra user data which is piggybacked onto EggGroup
* objects for the purpose of the softimage converter.
*/
class SoftEggGroupUserData : public EggUserData {
public:
INLINE SoftEggGroupUserData();
INLINE SoftEggGroupUserData(const SoftEggGroupUserData &copy);
INLINE void operator = (const SoftEggGroupUserData &copy);
bool _vertex_color;
bool _double_sided;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggUserData::init_type();
register_type(_type_handle, "SoftEggGroupUserData",
EggUserData::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;
};
#include "softEggGroupUserData.I"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,159 +0,0 @@
/**
* 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 softNodeDesc.h
* @author masad
* @date 2003-10-03
*/
#ifndef SOFTNODEDESC_H
#define SOFTNODEDESC_H
#ifdef _MIN
#undef _MIN
#endif
#ifdef _MAX
#undef _MAX
#endif
#include "pandatoolbase.h"
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "referenceCount.h"
#include "pointerTo.h"
#include "namable.h"
#include <SAA.h>
class EggGroup;
class EggTable;
class EggXfmSAnim;
/**
* Describes a single instance of a node aka element in the Soft scene graph,
* relating it to the corresponding egg structures (e.g. node, group, or
* table entry) that will be created.
*/
class SoftNodeDesc : public ReferenceCount, public Namable {
public:
SoftNodeDesc(SoftNodeDesc *parent=nullptr, const std::string &name = std::string());
~SoftNodeDesc();
void set_parent(SoftNodeDesc *parent);
void force_set_parent(SoftNodeDesc *parent);
void set_model(SAA_Elem *model);
bool has_model() const;
SAA_Elem *get_model() const;
bool is_joint() const;
bool is_junk() const;
void set_joint();
bool is_joint_parent() const;
bool is_partial(char *search_prefix);
SoftNodeDesc *_parent;
SoftNodeDesc *_parentJoint; // keep track of who is your parent joint
typedef pvector< PT(SoftNodeDesc) > Children;
Children _children;
private:
void clear_egg();
void mark_joint_parent();
void check_joint_parent();
void check_junk(bool parent_junk);
void check_pseudo_joints(bool joint_above);
void set_parentJoint(SAA_Scene *scene, SoftNodeDesc *lastJoint);
SAA_ModelType type;
SAA_Elem *_model;
EggGroup *_egg_group;
EggTable *_egg_table;
EggXfmSAnim *_anim;
enum JointType {
JT_none, // Not a joint.
JT_joint, // An actual joint in Soft.
JT_pseudo_joint, // Not a joint in Soft, but treated just like a
// joint for the purposes of the converter.
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
JT_junk, // originated from con-/fly-/car_rig/bars etc.
};
JointType _joint_type;
public:
char **texNameArray;
int *uRepeat, *vRepeat;
PN_stdfloat matrix[4][4];
const char *fullname;
int numTri;
// int numShapes;
int numTexLoc;
int numTexGlb;
int *numTexTri;
// if the node is a MNSRF
int numNurbTexLoc;
int numNurbTexGlb;
int numNurbMats;
PN_stdfloat *uScale;
PN_stdfloat *vScale;
PN_stdfloat *uOffset;
PN_stdfloat *vOffset;
SAA_Boolean valid;
SAA_Boolean uv_swap;
// SAA_Boolean visible;
SAA_Elem *textures;
SAA_Elem *materials;
SAA_SubElem *triangles;
SAA_GeomType gtype;
EggGroup *get_egg_group()const {return _egg_group;}
void get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global);
void get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global);
void load_poly_model(SAA_Scene *scene, SAA_ModelType type);
void load_nurbs_model(SAA_Scene *scene, SAA_ModelType type);
void make_morph_table(PN_stdfloat time);
void make_linear_morph_table(int numShapes, PN_stdfloat time);
void make_weighted_morph_table(int numShapes, PN_stdfloat time);
void make_expression_morph_table(int numShapes, PN_stdfloat time);
void make_vertex_offsets(int numShapes);
int find_shape_vert(LPoint3d p3d, SAA_DVector *vertices, int numVert);
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ReferenceCount::init_type();
Namable::init_type();
register_type(_type_handle, "SoftNodeDesc",
ReferenceCount::get_class_type(),
Namable::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class SoftNodeTree;
};
class SoftToEggConverter;
extern SoftToEggConverter stec;
#endif

View File

@ -1,561 +0,0 @@
/**
* 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 softNodeTree.cxx
* @author masad
* @date 2003-09-26
*/
// Includes
#include "softNodeTree.h"
#include "softEggGroupUserData.h"
#include "config_softegg.h"
#include "eggGroup.h"
#include "eggTable.h"
#include "eggXfmSAnim.h"
#include "eggData.h"
#include "softToEggConverter.h"
#include "dcast.h"
#include <SAA.h>
using std::endl;
/**
*
*/
SoftNodeTree::
SoftNodeTree() {
_root = new SoftNodeDesc(nullptr, "----root");
_root->fullname = "----root";
_fps = 0.0;
_use_prefix = 0;
_search_prefix = nullptr;
_egg_data = nullptr;
_egg_root = nullptr;
_skeleton_node = nullptr;
}
/**
* Given an element, return a copy of the element's name WITHOUT prefix.
*/
char *SoftNodeTree::
GetName( SAA_Scene *scene, SAA_Elem *element ) {
int nameLen;
char *name;
// get the name
SAA_elementGetNameLength( scene, element, &nameLen );
name = new char[++nameLen];
SAA_elementGetName( scene, element, nameLen, name );
return name;
}
/**
* Given an element, return a copy of the element's name complete with prefix.
*/
char *SoftNodeTree::
GetFullName( SAA_Scene *scene, SAA_Elem *element )
{
int nameLen, prefixLen;
char *name, *prefix;
// get the name length
SAA_elementGetNameLength( scene, element, &nameLen );
// get the prefix length
SAA_elementGetPrefixLength( scene, element, &prefixLen );
// allocate the array to hold name
name = new char[++nameLen];
// allocate the array to hold prefix and length + hyphen
prefix = new char[++prefixLen + nameLen + 4];
// get the name
SAA_elementGetName( scene, element, nameLen, name );
// get the prefix
SAA_elementGetPrefix( scene, element, prefixLen, prefix );
// add 'em together
strcat(prefix, "-");
strcat(prefix, name);
// return string
return prefix;
}
/**
* Given an element, return a string containing the contents of its MODEL NOTE
* entry
*/
char *SoftNodeTree::
GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) {
int size;
char *modelNote = nullptr;
SAA_Boolean bigEndian;
SAA_elementGetUserDataSize( scene, model, "MNOT", &size );
if ( size != 0 ) {
// allocate modelNote string
modelNote = new char[size + 1];
// get ModelNote data from this model
SAA_elementGetUserData( scene, model, "MNOT", size,
&bigEndian, (void *)modelNote );
// strip off newline, if present
char *eol = (char *)memchr( modelNote, '\n', size );
if ( eol != nullptr)
*eol = '\0';
else
modelNote[size] = '\0';
softegg_cat.spam() << "\nmodelNote = " << modelNote << endl;
}
return modelNote;
}
/**
* Given a string, return a copy of the string up to the first occurence of
* '-'.
*/
char *SoftNodeTree::
GetRootName( const char *name ) {
const char *hyphen;
char *root;
int len;
hyphen = strchr( name, '-' );
len = hyphen-name;
if ( (hyphen != nullptr) && len ) {
root = new char[len+1];
strncpy( root, name, len );
root[len] = '\0';
}
else {
root = new char[strlen(name)+1];
strcpy( root, name );
}
return( root );
}
/**
* Walks through the complete Soft hierarchy and builds up the corresponding
* tree.
*/
bool SoftNodeTree::
build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
SI_Error status;
SoftNodeDesc *node;
// Get the entire Soft scene.
int numModels;
SAA_Elem *models;
SAA_sceneGetNbModels( &scene, &numModels );
softegg_cat.spam() << "Scene has " << numModels << " model(s)...\n";
// This while loop walks through the entire Soft hierarchy, one node at a
// time.
bool all_ok = true;
if ( numModels ) {
// allocate array of models
models = (SAA_Elem *) new SAA_Elem[numModels];
if ( models != nullptr ) {
if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
return false;
}
for ( int i = 0; i < numModels; i++ ) {
int level;
status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
softegg_cat.spam() << "model[" << i << "]" << endl;
softegg_cat.spam() << " level " << level << endl;
softegg_cat.spam() << " status is " << status << "\n";
node = build_node(&scene, &models[i]);
if (!level && node)
node->set_parent(_root);
}
}
}
softegg_cat.spam() << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj\n";
// check the nodes that are junk for animationartist control purposes
_root->check_junk(false);
softegg_cat.spam() << "jpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjp\n";
// check the nodes that are parent of ancestors of a joint
_root->check_joint_parent();
softegg_cat.spam() << "pppppppppppppppppppppppppppppppppppppppppppppppppppppppp\n";
// check the nodes that are pseudo joints
_root->check_pseudo_joints(false);
softegg_cat.spam() << "========================================================\n";
// find _parentJoint for each node
_root->set_parentJoint(&scene, nullptr);
return all_ok;
}
#if 0
/**
* Walks through the selected subset of the Soft hierarchy (or the complete
* hierarchy, if nothing is selected) and builds up the corresponding tree.
*/
bool SoftNodeTree::
build_selected_hierarchy(char *scene_name) {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
return false;
}
// Get only the selected geometry.
MSelectionList selection;
status = MGlobal::getActiveSelectionList(selection);
if (!status) {
status.perror("MGlobal::getActiveSelectionList");
return false;
}
// Get the selected geometry only if the selection is nonempty; otherwise,
// get the whole scene anyway.
if (selection.isEmpty()) {
softegg_cat.info()
<< "Selection list is empty.\n";
return build_complete_hierarchy();
}
bool all_ok = true;
unsigned int length = selection.length();
for (unsigned int i = 0; i < length; i++) {
MDagPath root_path;
status = selection.getDagPath(i, root_path);
if (!status) {
status.perror("MSelectionList::getDagPath");
} else {
// Now traverse through the selected dag path and all nested dag paths.
dag_iterator.reset(root_path);
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
} else {
build_node(dag_path);
}
dag_iterator.next();
}
}
}
if (all_ok) {
_root->check_pseudo_joints(false);
}
return all_ok;
}
#endif
/**
* Returns the total number of nodes in the hierarchy, not counting the root
* node.
*/
int SoftNodeTree::
get_num_nodes() const {
return _nodes.size();
}
/**
* Returns the nth node in the hierarchy, in an arbitrary ordering.
*/
SoftNodeDesc *SoftNodeTree::
get_node(int n) const {
nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
return _nodes[n];
}
/**
* Returns the node named 'name' in the hierarchy, in an arbitrary ordering.
*/
SoftNodeDesc *SoftNodeTree::
get_node(std::string name) const {
NodesByName::const_iterator ni = _nodes_by_name.find(name);
if (ni != _nodes_by_name.end())
return (*ni).second;
return nullptr;
}
/**
* Removes all of the references to generated egg structures from the tree,
* and prepares the tree for generating new egg structures.
*/
void SoftNodeTree::
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
EggGroupNode *skeleton_node) {
_root->clear_egg();
_egg_data = egg_data;
_egg_root = egg_root;
_skeleton_node = skeleton_node;
}
/**
* Returns the EggGroupNode corresponding to the group or joint for the
* indicated node. Creates the group node if it has not already been created.
*/
EggGroup *SoftNodeTree::
get_egg_group(SoftNodeDesc *node_desc) {
nassertr(_egg_root != nullptr, nullptr);
// lets print some relationship
softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
if (node_desc->_parent)
softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
else
softegg_cat.spam() << " parent " << node_desc->_parent;
softegg_cat.spam() << endl;
if (node_desc->_egg_group == nullptr) {
// We need to make a new group node.
EggGroup *egg_group;
egg_group = new EggGroup(node_desc->get_name());
if (node_desc->is_joint()) {
egg_group->set_group_type(EggGroup::GT_joint);
}
if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
// The parent is the root.
softegg_cat.spam() << "came hereeeee\n";
_egg_root->add_child(egg_group);
} else {
// The parent is another node.
EggGroup *parent_egg_group = get_egg_group(node_desc->_parentJoint);
parent_egg_group->add_child(egg_group);
}
node_desc->_egg_group = egg_group;
}
return node_desc->_egg_group;
}
/**
* Returns the EggTable corresponding to the joint for the indicated node.
* Creates the table node if it has not already been created.
*/
EggTable *SoftNodeTree::
get_egg_table(SoftNodeDesc *node_desc) {
nassertr(_skeleton_node != nullptr, nullptr);
nassertr(node_desc->is_joint(), nullptr);
// lets print some relationship
softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
if (node_desc->_parent)
softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
else
softegg_cat.spam() << " parent " << node_desc->_parent;
softegg_cat.spam() << endl;
if (node_desc->_egg_table == nullptr) {
softegg_cat.spam() << "creating a new table\n";
// We need to make a new table node. nassertr(node_desc->_parent !=
// (SoftNodeDesc *)NULL, NULL);
EggTable *egg_table = new EggTable(node_desc->get_name());
node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
node_desc->_anim->set_fps(_fps);
egg_table->add_child(node_desc->_anim);
if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
// if (!node_desc->_parent->is_joint()) { The parent is not a joint; put
// it at the top.
_skeleton_node->add_child(egg_table);
} else {
// The parent is another joint.
EggTable *parent_egg_table = get_egg_table(node_desc->_parentJoint);
parent_egg_table->add_child(egg_table);
}
node_desc->_egg_table = egg_table;
}
return node_desc->_egg_table;
}
/**
* Returns the anim table corresponding to the joint for the indicated node.
* Creates the table node if it has not already been created.
*/
EggXfmSAnim *SoftNodeTree::
get_egg_anim(SoftNodeDesc *node_desc) {
get_egg_table(node_desc);
return node_desc->_anim;
}
/**
* Sets joint information for MNILL node
*/
void SoftNodeTree::
handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name) {
const char *name = node_name;
SAA_AlgorithmType algo;
SAA_Elem *model = node_desc->get_model();
SAA_modelGetAlgorithm( scene, model, &algo );
softegg_cat.spam() << " null algorithm: " << algo << endl;
if ( algo == SAA_ALG_INV_KIN ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
softegg_cat.spam() << " encountered IK root: " << name << endl;
}
else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
softegg_cat.spam() << " encountered IK leaf: " << name << endl;
}
else if ( algo == SAA_ALG_STANDARD ) {
SAA_Boolean isSkeleton = FALSE;
softegg_cat.spam() << " encountered Standard null: " << name << endl;
SAA_modelIsSkeleton( scene, model, &isSkeleton );
// check to see if this NULL is used as a skeleton or is animated via
// constraint only ( these nodes are tagged by the animator with the
// keyword "joint" somewhere in the nodes name)
if ( isSkeleton || (strstr( name, "joint" ) != nullptr) ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
softegg_cat.spam() << " animating Standard null!!!\n";
softegg_cat.spam() << "isSkeleton: " << isSkeleton << endl;
}
}
else
softegg_cat.spam() << " encountered some other NULL: " << algo << endl;
}
/**
* Returns a pointer to the node corresponding to the indicated dag_path
* object, creating it first if necessary.
*/
SoftNodeDesc *SoftNodeTree::
build_node(SAA_Scene *scene, SAA_Elem *model) {
char *name, *fullname;
std::string node_name;
int numChildren;
int thisChild;
SAA_Elem *children;
SAA_ModelType type;
SAA_Boolean isSkeleton = FALSE;
fullname = GetFullName(scene, model);
if (_use_prefix)
name = fullname;
else
name = GetName(scene, model);
node_name = name;
SoftNodeDesc *node_desc = r_build_node(nullptr, node_name);
node_desc->fullname = fullname;
node_desc->set_model(model);
SAA_modelIsSkeleton( scene, model, &isSkeleton );
// find out what type of node we're dealing with
SAA_modelGetType( scene, node_desc->get_model(), &type );
if (type == SAA_MJNT || isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != nullptr))
node_desc->set_joint();
// treat the MNILL differently, because it needs to detect and set some
// joints
if (type == SAA_MNILL)
handle_null(scene, node_desc, name);
if (node_desc->is_joint())
softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
// get to the children
SAA_modelGetNbChildren( scene, model, &numChildren );
softegg_cat.spam() << " Model " << node_name << " children: " << numChildren << endl;
if ( numChildren ) {
children = new SAA_Elem[numChildren];
SAA_modelGetChildren( scene, model, numChildren, children );
if (!children)
softegg_cat.info() << "Not enough Memory for children...\n";
for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
fullname = GetFullName(scene, &children[thisChild]);
if (_use_prefix)
node_name = fullname;
else
node_name = GetName(scene, &children[thisChild]);
softegg_cat.spam() << " building child " << thisChild << "...";
SoftNodeDesc *node_child = r_build_node(node_desc, node_name);
node_child->fullname = fullname;
node_child->set_model(&children[thisChild]);
SAA_modelIsSkeleton( scene, &children[thisChild], &isSkeleton );
// find out what type of node we're dealing with
SAA_modelGetType( scene, node_child->get_model(), &type );
if (type == SAA_MJNT || isSkeleton || (strstr(node_child->get_name().c_str(), "joint") != nullptr))
node_child->set_joint();
// treat the MNILL differently, because it needs to detect and set some
// joints
if (type == SAA_MNILL)
handle_null(scene, node_child, node_name.c_str());
if (node_child->is_joint())
softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
}
}
return node_desc;
}
/**
* The recursive implementation of build_node().
*/
SoftNodeDesc *SoftNodeTree::
r_build_node(SoftNodeDesc *parent_node, const std::string &name) {
SoftNodeDesc *node_desc;
// If we have already encountered this pathname, return the corresponding
// SoftNodeDesc immediately.
NodesByName::const_iterator ni = _nodes_by_name.find(name);
if (ni != _nodes_by_name.end()) {
softegg_cat.spam() << " already built node " << (*ni).first;
node_desc = (*ni).second;
node_desc->set_parent(parent_node);
return node_desc;
}
// Otherwise, we have to create it. Do this recursively, so we create each
// node along the path.
node_desc = new SoftNodeDesc(parent_node, name);
softegg_cat.spam() << " node name : " << name << endl;
_nodes.push_back(node_desc);
_nodes_by_name.insert(NodesByName::value_type(name, node_desc));
return node_desc;
}

View File

@ -1,78 +0,0 @@
/**
* 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 softNodeTree.h
* @author masad
* @date 2003-10-03
*/
#ifndef SOFTNODETREE_H
#define SOFTNODETREE_H
#include "pandatoolbase.h"
#include "softNodeDesc.h"
#include <SAA.h>
class EggGroup;
class EggTable;
class EggXfmSAnim;
class EggData;
class EggGroupNode;
/**
* Describes a complete tree of soft nodes for conversion.
*/
class SoftNodeTree {
public:
SoftNodeTree();
SoftNodeDesc *build_node(SAA_Scene *scene, SAA_Elem *model);
bool build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database);
void handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name);
// bool build_selected_hierarchy(SAA_Scene *s, SAA_Database *d, char
// *scene_name);
int get_num_nodes() const;
SoftNodeDesc *get_node(int n) const;
SoftNodeDesc *get_node(std::string name) const;
char *GetRootName(const char *);
char *GetModelNoteInfo(SAA_Scene *, SAA_Elem *);
char *GetName(SAA_Scene *scene, SAA_Elem *element);
char *GetFullName(SAA_Scene *scene, SAA_Elem *element);
EggGroupNode *get_egg_root() {return _egg_root;}
EggGroup *get_egg_group(SoftNodeDesc *node_desc);
EggTable *get_egg_table(SoftNodeDesc *node_desc);
EggXfmSAnim *get_egg_anim(SoftNodeDesc *node_desc);
void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node);
PT(SoftNodeDesc) _root;
PN_stdfloat _fps;
int _use_prefix;
char *_search_prefix;
private:
EggData *_egg_data;
EggGroupNode *_egg_root;
EggGroupNode *_skeleton_node;
SoftNodeDesc *r_build_node(SoftNodeDesc *parent_node, const std::string &path);
typedef pmap<std::string, SoftNodeDesc *> NodesByName;
NodesByName _nodes_by_name;
typedef pvector<SoftNodeDesc *> Nodes;
Nodes _nodes;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +0,0 @@
/**
* 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 softToEggConverter.h
* @author masad
* @date 2003-09-25
*/
#ifndef SOFTTOEGGCONVERTER_H
#define SOFTTOEGGCONVERTER_H
#include "pandatoolbase.h"
#include "somethingToEggConverter.h"
#include "softNodeTree.h"
#include "eggTextureCollection.h"
#include "distanceUnit.h"
#include "coordinateSystem.h"
#ifdef _MIN
#undef _MIN
#endif
#ifdef _MAX
#undef _MAX
#endif
#include <SAA.h>
#include <SI_macros.h>
class EggData;
class EggGroup;
class EggTable;
class EggVertexPool;
class EggNurbsCurve;
class EggPrimitive;
class EggXfmSAnim;
class EggSAnimData;
/**
* This class supervises the construction of an EggData structure from a
* single Softimage file, or from the data already in th cout << "egg name
* = " << eggFilename << endl;e global Softimage model space.
*
*/
class SoftToEggConverter : public SomethingToEggConverter {
public:
SoftToEggConverter(const std::string &program_name = "");
SoftToEggConverter(const SoftToEggConverter &copy);
virtual ~SoftToEggConverter();
void Help();
void Usage();
void ShowOpts();
bool HandleGetopts(int &idx, int argc, char **argv);
bool DoGetopts(int &argc, char **&argv);
SoftNodeDesc *find_node(std::string name);
int *FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert );
virtual SomethingToEggConverter *make_copy();
virtual std::string get_name() const;
virtual std::string get_extension() const;
virtual bool convert_file(const Filename &filename);
bool convert_soft(bool from_selection);
bool open_api();
void close_api();
private:
bool convert_flip(double start_frame, double end_frame,
double frame_inc, double output_frame_rate);
bool make_soft_skin();
bool cleanup_soft_skin();
bool convert_char_chan();
bool convert_char_model();
bool convert_hierarchy(EggGroupNode *egg_root);
bool process_model_node(SoftNodeDesc *node_desc);
void make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
void make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
void add_knots( vector <double> &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree );
void set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, int idx);
void apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat);
bool reparent_decals(EggGroupNode *egg_parent);
std::string _program_name;
bool _from_selection;
SI_Error result;
SAA_Elem model;
SAA_Database database;
public:
SoftNodeTree _tree;
SAA_Scene scene;
char *_getopts;
// This is argv[0].
const char *_commandName;
// This is the entire command line.
char _commandLine[4096];
char *rsrc_path;
char *database_name;
char *scene_name;
char *model_name;
char *eggFileName;
char *animFileName;
char *eggGroupName;
char *tex_path;
char *tex_filename;
char *search_prefix;
int nurbs_step;
int anim_start;
int anim_end;
int anim_rate;
int pose_frame;
int verbose;
int flatten;
int shift_textures;
int ignore_tex_offsets;
int use_prefix;
bool foundRoot;
bool geom_as_joint;
bool make_anim;
bool make_nurbs;
bool make_poly;
bool make_soft;
bool make_morph;
bool make_duv;
bool make_dart;
bool has_morph;
bool make_pose;
char *GetTextureName( SAA_Scene *scene, SAA_Elem *texture );
EggTextureCollection _textures;
bool _polygon_output;
double _polygon_tolerance;
enum TransformType {
TT_invalid,
TT_all,
TT_model,
TT_dcs,
TT_none,
};
TransformType _transform_type;
static TransformType string_transform_type(const std::string &arg);
typedef pvector<EggSAnimData *> MorphTable;
MorphTable _morph_table;
EggTable *morph_node;
EggSAnimData *find_morph_table(char *name);
};
extern const int TEX_PER_MAT;
#endif

View File

@ -1,588 +0,0 @@
/**
* 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 softCVS.cxx
* @author drose
* @date 2000-11-10
*/
#include "softCVS.h"
#include "pnotify.h"
#include "multifile.h"
#include <algorithm>
using std::string;
/**
*
*/
SoftCVS::
SoftCVS() {
_cvs_binary = "cvs";
set_program_brief("prepare a SoftImage database directory for adding to CVS");
set_program_description
("softcvs is designed to prepare a directory hierarchy "
"representing a SoftImage database for adding to CVS. "
"First, it eliminates SoftImage's silly filename-based "
"versioning system by renaming versioned filenames higher "
"than 1-0 back to version 1-0. Then, it rolls up all the "
"files for each scene except the texture images into a Panda "
"multifile, which is added to CVS; the texture images are "
"directly added to CVS where they are.\n\n"
"The reduction of hundreds of SoftImage files per scene down to one "
"multifile and a handle of texture images should greatly improve "
"the update and commit times of CVS.\n\n"
"You must run this from within the root of a SoftImage database "
"directory; e.g. the directory that contains SCENES, PICTURES, MODELS, "
"and so on.");
clear_runlines();
add_runline("[opts]");
add_option
("nc", "", 80,
"Do not attempt to add newly-created files to CVS. The default "
"is to add them.",
&SoftCVS::dispatch_none, &_no_cvs);
add_option
("cvs", "cvs_binary", 80,
"Specify how to run the cvs program for adding newly-created files. "
"The default is simply \"cvs\".",
&SoftCVS::dispatch_string, nullptr, &_cvs_binary);
}
/**
*
*/
void SoftCVS::
run() {
// First, check for the scenes directory. If it doesn't exist, we must not
// be in the root of a soft database.
Filename scenes = "SCENES/.";
if (!scenes.exists()) {
nout << "No SCENES directory found; you are not in the root of a "
"SoftImage database.\n";
exit(1);
}
// Also, if we're expecting to use CVS, make sure the CVS directory exists.
Filename cvs_entries = "CVS/Entries";
if (!_no_cvs && !cvs_entries.exists()) {
nout << "You do not appear to be within a CVS-controlled source "
"directory.\n";
exit(1);
}
// Scan all the files in the database.
traverse_root();
// Collapse out the higher-versioned scene files.
collapse_scene_files();
// Now determine which element files are actually referenced by at least one
// of the scene files.
if (!get_scenes()) {
exit(1);
}
// Finally, remove all the element files that are no longer referenced by
// any scenes.
remove_unused_elements();
// Now do all the cvs adding and removing we need.
if (!_no_cvs) {
cvs_add_or_remove("remove", _cvs_remove);
cvs_add_or_remove("add -kb", _cvs_add);
}
}
/**
* Reads all of the toplevel directory names, e.g. SCENES, MATERIALS, etc.,
* and traverses them.
*/
void SoftCVS::
traverse_root() {
Filename root(".");
// Get the list of subdirectories.
vector_string subdirs;
if (!root.scan_directory(subdirs)) {
nout << "Unable to scan directory.\n";
return;
}
vector_string::const_iterator di;
for (di = subdirs.begin(); di != subdirs.end(); ++di) {
Filename subdir = (*di);
if (subdir.is_directory() && subdir != "CVS") {
traverse_subdir(subdir);
}
}
}
/**
* Reads the directory indicated by prefix and identifies all of the SoftImage
* files stored there.
*/
void SoftCVS::
traverse_subdir(const Filename &directory) {
// Get the list of files in the directory.
vector_string files;
if (!directory.scan_directory(files)) {
nout << "Unable to scan directory " << directory << "\n";
return;
}
// We need to know the set of files in this directory that are CVS elements.
pset<string> cvs_elements;
bool in_cvs = false;
if (!_no_cvs) {
in_cvs = scan_cvs(directory, cvs_elements);
}
bool is_scenes = false;
bool keep_all = false;
bool wants_cvs = false;
// Now make some special-case behavior based on the particular SoftImage
// subdirectory we're in.
string dirname = directory.get_basename();
if (dirname == "SCENES") {
is_scenes = true;
} else if (dirname == "CAMERAS") {
// We don't want anything in the cameras directory. These may change
// arbitrarily and have no bearing on the model or animation that we will
// extract, so avoid them altogether.
return;
} else if (dirname == "PICTURES") {
// In the pictures directory, we must keep everything, since the scene
// files don't explicitly reference these but they're still important.
// Textures that are no longer used will pile up; we leave this as the
// user's problem.
// We not only keep the textures, but we also move them into CVS, since
// (again) they're not part of the scene files and thus won't get added to
// the multifiles. Also, some textures are shared between different
// scenes, and it would be wasteful to add them to each scene multifile;
// furthermore, some scenes are used for animation only, and we don't want
// to modify these multifiles when the textures change.
keep_all = true;
wants_cvs = !_no_cvs;
}
vector_string::const_iterator fi;
for (fi = files.begin(); fi != files.end(); ++fi) {
const string &filename = (*fi);
if (filename == "CVS") {
// This special filename is not to be considered.
} else if (filename == "Chapter.rsrc") {
// This special filename should not be considered, except to add it to
// the multifiles.
_global_files.push_back(Filename(directory, filename));
} else {
SoftFilename soft(directory, filename);
if (cvs_elements.count(filename) != 0) {
// This file is known to be in CVS.
soft.set_in_cvs(true);
}
if (keep_all) {
soft.increment_use_count();
}
if (wants_cvs && !in_cvs) {
// Try to CVSify the directory.
cvs_add(directory);
in_cvs = true;
}
soft.set_wants_cvs(wants_cvs);
if (is_scenes && soft.has_version() && soft.get_extension() == ".dsc") {
_scene_files.push_back(soft);
} else {
_element_files.insert(soft);
}
}
}
}
/**
* Walks through the list of scene files found, and renames the higher-
* versioned ones to version 1-0, removing the intervening versions.
*/
void SoftCVS::
collapse_scene_files() {
// Get a copy of the scene files vector so we can modify it. Also empty out
// the _scene_files at the same time so we can fill it up again.
SceneFiles versions;
versions.swap(_scene_files);
// And sort them into order so we can easily compare higher and lower
// versions.
sort(versions.begin(), versions.end());
SceneFiles::iterator vi;
vi = versions.begin();
while (vi != versions.end()) {
SoftFilename &file = (*vi);
if (!file.is_1_0()) {
// Here's a file that needs to be renamed. But first, identify all the
// other versions of the same file.
SceneFiles::iterator start_vi;
start_vi = vi;
while (vi != versions.end() && (*vi).is_same_file(file)) {
++vi;
}
rename_file(start_vi, vi);
} else {
++vi;
}
file.make_1_0();
_scene_files.push_back(file);
}
}
/**
* Walks through the list of scene files and looks for the set of element
* files referenced by each one, updating multifile accordingly.
*/
bool SoftCVS::
get_scenes() {
bool okflag = true;
// We will be added the multifiles to CVS if they're not already added, so
// we have to know which files are in CVS already.
pset<string> cvs_elements;
if (!_no_cvs) {
scan_cvs(".", cvs_elements);
}
SceneFiles::const_iterator vi;
for (vi = _scene_files.begin(); vi != _scene_files.end(); ++vi) {
const SoftFilename &sf = (*vi);
Filename file(sf.get_dirname(), sf.get_filename());
file.set_text();
std::ifstream in;
if (!file.open_read(in)) {
nout << "Unable to read " << file << "\n";
} else {
nout << "Scanning " << file << "\n";
Multifile multifile;
Filename multifile_name = sf.get_base() + "mf";
if (!multifile.open_read_write(multifile_name)) {
nout << "Unable to open " << multifile_name << " for updating.\n";
okflag = false;
} else {
if (!scan_scene_file(in, multifile)) {
okflag = false;
}
// Add all the global files to the multifile too. These probably
// can't take compression (since in SoftImage they're just the
// Chapter.rsrc files, each very tiny).
vector_string::const_iterator gi;
for (gi = _global_files.begin(); gi != _global_files.end(); ++gi) {
if (multifile.update_subfile((*gi), (*gi), 0).empty()) {
nout << "Unable to add " << (*gi) << "\n";
okflag = false;
}
}
// Also add the scene file itself.
if (multifile.update_subfile(file, file, 6).empty()) {
nout << "Unable to add " << file << "\n";
okflag = false;
}
bool flushed = false;
if (multifile.needs_repack()) {
flushed = multifile.repack();
} else {
flushed = multifile.flush();
}
if (!flushed) {
nout << "Failed to write " << multifile_name << ".\n";
okflag = false;
} else {
nout << "Wrote " << multifile_name << ".\n";
if (!_no_cvs && cvs_elements.count(multifile_name) == 0) {
// Add the multifile to CVS.
_cvs_add.push_back(multifile_name);
}
}
}
}
}
return okflag;
}
/**
* Remove all the element files that weren't referenced by any scene file.
* Also plan to cvs add all those that were referenced.
*/
void SoftCVS::
remove_unused_elements() {
ElementFiles::const_iterator fi;
for (fi = _element_files.begin(); fi != _element_files.end(); ++fi) {
const SoftFilename &sf = (*fi);
Filename file(sf.get_dirname(), sf.get_filename());
if (sf.get_use_count() == 0) {
nout << file << " is unused.\n";
if (!file.unlink()) {
nout << "Unable to remove " << file << ".\n";
} else if (sf.get_in_cvs()) {
_cvs_remove.push_back(file);
}
} else if (sf.get_wants_cvs() && !sf.get_in_cvs()) {
_cvs_add.push_back(file);
}
}
}
/**
* Renames the first file in the indicated list to a version 1-0 filename,
* superceding all the other files in the list. Returns true if the file is
* renamed, false otherwise.
*/
bool SoftCVS::
rename_file(SoftCVS::SceneFiles::iterator begin,
SoftCVS::SceneFiles::iterator end) {
int length = end - begin;
nassertr(length > 0, false);
SoftFilename &orig = (*begin);
string dirname = orig.get_dirname();
string source_filename = orig.get_filename();
string dest_filename = orig.get_1_0_filename();
if (length > 2) {
nout << source_filename << " supercedes:\n";
SceneFiles::const_iterator p;
for (p = begin + 1; p != end; ++p) {
nout << " " << (*p).get_filename() << "\n";
}
} else if (length == 2) {
nout << source_filename << " supercedes "
<< (*(begin + 1)).get_filename() << ".\n";
} else {
nout << source_filename << " renamed.\n";
}
// Now remove all of the "wrong" files.
SceneFiles::const_iterator p;
for (p = begin + 1; p != end; ++p) {
Filename file((*p).get_dirname(), (*p).get_filename());
if (!file.unlink()) {
nout << "Unable to remove " << file << ".\n";
}
}
// And rename the good one.
Filename source(dirname, source_filename);
Filename dest(dirname, dest_filename);
if (!source.rename_to(dest)) {
nout << "Unable to rename " << source << " to " << dest_filename << ".\n";
exit(1);
}
return true;
}
/**
* Scans the CVS repository in the indicated directory to determine which
* files are already versioned elements. Returns true if the directory is
* CVS-controlled, false otherwise.
*/
bool SoftCVS::
scan_cvs(const string &dirname, pset<string> &cvs_elements) {
Filename cvs_entries = dirname + "/CVS/Entries";
if (!cvs_entries.exists()) {
return false;
}
std::ifstream in;
cvs_entries.set_text();
if (!cvs_entries.open_read(in)) {
nout << "Unable to read CVS directory.\n";
return true;
}
string line;
std::getline(in, line);
while (!in.fail() && !in.eof()) {
if (!line.empty() && line[0] == '/') {
size_t slash = line.find('/', 1);
if (slash != string::npos) {
string filename = line.substr(1, slash - 1);
if (line.substr(slash + 1, 2) == "-1") {
// If the first number after the slash is -1, the file used to be
// here but was recently cvs removed. It counts as no longer being
// an element.
} else {
cvs_elements.insert(filename);
}
}
}
std::getline(in, line);
}
return true;
}
/**
* Reads a scene file, looking for references to element files. For each
* reference found, increments the appropriate element file's reference count.
*/
bool SoftCVS::
scan_scene_file(std::istream &in, Multifile &multifile) {
bool okflag = true;
int c = in.get();
while (!in.eof() && !in.fail()) {
// Skip whitespace.
while (isspace(c) && !in.eof() && !in.fail()) {
c = in.get();
}
// Now begin a word.
string word;
while (!isspace(c) && !in.eof() && !in.fail()) {
word += c;
c = in.get();
}
if (!word.empty()) {
SoftFilename v("", word);
// Increment the use count on all matching elements of the multiset.
std::pair<ElementFiles::iterator, ElementFiles::iterator> range;
range = _element_files.equal_range(v);
ElementFiles::iterator ei;
for (ei = range.first; ei != range.second; ++ei) {
// We cheat and get a non-const reference to the filename out of the
// set. We can safely do this because incrementing the use count
// won't change its position in the set.
SoftFilename &sf = (SoftFilename &)(*ei);
sf.increment_use_count();
Filename file(sf.get_dirname(), sf.get_filename());
if (multifile.update_subfile(file, file, 6).empty()) {
nout << "Unable to add " << file << "\n";
okflag = false;
}
}
}
}
return okflag;
}
/**
* Invokes CVS to add just the named file to the repository. Returns true on
* success, false on failure.
*/
bool SoftCVS::
cvs_add(const string &path) {
string command = _cvs_binary + " add -kb " + path;
nout << command << "\n";
int result = system(command.c_str());
if (result != 0) {
nout << "Failure invoking cvs.\n";
return false;
}
return true;
}
/**
* Invokes CVS to add (or remove) all of the files in the indicated vector.
* Returns true on success, false on failure.
*/
bool SoftCVS::
cvs_add_or_remove(const string &cvs_command, const vector_string &paths) {
static const int max_command = 4096;
if (!paths.empty()) {
string command = _cvs_binary + " " + cvs_command;
vector_string::const_iterator pi;
pi = paths.begin();
while (pi != paths.end()) {
const string &path = (*pi);
if ((int)command.length() + 1 + (int)path.length() >= max_command) {
// Fire off the command now.
nout << command << "\n";
int result = system(command.c_str());
if (result != 0) {
nout << "Failure invoking cvs.\n";
return false;
}
command = _cvs_binary + " " + cvs_command;
}
command += ' ';
command += path;
++pi;
}
nout << command << "\n";
int result = system(command.c_str());
if (result != 0) {
nout << "Failure invoking cvs.\n";
return false;
}
}
return true;
}
int main(int argc, char *argv[]) {
SoftCVS prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -1,70 +0,0 @@
/**
* 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 softCVS.h
* @author drose
* @date 2000-11-10
*/
#ifndef SOFTCVS_H
#define SOFTCVS_H
#include "pandatoolbase.h"
#include "softFilename.h"
#include "programBase.h"
#include "vector_string.h"
#include "filename.h"
#include "pvector.h"
#include "pset.h"
class Multifile;
/**
* This program prepares a SoftImage database for CVS by renaming everything
* to version 1-0, and adding new files to CVS.
*/
class SoftCVS : public ProgramBase {
public:
SoftCVS();
void run();
private:
typedef pvector<SoftFilename> SceneFiles;
typedef pmultiset<SoftFilename> ElementFiles;
void traverse_root();
void traverse_subdir(const Filename &directory);
void collapse_scene_files();
bool get_scenes();
void remove_unused_elements();
bool rename_file(SceneFiles::iterator begin, SceneFiles::iterator end);
bool scan_cvs(const std::string &dirname, pset<std::string> &cvs_elements);
bool scan_scene_file(std::istream &in, Multifile &multifile);
bool cvs_add(const std::string &path);
bool cvs_add_or_remove(const std::string &cvs_command,
const vector_string &paths);
SceneFiles _scene_files;
ElementFiles _element_files;
vector_string _global_files;
vector_string _cvs_add;
vector_string _cvs_remove;
bool _no_cvs;
std::string _cvs_binary;
};
#endif

View File

@ -1,291 +0,0 @@
/**
* 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 softFilename.cxx
* @author drose
* @date 2000-11-10
*/
#include "softFilename.h"
#include "pnotify.h"
using std::string;
/**
*
*/
SoftFilename::
SoftFilename(const string &dirname, const string &filename) :
_dirname(dirname),
_filename(filename)
{
_has_version = false;
_major = 0;
_minor = 0;
_in_cvs = false;
_wants_cvs = false;
_use_count = 0;
_base = _filename;
// Scan for a version number and an optional extension after each dot in the
// filename.
size_t dot = _filename.find('.');
while (dot != string::npos) {
size_t m = dot + 1;
const char *fstr = _filename.c_str();
char *endptr;
// Check for a numeric version number.
int major = strtol(fstr + m , &endptr, 10);
if (endptr != fstr + m && *endptr == '-') {
// We got a major number, is there a minor number?
m = (endptr - fstr) + 1;
int minor = strtol(fstr + m, &endptr, 10);
if (endptr != fstr + m && (*endptr == '.' || *endptr == '\0')) {
// We got a minor number too!
_has_version = true;
_base = _filename.substr(0, dot + 1);
_major = major;
_minor = minor;
_ext = endptr;
return;
}
}
// That wasn't a version number. Is there more?
dot = _filename.find('.', dot + 1);
}
}
/**
*
*/
SoftFilename::
SoftFilename(const SoftFilename &copy) :
_dirname(copy._dirname),
_filename(copy._filename),
_has_version(copy._has_version),
_base(copy._base),
_major(copy._major),
_minor(copy._minor),
_ext(copy._ext),
_in_cvs(copy._in_cvs),
_wants_cvs(copy._wants_cvs),
_use_count(copy._use_count)
{
}
/**
*
*/
void SoftFilename::
operator = (const SoftFilename &copy) {
_dirname = copy._dirname;
_filename = copy._filename;
_has_version = copy._has_version;
_base = copy._base;
_major = copy._major;
_minor = copy._minor;
_ext = copy._ext;
_in_cvs = copy._in_cvs;
_wants_cvs = copy._wants_cvs;
_use_count = copy._use_count;
}
/**
* Returns the name of the directory this file was found in.
*/
const string &SoftFilename::
get_dirname() const {
return _dirname;
}
/**
* Returns the actual filename as found in the directory.
*/
const string &SoftFilename::
get_filename() const {
return _filename;
}
/**
* Returns true if the filename had a version number, false otherwise.
*/
bool SoftFilename::
has_version() const {
return _has_version;
}
/**
* Returns what the filename would be if it were version 1-0.
*/
string SoftFilename::
get_1_0_filename() const {
nassertr(_has_version, string());
return _base + "1-0" + _ext;
}
/**
* Returns the base part of the filename. This is everything before the
* version number.
*/
const string &SoftFilename::
get_base() const {
nassertr(_has_version, _filename);
return _base;
}
/**
* Returns the major version number.
*/
int SoftFilename::
get_major() const {
nassertr(_has_version, 0);
return _major;
}
/**
* Returns the minor version number.
*/
int SoftFilename::
get_minor() const {
nassertr(_has_version, 0);
return _minor;
}
/**
* Returns the extension part of the filename. This is everything after the
* version number.
*/
const string &SoftFilename::
get_extension() const {
nassertr(_has_version, _ext);
return _ext;
}
/**
* Returns the filename part, without the extension.
*/
string SoftFilename::
get_non_extension() const {
nassertr(_has_version, _filename);
nassertr(_ext.length() < _filename.length(), _filename);
return _filename.substr(0, _filename.length() - _ext.length());
}
/**
* Returns true if this is a version 1_0 filename, false otherwise.
*/
bool SoftFilename::
is_1_0() const {
nassertr(_has_version, false);
return (_major == 1 && _minor == 0);
}
/**
* Makes this a 1_0 filename.
*/
void SoftFilename::
make_1_0() {
_has_version = true;
_major = 1;
_minor = 0;
_filename = get_1_0_filename();
}
/**
* Returns true if this file has the same base and extension as the other,
* disregarding the version number; false otherwise.
*/
bool SoftFilename::
is_same_file(const SoftFilename &other) const {
return _base == other._base && _ext == other._ext;
}
/**
* Puts filenames in order such that the files with the same base are sorted
* together, ignoring extension; and within files with the same base, files
* are sorted in decreasing version number order so that the most recent
* version appears first.
*/
bool SoftFilename::
operator < (const SoftFilename &other) const {
if (_base != other._base) {
return _base < other._base;
}
if (_has_version != other._has_version) {
// If one has a version and the other one doesn't, the one without a
// version comes first.
return _has_version < other._has_version;
}
if (_has_version) {
if (_major != other._major) {
return _major > other._major;
}
if (_minor != other._minor) {
return _minor > other._minor;
}
}
return false;
}
/**
* Sets the flag that indicates whether this file is known to be entered into
* the CVS database.
*/
void SoftFilename::
set_in_cvs(bool in_cvs) {
_in_cvs = in_cvs;
}
/**
* Returns true if this file is known to be entered in the CVS database, false
* if it is not.
*/
bool SoftFilename::
get_in_cvs() const {
return _in_cvs;
}
/**
* Sets the flag that indicates whether this file should be entered into the
* CVS database.
*/
void SoftFilename::
set_wants_cvs(bool wants_cvs) {
_wants_cvs = wants_cvs;
}
/**
* Returns true if this file should be entered into the CVS database, false
* otherwise.
*/
bool SoftFilename::
get_wants_cvs() const {
return _wants_cvs;
}
/**
* Indicates that this filename is referenced by one more scene file.
*/
void SoftFilename::
increment_use_count() {
_use_count++;
}
/**
* Returns the number of scene files that referenced this filename.
*/
int SoftFilename::
get_use_count() const {
return _use_count;
}

View File

@ -1,73 +0,0 @@
/**
* 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 softFilename.h
* @author drose
* @date 2000-11-10
*/
#ifndef SOFTFILENAME_H
#define SOFTFILENAME_H
#include "pandatoolbase.h"
/**
* This encapsulates a SoftImage versioned filename, of the form base.v-v.ext:
* it consists of a directory name, a base, a major and minor version number,
* and an optional extension.
*
* It also keeps track of whether the named file has been added to CVS, and
* how many scene files it is referenced by,
*/
class SoftFilename {
public:
SoftFilename(const std::string &dirname, const std::string &filename);
SoftFilename(const SoftFilename &copy);
void operator = (const SoftFilename &copy);
const std::string &get_dirname() const;
const std::string &get_filename() const;
bool has_version() const;
std::string get_1_0_filename() const;
const std::string &get_base() const;
int get_major() const;
int get_minor() const;
const std::string &get_extension() const;
std::string get_non_extension() const;
bool is_1_0() const;
void make_1_0();
bool is_same_file(const SoftFilename &other) const;
bool operator < (const SoftFilename &other) const;
void set_in_cvs(bool in_cvs);
bool get_in_cvs() const;
void set_wants_cvs(bool wants_cvs);
bool get_wants_cvs() const;
void increment_use_count();
int get_use_count() const;
private:
std::string _dirname;
std::string _filename;
bool _has_version;
std::string _base;
int _major;
int _minor;
std::string _ext;
bool _in_cvs;
bool _wants_cvs;
int _use_count;
};
#endif

View File

@ -18,6 +18,7 @@
#include "eggTexture.h"
#include "eggPrimitive.h"
#include "datagram.h"
#include "config_xfile.h"
#include <string.h> // for strcmp, strdup

View File

@ -12,6 +12,7 @@
*/
#include "xFileMesh.h"
#include "xFileToEggConverter.h"
#include "xFileFace.h"
#include "xFileVertex.h"
#include "xFileNormal.h"
@ -22,6 +23,7 @@
#include "eggVertexPool.h"
#include "eggVertex.h"
#include "eggPolygon.h"
#include "eggGroup.h"
#include "eggGroupNode.h"
using std::min;

View File

@ -22,6 +22,8 @@
#include "namable.h"
#include "coordinateSystem.h"
#include "luse.h"
class XFileNode;
class XFileDataNode;
class XFileMesh;

View File

@ -19,6 +19,7 @@
#include "eggData.h"
#include "eggGroup.h"
#include "eggTable.h"
#include "eggXfmSAnim.h"
#include "eggGroupUniquifier.h"
#include "datagram.h"

View File

@ -10,6 +10,7 @@ from _pytest.outcomes import Failed
# The reset() function serves to prevent the _triggered variable from being
# optimized out in the case that the assertions are being optimized out.
GLSL_COMPUTE_TEMPLATE = """#version {version}
{extensions}
layout(local_size_x = 1, local_size_y = 1) in;
@ -37,7 +38,7 @@ void main() {{
"""
def run_glsl_test(gsg, body, preamble="", inputs={}, version=430):
def run_glsl_test(gsg, body, preamble="", inputs={}, version=130, exts=set()):
""" Runs a GLSL test on the given GSG. The given body is executed in the
main function and should call assert(). The preamble should contain all
of the shader inputs. """
@ -48,11 +49,20 @@ def run_glsl_test(gsg, body, preamble="", inputs={}, version=430):
if not gsg.supports_buffer_texture:
pytest.skip("buffer textures not supported")
exts = exts | {'GL_ARB_compute_shader', 'GL_ARB_shader_image_load_store'}
missing_exts = sorted(ext for ext in exts if not gsg.has_extension(ext))
if missing_exts:
pytest.skip("missing extensions: " + ' '.join(missing_exts))
extensions = ''
for ext in exts:
extensions += '#extension {ext} : require\n'.format(ext=ext)
__tracebackhide__ = True
preamble = preamble.strip()
body = body.rstrip().lstrip('\n')
code = GLSL_COMPUTE_TEMPLATE.format(version=version, preamble=preamble, body=body)
code = GLSL_COMPUTE_TEMPLATE.format(version=version, extensions=extensions, preamble=preamble, body=body)
line_offset = code[:code.find(body)].count('\n') + 1
shader = core.Shader.make_compute(core.Shader.SL_GLSL, code)
assert shader, code
@ -122,7 +132,7 @@ def test_glsl_sampler(gsg):
assert(texelFetch(tex1, 0, 0) == vec4(0, 2 / 255.0, 1, 1));
assert(texelFetch(tex2, ivec2(0, 0), 0) == vec4(1.0, 2.0, -3.14, 0.0));
"""
run_glsl_test(gsg, code, preamble, {'tex1': tex1, 'tex2': tex2}), code
run_glsl_test(gsg, code, preamble, {'tex1': tex1, 'tex2': tex2})
def test_glsl_image(gsg):
@ -142,7 +152,7 @@ def test_glsl_image(gsg):
assert(imageLoad(tex1, 0) == vec4(0, 2 / 255.0, 1, 1));
assert(imageLoad(tex2, ivec2(0, 0)) == vec4(1.0, 2.0, -3.14, 0.0));
"""
run_glsl_test(gsg, code, preamble, {'tex1': tex1, 'tex2': tex2}), code
run_glsl_test(gsg, code, preamble, {'tex1': tex1, 'tex2': tex2})
def test_glsl_ssbo(gsg):
@ -164,7 +174,10 @@ def test_glsl_ssbo(gsg):
assert(value1 == 1234567);
assert(value2 == -1234567);
"""
run_glsl_test(gsg, code, preamble, {'buffer1': buffer1, 'buffer2': buffer2}), code
run_glsl_test(gsg, code, preamble, {'buffer1': buffer1, 'buffer2': buffer2},
exts={'GL_ARB_shader_storage_buffer_object',
'GL_ARB_uniform_buffer_object',
'GL_ARB_shading_language_420pack'})
def test_glsl_int(gsg):
@ -197,8 +210,8 @@ def test_glsl_uint(gsg):
uniform uint intmax;
"""
code = """
assert(zero == 0);
assert(intmax == 0x7fffffff);
assert(zero == 0u);
assert(intmax == 0x7fffffffu);
"""
run_glsl_test(gsg, code, preamble, inputs)
@ -243,7 +256,7 @@ def test_glsl_pta_int(gsg):
assert(pta[2] == 2);
assert(pta[3] == 3);
"""
run_glsl_test(gsg, code, preamble, {'pta': pta}), code
run_glsl_test(gsg, code, preamble, {'pta': pta})
def test_glsl_pta_ivec4(gsg):
@ -256,7 +269,7 @@ def test_glsl_pta_ivec4(gsg):
assert(pta[0] == ivec4(0, 1, 2, 3));
assert(pta[1] == ivec4(4, 5, 6, 7));
"""
run_glsl_test(gsg, code, preamble, {'pta': pta}), code
run_glsl_test(gsg, code, preamble, {'pta': pta})
def test_glsl_pta_mat4(gsg):
@ -278,7 +291,7 @@ def test_glsl_pta_mat4(gsg):
assert(pta[1][2] == vec4(24, 25, 26, 27));
assert(pta[1][3] == vec4(28, 29, 30, 31));
"""
run_glsl_test(gsg, code, preamble, {'pta': pta}), code
run_glsl_test(gsg, code, preamble, {'pta': pta})
def test_glsl_write_extract_image_buffer(gsg):
@ -299,12 +312,12 @@ def test_glsl_write_extract_image_buffer(gsg):
layout(r32i) uniform iimageBuffer tex2;
"""
code = """
assert(imageLoad(tex1, 0).r == 0);
assert(imageLoad(tex1, 0).r == 0u);
assert(imageLoad(tex2, 0).r == 0);
imageStore(tex1, 0, uvec4(123));
imageStore(tex2, 0, ivec4(-456));
memoryBarrier();
assert(imageLoad(tex1, 0).r == 123);
assert(imageLoad(tex1, 0).r == 123u);
assert(imageLoad(tex2, 0).r == -456);
"""

View File

@ -1,6 +1,5 @@
from panda3d import core
import pytest
import threading
import time
import sys
@ -39,7 +38,11 @@ def test_future_timeout():
fut.result(0.001)
@pytest.mark.skipif(not core.Thread.is_threading_supported(),
reason="Threading support disabled")
def test_future_wait():
threading = pytest.importorskip("direct.stdpy.threading")
fut = core.AsyncFuture()
# Launch a thread to set the result value.
@ -59,7 +62,11 @@ def test_future_wait():
assert fut.result() is None
@pytest.mark.skipif(not core.Thread.is_threading_supported(),
reason="Threading support disabled")
def test_future_wait_cancel():
threading = pytest.importorskip("direct.stdpy.threading")
fut = core.AsyncFuture()
# Launch a thread to cancel the future.

View File

@ -1,6 +1,13 @@
from panda3d import core
def test_textnode_write():
out = core.StringStream()
text = core.TextNode("test")
text.write(out, 0)
assert out.data.startswith(b"TextNode test")
def test_textnode_card_as_margin():
text = core.TextNode("test")
text.text = "Test"