mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
54b3474670
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -743,6 +743,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:
|
||||
@ -1659,6 +1662,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)
|
||||
|
||||
@ -3391,7 +3396,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')
|
||||
@ -3912,7 +3916,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"])
|
||||
@ -6444,21 +6448,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/
|
||||
#
|
||||
|
@ -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>
|
||||
|
@ -134,6 +134,12 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
|
||||
if (accelerated) {
|
||||
properties.set_force_hardware(1);
|
||||
}
|
||||
|
||||
// Cautiously setting this to true. It appears that macOS framebuffers are
|
||||
// sRGB-capable, but I don't really know how to verify this.
|
||||
if (color_size == 32 && !color_float) {
|
||||
properties.set_srgb_color(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -45,6 +45,19 @@ CycleDataLockedReader(const CycleDataLockedReader<CycleDataType> ©) :
|
||||
_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> ©) {
|
||||
_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> ©) {
|
||||
_pointer = copy._pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
template<class CycleDataType>
|
||||
INLINE void CycleDataLockedReader<CycleDataType>::
|
||||
operator = (CycleDataLockedReader<CycleDataType> &&from) noexcept {
|
||||
nassertv(_pointer == nullptr);
|
||||
|
||||
_pointer = from._pointer;
|
||||
from._pointer = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -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";
|
||||
|
@ -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)) {
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "eggBackPointer.h"
|
||||
|
||||
#include "pnotify.h"
|
||||
|
||||
|
||||
TypeHandle EggBackPointer::_type_handle;
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
class EggJointPointer;
|
||||
class LMatrix4d;
|
||||
|
||||
/**
|
||||
* This class is used during joint optimization or restructuring to store the
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
|
||||
#include "eggJointData.h"
|
||||
|
||||
#include "eggCharacterDb.h"
|
||||
#include "eggJointNodePointer.h"
|
||||
#include "eggMatrixTablePointer.h"
|
||||
#include "pvector.h"
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -12,7 +12,9 @@
|
||||
*/
|
||||
|
||||
#include "eggMatrixTablePointer.h"
|
||||
|
||||
#include "dcast.h"
|
||||
#include "eggCharacterDb.h"
|
||||
#include "eggSAnimData.h"
|
||||
#include "eggXfmAnimData.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "textureImage.h"
|
||||
#include "palettizer.h"
|
||||
#include "paletteImage.h"
|
||||
#include "sourceTextureImage.h"
|
||||
|
||||
#include "indent.h"
|
||||
#include "datagram.h"
|
||||
|
@ -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();
|
||||
}
|
@ -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
@ -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 ©) :
|
||||
EggUserData(copy),
|
||||
_vertex_color(copy._vertex_color),
|
||||
_double_sided(copy._double_sided)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void SoftEggGroupUserData::
|
||||
operator = (const SoftEggGroupUserData ©) {
|
||||
EggUserData::operator = (copy);
|
||||
_vertex_color = copy._vertex_color;
|
||||
_double_sided = copy._double_sided;
|
||||
}
|
@ -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;
|
@ -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 ©);
|
||||
INLINE void operator = (const SoftEggGroupUserData ©);
|
||||
|
||||
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
@ -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
|
@ -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;
|
||||
}
|
@ -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
@ -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 ©);
|
||||
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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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 ©) :
|
||||
_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 ©) {
|
||||
_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;
|
||||
}
|
@ -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 ©);
|
||||
void operator = (const SoftFilename ©);
|
||||
|
||||
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
|
@ -18,6 +18,7 @@
|
||||
#include "eggTexture.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "datagram.h"
|
||||
#include "config_xfile.h"
|
||||
|
||||
#include <string.h> // for strcmp, strdup
|
||||
|
||||
|
@ -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;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "namable.h"
|
||||
#include "coordinateSystem.h"
|
||||
|
||||
#include "luse.h"
|
||||
|
||||
class XFileNode;
|
||||
class XFileDataNode;
|
||||
class XFileMesh;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "eggData.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "eggGroupUniquifier.h"
|
||||
#include "datagram.h"
|
||||
|
@ -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);
|
||||
"""
|
||||
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user