From 3b7b9cd18cc3c4e7b1ba8979c525a9f25c4547ea Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sat, 20 Oct 2018 17:54:54 -0600 Subject: [PATCH 01/15] tests: Enhance GLSL test - Don't assume GLSL 4.30 is available just because the driver supports compute shaders. Drivers before OpenGL 4.3 may still offer the extension. - Use GLSL 1.30 by default, and turn on additional features using extensions. Skip any tests requiring extensions that aren't supported by the driver. - Unsigned literal ints should have a 'u' suffix. - Clean up a few dead Python expressions --- tests/display/test_glsl_shader.py | 37 +++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index 91816353f6..0a0a5f5737 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -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); """ From b8b86dc2f283115ae8aea90ec9c3930c0ddd9eb2 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sat, 27 Oct 2018 19:41:51 -0600 Subject: [PATCH 02/15] glesgsg: Only use the iOS GLES framework when "BUILD_IPHONE" is defined --- panda/src/gles2gsg/gles2gsg.h | 2 +- panda/src/glesgsg/glesgsg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/src/gles2gsg/gles2gsg.h b/panda/src/gles2gsg/gles2gsg.h index 8d80e690eb..363baad0ca 100644 --- a/panda/src/gles2gsg/gles2gsg.h +++ b/panda/src/gles2gsg/gles2gsg.h @@ -51,7 +51,7 @@ // OpenGL ES 2 has no fixed-function pipeline. #undef SUPPORT_FIXED_FUNCTION -#ifdef IS_OSX +#ifdef BUILD_IPHONE #include // #include #else diff --git a/panda/src/glesgsg/glesgsg.h b/panda/src/glesgsg/glesgsg.h index 64d64db216..b7c7348cb9 100644 --- a/panda/src/glesgsg/glesgsg.h +++ b/panda/src/glesgsg/glesgsg.h @@ -54,7 +54,7 @@ #define __glext_h_ #define ES1_GLEXT_H_GUARD -#ifdef IS_OSX +#ifdef BUILD_IPHONE #include // #include #else From 466a68a985c646ba8625dfdd933942d25204a3a5 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sun, 28 Oct 2018 03:11:51 -0600 Subject: [PATCH 03/15] pandatool: Fix several missing includes --- pandatool/src/eggcharbase/eggBackPointer.cxx | 2 ++ pandatool/src/eggcharbase/eggCharacterDb.h | 1 + pandatool/src/eggcharbase/eggJointData.cxx | 2 ++ pandatool/src/eggcharbase/eggJointNodePointer.cxx | 3 ++- pandatool/src/eggcharbase/eggMatrixTablePointer.cxx | 2 ++ pandatool/src/palettizer/paletteGroup.cxx | 1 + pandatool/src/xfileegg/xFileMaterial.cxx | 1 + pandatool/src/xfileegg/xFileMesh.cxx | 2 ++ pandatool/src/xfileegg/xFileMesh.h | 2 ++ pandatool/src/xfileegg/xFileToEggConverter.cxx | 1 + 10 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pandatool/src/eggcharbase/eggBackPointer.cxx b/pandatool/src/eggcharbase/eggBackPointer.cxx index 400d9e3b2f..b1e269624a 100644 --- a/pandatool/src/eggcharbase/eggBackPointer.cxx +++ b/pandatool/src/eggcharbase/eggBackPointer.cxx @@ -13,6 +13,8 @@ #include "eggBackPointer.h" +#include "pnotify.h" + TypeHandle EggBackPointer::_type_handle; diff --git a/pandatool/src/eggcharbase/eggCharacterDb.h b/pandatool/src/eggcharbase/eggCharacterDb.h index 037367dc8b..31af55f231 100644 --- a/pandatool/src/eggcharbase/eggCharacterDb.h +++ b/pandatool/src/eggcharbase/eggCharacterDb.h @@ -29,6 +29,7 @@ */ class EggJointPointer; +class LMatrix4d; /** * This class is used during joint optimization or restructuring to store the diff --git a/pandatool/src/eggcharbase/eggJointData.cxx b/pandatool/src/eggcharbase/eggJointData.cxx index 65ed9505a5..ebf656b113 100644 --- a/pandatool/src/eggcharbase/eggJointData.cxx +++ b/pandatool/src/eggcharbase/eggJointData.cxx @@ -12,6 +12,8 @@ */ #include "eggJointData.h" + +#include "eggCharacterDb.h" #include "eggJointNodePointer.h" #include "eggMatrixTablePointer.h" #include "pvector.h" diff --git a/pandatool/src/eggcharbase/eggJointNodePointer.cxx b/pandatool/src/eggcharbase/eggJointNodePointer.cxx index c9c891606b..23bf7ea480 100644 --- a/pandatool/src/eggcharbase/eggJointNodePointer.cxx +++ b/pandatool/src/eggcharbase/eggJointNodePointer.cxx @@ -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" diff --git a/pandatool/src/eggcharbase/eggMatrixTablePointer.cxx b/pandatool/src/eggcharbase/eggMatrixTablePointer.cxx index 21c9c63516..267296483f 100644 --- a/pandatool/src/eggcharbase/eggMatrixTablePointer.cxx +++ b/pandatool/src/eggcharbase/eggMatrixTablePointer.cxx @@ -12,7 +12,9 @@ */ #include "eggMatrixTablePointer.h" + #include "dcast.h" +#include "eggCharacterDb.h" #include "eggSAnimData.h" #include "eggXfmAnimData.h" #include "eggXfmSAnim.h" diff --git a/pandatool/src/palettizer/paletteGroup.cxx b/pandatool/src/palettizer/paletteGroup.cxx index 182479216f..5f231b2e14 100644 --- a/pandatool/src/palettizer/paletteGroup.cxx +++ b/pandatool/src/palettizer/paletteGroup.cxx @@ -17,6 +17,7 @@ #include "textureImage.h" #include "palettizer.h" #include "paletteImage.h" +#include "sourceTextureImage.h" #include "indent.h" #include "datagram.h" diff --git a/pandatool/src/xfileegg/xFileMaterial.cxx b/pandatool/src/xfileegg/xFileMaterial.cxx index 11457ebcd5..9eaac25fbd 100644 --- a/pandatool/src/xfileegg/xFileMaterial.cxx +++ b/pandatool/src/xfileegg/xFileMaterial.cxx @@ -18,6 +18,7 @@ #include "eggTexture.h" #include "eggPrimitive.h" #include "datagram.h" +#include "config_xfile.h" #include // for strcmp, strdup diff --git a/pandatool/src/xfileegg/xFileMesh.cxx b/pandatool/src/xfileegg/xFileMesh.cxx index 4fad113ed4..e253ee385d 100644 --- a/pandatool/src/xfileegg/xFileMesh.cxx +++ b/pandatool/src/xfileegg/xFileMesh.cxx @@ -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; diff --git a/pandatool/src/xfileegg/xFileMesh.h b/pandatool/src/xfileegg/xFileMesh.h index 417d7c4253..339ba2038f 100644 --- a/pandatool/src/xfileegg/xFileMesh.h +++ b/pandatool/src/xfileegg/xFileMesh.h @@ -22,6 +22,8 @@ #include "namable.h" #include "coordinateSystem.h" +#include "luse.h" + class XFileNode; class XFileDataNode; class XFileMesh; diff --git a/pandatool/src/xfileegg/xFileToEggConverter.cxx b/pandatool/src/xfileegg/xFileToEggConverter.cxx index 130c42546e..91ba21ba97 100644 --- a/pandatool/src/xfileegg/xFileToEggConverter.cxx +++ b/pandatool/src/xfileegg/xFileToEggConverter.cxx @@ -19,6 +19,7 @@ #include "eggData.h" #include "eggGroup.h" +#include "eggTable.h" #include "eggXfmSAnim.h" #include "eggGroupUniquifier.h" #include "datagram.h" From 43142e4e80ea6d9ba1adab6e53fcce144de16e10 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sun, 28 Oct 2018 04:08:15 -0600 Subject: [PATCH 04/15] pandatool: Delete softegg/softprogs These depend on "SAA" - a Softimage library so long gone I can't even find references to it on Google. --- pandatool/src/softegg/config_softegg.cxx | 55 - pandatool/src/softegg/config_softegg.h | 28 - pandatool/src/softegg/soft2Egg.c | 4751 ----------------- pandatool/src/softegg/softEggGroupUserData.I | 44 - .../src/softegg/softEggGroupUserData.cxx | 16 - pandatool/src/softegg/softEggGroupUserData.h | 53 - pandatool/src/softegg/softNodeDesc.cxx | 1310 ----- pandatool/src/softegg/softNodeDesc.h | 159 - pandatool/src/softegg/softNodeTree.cxx | 561 -- pandatool/src/softegg/softNodeTree.h | 78 - pandatool/src/softegg/softToEggConverter.cxx | 2122 -------- pandatool/src/softegg/softToEggConverter.h | 179 - pandatool/src/softprogs/softCVS.cxx | 588 -- pandatool/src/softprogs/softCVS.h | 70 - pandatool/src/softprogs/softFilename.cxx | 291 - pandatool/src/softprogs/softFilename.h | 73 - 16 files changed, 10378 deletions(-) delete mode 100644 pandatool/src/softegg/config_softegg.cxx delete mode 100644 pandatool/src/softegg/config_softegg.h delete mode 100644 pandatool/src/softegg/soft2Egg.c delete mode 100644 pandatool/src/softegg/softEggGroupUserData.I delete mode 100644 pandatool/src/softegg/softEggGroupUserData.cxx delete mode 100644 pandatool/src/softegg/softEggGroupUserData.h delete mode 100644 pandatool/src/softegg/softNodeDesc.cxx delete mode 100644 pandatool/src/softegg/softNodeDesc.h delete mode 100644 pandatool/src/softegg/softNodeTree.cxx delete mode 100644 pandatool/src/softegg/softNodeTree.h delete mode 100644 pandatool/src/softegg/softToEggConverter.cxx delete mode 100644 pandatool/src/softegg/softToEggConverter.h delete mode 100644 pandatool/src/softprogs/softCVS.cxx delete mode 100644 pandatool/src/softprogs/softCVS.h delete mode 100644 pandatool/src/softprogs/softFilename.cxx delete mode 100644 pandatool/src/softprogs/softFilename.h diff --git a/pandatool/src/softegg/config_softegg.cxx b/pandatool/src/softegg/config_softegg.cxx deleted file mode 100644 index 89ad412508..0000000000 --- a/pandatool/src/softegg/config_softegg.cxx +++ /dev/null @@ -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(); -} diff --git a/pandatool/src/softegg/config_softegg.h b/pandatool/src/softegg/config_softegg.h deleted file mode 100644 index 8deb0cb7aa..0000000000 --- a/pandatool/src/softegg/config_softegg.h +++ /dev/null @@ -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 diff --git a/pandatool/src/softegg/soft2Egg.c b/pandatool/src/softegg/soft2Egg.c deleted file mode 100644 index 9e744b8655..0000000000 --- a/pandatool/src/softegg/soft2Egg.c +++ /dev/null @@ -1,4751 +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 soft2Egg.c - * @author masad - * @date 2003-09-26 - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include "pandatoolbase.h" - -int init_soft2egg(int, char **); - -#if 0 -// DWD includes -#include "eggBase.h" -#include -#include -#include - -// system includes -#include -#include -#include -#include -#include -#include - -// Performer includes -#include - -// SoftImage includes -#include -#include - -static const int TEX_PER_MAT = 1; -static FILE *outStream = stdout; -// static FILE *outStream = stderr; - -class soft2egg : public EggBase -{ - public: - - soft2egg() : EggBase("r:d:s:m:t:P:b:e:f:T:S:M:A:N:v:o:FhknpaxiucCD") - { - rsrc_path = "/ful/ufs/soft371_mips2/3D/rsrc"; - database_name = NULL; - scene_name = NULL; - model_name = NULL; - animFileName = NULL; - eggFileName = NULL; - tex_path = NULL; - eggGroupName = NULL; - tex_filename = NULL; - search_prefix = NULL; - result = SI_SUCCESS; - - skeleton = new EggGroup(); - foundRoot = FALSE; - animRoot = NULL; - morphRoot = NULL; - geom_as_joint = 0; - make_anim = 0; - make_nurbs = 0; - make_poly = 0; - make_soft = 0; - make_morph = 1; - make_duv = 1; - make_dart = TRUE; - has_morph = 0; - make_pose = 0; - animData.is_z_up = FALSE; - nurbs_step = 1; - anim_start = -1000; - anim_end = -1000; - anim_rate = 24; - pose_frame = -1; - verbose = 0; - flatten = 0; - shift_textures = 0; - ignore_tex_offsets = 0; - use_prefix = 0; - } - - virtual void Help(); - virtual void Usage(); - virtual void ShowOpts(); - - virtual boolean UseOutputSwitch() const { - return false; - } - - virtual boolean - HandleGetopts(char flag, char *optarg, int &optind, int argc, char **argv); - - int isNum( float ); - char *GetRootName( const char * ); - char *RemovePathName( const char * ); - char *GetSliderName( const char * ); - char *GetFullName( SAA_Scene *, SAA_Elem * ); - char *GetName( SAA_Scene *, SAA_Elem * ); - char *GetModelNoteInfo( SAA_Scene *, SAA_Elem * ); - char *MakeTableName( const char *, int ); - char *DepointellizeName( char * ); - SAA_Elem *FindModelByName( char *, SAA_Scene *, SAA_Elem *, int ); - char *ConvertTexture( SAA_Scene *, SAA_Elem * ); - int *FindClosestTriVert( EggVertexPool *, SAA_DVector *, int ); - int *MakeIndexMap( int *, int, int ); - int findShapeVert( SAA_DVector, SAA_DVector *, int ); - void LoadSoft(); - void MakeEgg( EggGroup *, EggJoint *, AnimGroup *, SAA_Scene *, SAA_Elem * ); - void MakeSurfaceCurve( SAA_Scene *, SAA_Elem *, EggGroup *, - EggNurbsSurface *&, int , SAA_SubElem *, bool ); - - EggNurbsCurve *MakeUVNurbsCurve( int, long *, double *, double *, - EggGroup *, char * ); - - EggNurbsCurve *MakeNurbsCurve( SAA_Scene *, SAA_Elem *, EggGroup *, - float [4][4], char * ); - - void AddKnots( perf_vector &, double *, int, SAA_Boolean, int ); - void MakeJoint( SAA_Scene *, EggJoint *&, AnimGroup *&, SAA_Elem *, char * ); - void MakeSoftSkin( SAA_Scene *, SAA_Elem *, SAA_Elem *, int, char * ); - void CleanUpSoftSkin( SAA_Scene *, SAA_Elem *, char * ); - void MakeAnimTable( SAA_Scene *, SAA_Elem *, char * ); - void MakeVertexOffsets( SAA_Scene *, SAA_Elem *, SAA_ModelType type, - int, int, SAA_DVector *, float (*)[4], char * ); - void MakeMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int, char *, - float ); - void MakeLinearMorphTable( SAA_Scene *, SAA_Elem *, int, char *, float ); - void MakeWeightedMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int, - int, char *, float ); - void MakeExpressionMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int, - int, char *, float ); - void MakeTexAnim( SAA_Scene *, SAA_Elem *, char * ); - - private: - - 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; - - SI_Error result; - SAA_Scene scene; - SAA_Elem model; - SAA_Database database; - EggGroup *dart; - EggGroup *skeleton; - AnimGroup *rootAnim; - EggJoint *rootJnt; - AnimGroup *animRoot; - AnimGroup *morphRoot; - EggData animData; - - 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; - - std::ofstream eggFile; - std::ofstream animFile; - std::ofstream texFile; -}; - - -/** - * Displays the "what is this program" message, along with the usage message. - * Should be overridden in base classes to describe the current program. - */ -void soft2egg:: -Help() -{ - cerr << - "soft2egg takes a SoftImage scene or model\n" - "and outputs its contents as an egg file\n"; - - Usage(); -} - -/** - * Displays the usage message. - */ -void soft2egg:: -Usage() { - cerr << "\nUsage:\n" - << _commandName << " [opts] (must specify -m or -s)\n\n" - << "Options:\n"; - - ShowOpts(); - cerr << "\n"; -} - - - -/** - * Displays the valid options. Should be extended in base classes to show - * additional options relevant to the current program. - */ -void soft2egg:: -ShowOpts() -{ - cerr << - " -r - Used to provide soft with the resource\n" - " Defaults to 'c:/Softimage/SOFT_3.9.2/3D/test'.\n" - // " Defaults to 'fulufssoft371_mips23Drsrc'.\n" - " -d - Database path.\n" - " -s - Indicates that a scene will be converted.\n" - " -m - Indicates that a model will be converted.\n" - " -t - Specify path to place converted textures.\n" - " -T - Specify filename for texture map listing.\n" - " -S - Specify step for nurbs surface triangulation.\n" - " -M - Specify model output filename. Defaults to scene name.\n" - " -A - Specify anim output filename. Defaults to scene name.\n" - " -N - Specify egg group name.\n" - " -k - Enable soft assignment for geometry.\n" - " -n - Specify egg NURBS representation instead of poly's.\n" - " -p - Specify egg polygon output for geometry.\n" - " -P - Specify frame number for static pose.\n" - " -b - Specify starting frame for animation (default = first).\n" - " -e - Specify ending frame for animation (default = last).\n" - " -f - Specify frame rate for animation playback.\n" - " -a - Compile animation tables if animation present.\n" - " -F - Ignore hierarchy and build a completely flat skeleton.\n" - " -v - Set debug level.\n" - " -x - Shift NURBS parameters to preserve Alias textures.\n" - " -i - Ignore Soft texture uv offsets.\n" - " -u - Use Soft prefix in model names.\n" - " -c - Cancel morph conversion.\n" - " -C - Cancel duv conversion.\n" - " -D - Don't make the output model a character.\n" - " -o - Convert only models with given prefix.\n"; - - EggBase::ShowOpts(); -} - - -/** - * - */ -boolean soft2egg:: -HandleGetopts(char flag, char *optarg, int &optind, int argc, char **argv) -{ - boolean okflag = true; - - switch (flag) - { - case 'r': // Set the resource path for soft. - if ( strcmp( optarg, "" ) ) - { - // Get the path. - rsrc_path = optarg; - fprintf( outStream, "using rsrc path %s\n", rsrc_path ); - } - break; - - case 'd': // Set the database path. - if ( strcmp( optarg, "" ) ) - { - // Get the path. - database_name = optarg; - fprintf( outStream, "using database %s\n", database_name ); - } - break; - - case 's': // Check if its a scene. - if ( strcmp( optarg, "" ) ) - { - // Get scene name. - scene_name = optarg; - fprintf( outStream, "loading scene %s\n", scene_name ); - } - break; - - case 'm': // Check if its a model. - if ( strcmp( optarg, "" ) ) - { - // Get model name. - model_name = optarg; - fprintf( outStream, "loading model %s\n", model_name ); - } - break; - - case 't': // Get converted texture path. - if ( strcmp( optarg, "" ) ) - { - // Get tex path name. - tex_path = optarg; - fprintf( outStream, "texture path: %s\n", tex_path ); - } - break; - - case 'T': // Specify texture list filename. - if ( strcmp( optarg, "") ) - { - // Get the name. - tex_filename = optarg; - fprintf( outStream, "creating texture list file: %s\n", - tex_filename ); - } - break; - case 'S': // Set NURBS step. - if ( strcmp( optarg, "" ) ) - { - nurbs_step = atoi(optarg); - fprintf( outStream, "NURBS step: %d\n", nurbs_step ); - } - break; - - case 'M': // Set model output file name. - if ( strcmp( optarg, "" ) ) - { - eggFileName = optarg; - fprintf( outStream, "Model output filename: %s\n", eggFileName ); - } - break; - - case 'A': // Set anim output file name. - if ( strcmp( optarg, "" ) ) - { - animFileName = optarg; - fprintf( outStream, "Anim output filename: %s\n", animFileName ); - } - break; - - case 'N': // Set egg model name. - if ( strcmp( optarg, "" ) ) - { - eggGroupName = optarg; - fprintf( outStream, "Egg group name: %s\n", eggGroupName ); - } - break; - - case 'o': // Set search_prefix. - if ( strcmp( optarg, "" ) ) - { - search_prefix = optarg; - fprintf( outStream, "Only converting models with prefix: %s\n", - search_prefix ); - } - break; - - case 'h': // print help message - Help(); - exit(1); - break; - - case 'c': // Cancel morph animation conversion - make_morph = FALSE; - fprintf( outStream, "canceling morph conversion\n" ); - break; - - case 'C': // Cancel uv animation conversion - make_duv = FALSE; - fprintf( outStream, "canceling uv animation conversion\n" ); - break; - - case 'D': // Omit the Dart flag - make_dart = FALSE; - fprintf( outStream, "making a non-character model\n" ); - break; - - case 'k': // Enable soft skinning - // make_soft = TRUE; fprintf( outStream, "enabling soft skinning\n" ); - fprintf( outStream, "-k flag no longer necessary\n" ); - break; - - case 'n': // Generate egg NURBS output - make_nurbs = TRUE; - fprintf( outStream, "outputting egg NURBS info\n" ); - break; - - case 'p': // Generate egg polygon output - make_poly = TRUE; - fprintf( outStream, "outputting egg polygon info\n" ); - break; - - case 'P': // Generate static pose from given frame - if ( strcmp( optarg, "" ) ) - { - make_pose = TRUE; - pose_frame = atoi(optarg); - fprintf( outStream, "generating static pose from frame %d\n", - pose_frame ); - } - break; - - case 'a': // Compile animation tables. - make_anim = TRUE; - fprintf( outStream, "attempting to compile anim tables\n" ); - break; - - case 'F': // Build a flat skeleton. - flatten = TRUE; - fprintf( outStream, "building a flat skeleton!!!\n" ); - break; - - case 'x': // Shift NURBS parameters to preserve Alias textures. - shift_textures = TRUE; - fprintf( outStream, "shifting NURBS parameters...\n" ); - break; - - case 'i': // Ignore Soft uv texture offsets - ignore_tex_offsets = TRUE; - fprintf( outStream, "ignoring texture offsets...\n" ); - break; - - case 'u': // Use Soft prefix in model names - use_prefix = TRUE; - fprintf( outStream, "using prefix in model names...\n" ); - break; - - - case 'v': // print debug messages. - if ( strcmp( optarg, "" ) ) - { - verbose = atoi(optarg); - fprintf( outStream, "using debug level %d\n", verbose ); - } - break; - - case 'b': // Set animation start frame. - if ( strcmp( optarg, "" ) ) - { - anim_start = atoi(optarg); - fprintf( outStream, "animation starting at frame: %d\n", - anim_start ); - } - break; - - case 'e': /// Set animation end frame. - if ( strcmp( optarg, "" ) ) - { - anim_end = atoi(optarg); - fprintf( outStream, "animation ending at frame: %d\n", anim_end ); - } - break; - - case 'f': /// Set animation frame rate. - if ( strcmp( optarg, "" ) ) - { - anim_rate = atoi(optarg); - fprintf( outStream, "animation frame rate: %d\n", anim_rate ); - } - break; - - default: - okflag = EggBase::HandleGetopts(flag, optarg, optind, argc, argv); - } - - return (okflag); -} - - - -/** - * Take a float and make sure it is of the body. - */ -int soft2egg:: -isNum( float num ) -{ - return( ( num < HUGE_VAL ) && finite( num ) ); -} - - -/** - * Given a string, return a copy of the string up to the first occurrence of - * '-'. - */ -char *soft2egg:: -GetRootName( const char *name ) -{ - char *hyphen; - char *root; - int len; - - hyphen = strchr( name, '-' ); - len = hyphen-name; - - if ( (hyphen != NULL) && len ) - { - root = (char *)malloc(sizeof(char)*(len+1)); - strncpy( root, name, len ); - root[sizeof(char)*(len)] = '\0'; - } - else - { - root = (char *)malloc( sizeof(char)*(strlen(name)+1)); - strcpy( root, name ); - } - - return( root ); -} - - -/** - * Given a string, return a copy of the string after the last occurence of ' - */ -char *soft2egg:: -RemovePathName( const char *name ) -{ - char *slash; - char *root; - - if ( *name != NULL ) - { - slash = strrchr( name, '/' ); - - root = (char *)malloc( sizeof(char)*(strlen(name)+1)); - - if ( slash != NULL ) - strcpy( root, ++slash ); - else - strcpy( root, name ); - - return( root ); - } - - fprintf( stderr, "Error: RemovePathName received NULL string!\n" ); - return ( (char *)name ); -} - -/** - * Given a string, return that part of the string after the first occurence of - * '-' and before the last occurance of '.' - */ -char *soft2egg:: -GetSliderName( const char *name ) -{ - if ( name != NULL ) - { - strstream newStr; - char *hyphen; - char *end; - - hyphen = strchr( name, '-' ); - - // pull off stuff before first hyphen - if (hyphen != NULL) - { - newStr << ++hyphen; - end = newStr.str(); - } - - char *lastPeriod; - - lastPeriod = strrchr( end, '.' ); - - // ignore stuff after last period - if ( lastPeriod != NULL ) - { - *lastPeriod = '\0'; - } - - if ( verbose >= 1 ) - fprintf( stdout, "slider name: '%s'\n", end ); - - return( end ); - } - - return( (char *)name ); -} - -/** - * Given an element, return a copy of the element's name WITHOUT prefix. - */ -char *soft2egg:: -GetName( SAA_Scene *scene, SAA_Elem *element ) -{ - int nameLen; - char *name; - - // get the name - SAA_elementGetNameLength( scene, element, &nameLen ); - name = (char *)malloc(sizeof(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 *soft2egg:: -GetFullName( SAA_Scene *scene, SAA_Elem *element ) -{ - int nameLen; - char *name; - - // get the name - SAA_elementGetNameLength( scene, element, &nameLen ); - name = (char *)malloc(sizeof(char)*++nameLen); - SAA_elementGetName( scene, element, nameLen, name ); - - int prefixLen; - char *prefix; - - // get the prefix - SAA_elementGetPrefixLength( scene, element, &prefixLen ); - prefix = (char *)malloc(sizeof(char)*++prefixLen); - SAA_elementGetPrefix( scene, element, prefixLen, prefix ); - - strstream fullNameStrm; - - // add 'em together - fullNameStrm << prefix << "-" << name << ends; - - // free( name ); free( prefix ); - - return fullNameStrm.str(); -} - -/** - * Given an element, return a string containing the contents of its MODEL NOTE - * entry - */ -char *soft2egg:: -GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) -{ - - int size; - char *modelNote = NULL; - SAA_Boolean bigEndian; - - - SAA_elementGetUserDataSize( scene, model, "MNOT", &size ); - - if ( size != 0 ) - { - // allocate modelNote string - modelNote = (char *)malloc(sizeof(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 = strchr( modelNote, '\n' ); - if ( eol != NULL) - *eol = '\0'; - else - modelNote[size] = '\0'; - - if ( verbose >= 1 ) - fprintf( outStream, "\nmodelNote = %s\n", - modelNote ); - } - - return modelNote; -} - - -/** - * Given a string, and a number, return a new string consisting of - * "string.number". - */ -char *soft2egg:: -MakeTableName( const char *name, int number ) -{ - strstream namestrm; - - namestrm << name << "." << number << ends; - return namestrm.str(); -} - -/** - * Given a string, find the model in the scene whose name corresponds to the - * given string. - */ -SAA_Elem *soft2egg:: -FindModelByName( char *name, SAA_Scene *scene, SAA_Elem *models, - int numModels ) -{ - char *foundName; - SAA_Elem *foundModel = NULL; - - for ( int model = 0; model < numModels; model++ ) - { - foundName = GetName( scene, &models[model] ); - - if ( !strcmp( name, foundName ) ) - { - if ( verbose >= 1 ) - fprintf( outStream, "foundModel: '%s' = '%s'\n", - name, foundName ); - - foundModel = &models[model]; - return( foundModel ); - } - } - - fprintf( outStream, "findModelByName: failed to find model named: '%s'\n", - name ); - - return ( foundModel ); -} - - -/** - * Given a string, return the string up to the first period. - */ -char *soft2egg:: -DepointellizeName( char *name ) -{ - char *endPtr; - char *newName; - - newName = (char *)malloc(sizeof(char)*(strlen(name)+1)); - sprintf( newName, "%s", name ); - - endPtr = strchr( newName, '.' ); - if ( endPtr != NULL ) - *endPtr = '\0'; - - return ( newName ); -} - - -/** - * Given a string, return a copy of the string without the leading file path, - * and make an rgb file of the same name in the tex_path directory. - */ -char *soft2egg:: -ConvertTexture( SAA_Scene *scene, SAA_Elem *texture ) -{ - char *fileName = NULL; - int fileNameLen = 0; - - // get the texture's name - SAA_texture2DGetPicNameLength( scene, texture, &fileNameLen); - - if ( fileNameLen ) - { - fileName = (char *)malloc(sizeof(char)*++fileNameLen); - SAA_texture2DGetPicName( scene, texture, fileNameLen, fileName ); - } - - // make sure we are not being passed a NULL image, an empty image string or - // the default image created by egg2soft - if ( (fileName != NULL) && strlen( fileName ) && strcmp( fileName, - "/fat/people/gregw/new_test/PICTURES/default") && - ( strstr( fileName, "noIcon" ) == NULL) ) - { - char *texName = NULL; - char *texNamePath = NULL; - char *tmpName = NULL; - char *fileNameExt = NULL; - - // strip off path and add .rgb - tmpName = strrchr( fileName, '/' ); - - if ( tmpName == NULL ) - tmpName = fileName; - else - tmpName++; - - float transp; - - // check for alpha - SAA_texture2DGetTransparency( scene, texture, &transp ); - - if ( transp != 0.0f ) { - texName = (char *)malloc(sizeof(char)*(strlen(tmpName)+6)); - sprintf( texName, "%s.rgba", tmpName ); - } else { - texName = (char *)malloc(sizeof(char)*(strlen(tmpName)+5)); - sprintf( texName, "%s.rgb", tmpName ); - } - - fileNameExt = (char *)malloc(sizeof(char)*(strlen(fileName)+5)); - sprintf( fileNameExt, "%s.pic", fileName ); - - if ( verbose >= 1 ) - fprintf( outStream, "Looking for texture file: '%s'\n", fileNameExt ); - - // try to make conversion of file - int found_file = ( access( fileNameExt, F_OK ) == 0); - - if ( found_file ) - { - if ( tex_path ) - { - texNamePath = (char *)malloc(sizeof(char)*(strlen(tex_path) + - strlen(texName) + 2)); - - sprintf( texNamePath, "%s/%s", tex_path, texName ); - - if ( texFile ) - texFile << texNamePath << ": " << fileNameExt << "\n"; - - // make sure conversion doesn't already exist - if ( (access( texNamePath, F_OK ) != 0) && !texFile ) - { - char *command = (char *)malloc(sizeof(char)* - (strlen(fileNameExt) + strlen(texNamePath) + 20)); - - sprintf( command, "image-resize -1 %s %s", - fileNameExt, texNamePath ); - - if ( verbose >=1 ) - fprintf( outStream, "executing %s\n", command ); - - system( command ); - - // free( command ); - } - else - if ( verbose >=1 ) - fprintf( outStream, "%s already exists!\n", texNamePath ); - } - else - { - if ( verbose >= 1 ) - { - fprintf( outStream, "Warning: No texture path defined" ); - fprintf( outStream, " - No automatic conversion performed\n" ); - } - } - } - else - { - fprintf( outStream, "Warning: Couldn't find texture file: %s\n", - fileNameExt ); - } - - // free( fileNameExt ); - - if (tex_path) - return( texNamePath ); - else - return( texName ); - } - else - { - fprintf( outStream, "Warning: ConvertTexture received NULL fileName\n" ); - return( NULL ); - } -} - -/** - * Given an egg vertex pool, map each vertex therein to a vertex within an - * array of SAA model vertices of size numVert. Mapping is done by closest - * proximity. - */ -int *soft2egg:: -FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) -{ - int *vertMap = NULL; - int vpoolSize = vpool->NumVertices(); - int i,j; - float thisDist; - float closestDist; - int closest; - - - vertMap = (int *)malloc(sizeof(int)*vpoolSize); - - // for each vertex in vpool - for ( i = 0; i < vpoolSize; i++ ) - { - // find closest model vertex - for ( j = 0; j < numVert-1; j++ ) - { - // calculate distance - thisDist = sqrtf( - powf( vpool->Vertex(i)->position[0] - vertices[j].x , 2 ) + - powf( vpool->Vertex(i)->position[1] - vertices[j].y , 2 ) + - powf( vpool->Vertex(i)->position[2] - vertices[j].z , 2 ) ); - - // remember this if its the closest so far - if ( !j || ( thisDist < closestDist ) ) - { - closest = j; - closestDist = thisDist; - } - } - vertMap[i] = closest; - - if ( verbose >= 2 ) - { - fprintf( outStream, "mapping v %d of %d:( %f, %f, %f )\n", i, - vpoolSize, vpool->Vertex(i)->position[0], - vpool->Vertex(i)->position[1], - vpool->Vertex(i)->position[2] ); - fprintf( outStream, "to cv %d of %d:( %f, %f, %f )\tdelta = %f\n", - closest, numVert-1, vertices[closest].x, vertices[closest].y, - vertices[closest].z, closestDist ); - } - } - - return( vertMap ); -} - - -/** - * Given an array of indices that is a map from one set of vertices to - * another, return an array that performs the reverse mapping of the indices - * array - */ -int *soft2egg:: -MakeIndexMap( int *indices, int numIndices, int mapSize ) -{ - int i, j; - - // allocate map array - int *map = (int *)malloc(sizeof(int)*mapSize); - - if ( map != NULL ) - { - for ( i = 0; i < mapSize; i++ ) - { - j = 0; - int found = 0; - while( j < numIndices ) - { - if ( indices[j] == i ) - { - map[i] = j; - if ( verbose >= 2 ) - fprintf( outStream, "map[%d] = %d\n", i, map[i] ); - found = 1; - break; - } - j++; - } - if ( !found) - { - if ( verbose >= 2 ) - fprintf( outStream, "Warning: orphan vertex (%d)\n", i ); - // default to -1 for now - map[i] = -1; - } - } - } - else - fprintf( outStream, "Not enough Memory for index Map...\n"); - - return( map ); -} - -/** - * given a vertex, find its corresponding shape vertex and return its index. - */ -int soft2egg:: -findShapeVert( SAA_DVector vertex, SAA_DVector *vertices, int numVert ) -{ - int i; - int found = 0; - - for ( i = 0; i < numVert && !found ; i++ ) - { - if ( ( vertex.x == vertices[i].x ) && - ( vertex.y == vertices[i].y ) && - ( vertex.z == vertices[i].z ) ) - { - found = 1; - - if ( verbose >= 2) - fprintf( outStream, "found shape vert at index %d\n", i ); - } - } - - if (!found ) - i = -1; - else - i--; - - return( i ); -} - - -/** - * Open the SI database and grab the scene & model info - */ -void soft2egg:: -LoadSoft() -{ - int i; - - if ( (scene_name == NULL && model_name == NULL) || database_name == NULL ) - { - Usage(); - exit( 1 ); - } - - if ((result = SAA_Init(rsrc_path, FALSE)) != SI_SUCCESS) - { - fprintf( outStream, "Error: Couldn't get resource path!\n"); - exit( 1 ); - } - - if ((result = SAA_databaseLoad(database_name, &database)) != SI_SUCCESS) - { - fprintf( outStream, "Error: Couldn't load database!\n"); - exit( 1 ); - } - - if ((result = SAA_sceneGetCurrent(&scene)) == SI_SUCCESS) - { - // load scene if present - if ( scene_name != NULL ) - { - SAA_sceneLoad( &database, scene_name, &scene ); - - // if no egg filename specified, make up a name - if ( eggFileName == NULL ) - { - eggFileName = (char *)malloc(sizeof(char)* - (strlen( scene_name ) + 14 )); - sprintf( eggFileName, "%s", DepointellizeName(scene_name) ); - if ( make_nurbs ) - strcat( eggFileName, "-nurb" ); - strcat( eggFileName, "-mod.egg" ); - } - - // open an output file for the geometry if necessary - if ( make_poly || make_nurbs ) - { - unlink( eggFileName ); - eggFile.open( eggFileName, ios::out, 0666 ); - - if ( !eggFile ) - { - fprintf( outStream, "Couldn't open output file: %s\n", - eggFileName ); - exit( 1 ); - } - } - - // open an output file for texture list if specified - if ( tex_filename != NULL ) - { - unlink( tex_filename ); - texFile.open( tex_filename, ios::out, 0666 ); - - if ( !texFile ) - { - fprintf( outStream, "Couldn't open output file: %s\n", - tex_filename ); - exit( 1 ); - } - } - - if ( SAA_updatelistGet( &scene ) == SI_SUCCESS ) - { - float time; - - fprintf( outStream, "setting Scene to frame %d...\n", pose_frame ); - // SAA_sceneSetPlayCtrlCurrentFrame( &scene, pose_frame ); - SAA_frame2Seconds( &scene, pose_frame, &time ); - SAA_updatelistEvalScene( &scene, time ); - sginap( 100 ); - SAA_updatelistEvalScene( &scene, time ); - if ( make_pose ) - SAA_sceneFreeze( &scene ); - } - - int numModels; - SAA_Elem *models; - - SAA_sceneGetNbModels( &scene, &numModels ); - fprintf( outStream, "Scene has %d model(s)...\n", numModels ); - - if ( numModels ) - { - // allocate array of models - models = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numModels); - - if ( models != NULL ) - { - char *rootName = GetRootName( eggFileName ); - - if ( eggGroupName == NULL ) - dart = _data.CreateGroup( NULL, rootName ); - else - dart = _data.CreateGroup( NULL, eggGroupName ); - - if (make_dart) - dart->flags |= EF_DART; - - AnimGroup *rootTable; - - rootTable = animData.CreateTable( NULL, eggFileName ); - - if ( eggGroupName == NULL ) - animRoot = animData.CreateBundle( rootTable, rootName ); - else - animRoot = animData.CreateBundle( rootTable, - eggGroupName ); - - // propagate commet to anim data - animData.root_group.children.push_front( - new EggComment( _commandLine ) ); - - if ( verbose >= 1 ) - fprintf( outStream, "made animRoot: %s\n", rootName ); - - SAA_sceneGetModels( &scene, numModels, models ); - - for ( i = 0; i < numModels; i++ ) - { - int level; - - SAA_elementGetHierarchyLevel( &scene, &models[i], &level ); - if ( !level ) - { - if ( verbose >= 1 ) - fprintf( outStream, - "\negging scene model[%d]\n", i ); - - MakeEgg( dart, NULL, NULL, &scene, &models[i] ); - } - } - - if ( make_poly || make_nurbs ) - { - // generate soft skinning assignments if desired disabled 1199 - // to streamline joint assignments. all joint assignments now - // done here. Hard & Soft. if ( make_soft) - { - char *name; - char *fullname; - SAA_Boolean isSkeleton; - - // search through models and look for skeleton parts - for ( i = 0; i < numModels; i++ ) - { - SAA_modelIsSkeleton( &scene, &models[i], &isSkeleton ); - - // get fullname for splitting files, but only use it - // in file if requested - fullname = GetFullName( &scene, &models[i] ); - if ( use_prefix ) - name = fullname; - else - name = GetName( &scene, &models[i] ); - - // split - if ( strstr( fullname, search_prefix ) != NULL ) - { - // for every skel part: get soft skin info - if ( isSkeleton ) - MakeSoftSkin( &scene, &models[i], models, - numModels, name ); - } - - // free( name ); - } - - // make sure all vertices were assigned via soft skinning - // - if not hard assign them - for ( i = 0; i < numModels; i++ ) - { - // get fullname for splitting files, but only use it - // in file if requested - fullname = GetFullName( &scene, &models[i] ); - if ( use_prefix ) - name = fullname; - else - name = GetName( &scene, &models[i] ); - - // split - if ( strstr( fullname, search_prefix ) != NULL ) - CleanUpSoftSkin( &scene, &models[i], name ); - - // free( name ); - } - - } - - - // put the skeleton data into the egg data - dart->StealChildren( *skeleton ); - - // make sure all elements have unique names - _data.UniquifyNames(); - - // write out the geometry data if requested if ( make_poly || - // make_nurbs ) { - eggFile << _data << "\n"; - fprintf( outStream, "\nwriting out %s...\n", eggFileName ); - eggFile.close(); - } - - // close texture list file if opened - if ( texFile ) - texFile.close(); - - // generate animation data if desired - if ( make_anim ) - { - if ( animFileName == NULL ) - { - animFileName = (char *)malloc(sizeof(char)* - (strlen(scene_name)+ 10 )); - sprintf( animFileName, "%s", DepointellizeName(scene_name) ); - strcat( animFileName, "-chan.egg" ); - } - - unlink( animFileName ); - animFile.open( animFileName, ios::out, 0666 ); - - if ( !animFile ) - { - fprintf( outStream, "Couldn't open output file: %s\n", - animFileName ); - exit( 1 ); - } - - int frame; - // int frameStep; - float time; - - // get all the animation frame info if not specified on the - // command line - if (anim_start == -1000) - SAA_sceneGetPlayCtrlStartFrame( &scene, &anim_start ); - - if (anim_end == -1000) - SAA_sceneGetPlayCtrlEndFrame( &scene, &anim_end ); - - // SAA_sceneGetPlayCtrlFrameStep( &scene, &frameStep ); - - fprintf( outStream, "\nframeStart = %d\n", anim_start ); - fprintf( outStream, "frameEnd = %d\n", anim_end ); - // fprintf( outStream, "frameStep = %d\n", frameStep ); - - // start at first frame and go to last - for ( frame = anim_start; frame <= anim_end; - frame += 1) - { - SAA_frame2Seconds( &scene, frame, &time ); - SAA_updatelistEvalScene( &scene, time ); - sginap( 100 ); - SAA_updatelistEvalScene( &scene, time ); - fprintf( outStream, "\n> animating frame %d\n", frame ); - - // for each model - for ( i = 0; i < numModels; i++ ) - { - char *name; - char *fullname; - SAA_Boolean isSkeleton; - SAA_ModelType type; - - SAA_modelIsSkeleton( &scene, &models[i], &isSkeleton ); - - // get fullname for splitting files, but only use it - // in file if requested - fullname = GetFullName( &scene, &models[i] ); - if ( use_prefix ) - name = fullname; - else - name = GetName( &scene, &models[i] ); - - // split - if ( strstr( fullname, search_prefix ) != NULL ) - { - // make the morph table for this critter - if ( make_morph ) - { - MakeMorphTable( &scene, &models[i], models, - numModels, name, time ); - } - } - - // find out what type of node we're dealing with - result = SAA_modelGetType( &scene, &models[i], &type ); - - int size; - - // check for uv texture animation - SAA_elementGetUserDataSize( &scene, &models[i], - "TEX_OFFSETS", &size ); - - // if so, update for this frame if desired - if ( ( size != 0 ) && make_duv ) - MakeTexAnim( &scene, &models[i], name ); - - // if we have a skeleton or something that acts like - // one - build anim tables - if ( isSkeleton || - ( strstr( name, "joint") != NULL ) ) - MakeAnimTable( &scene, &models[i], name ); - - // free( name ); - } - - if ( verbose >= 1 ) - fprintf( outStream, "\n" ); - } - - animFile << animData << "\n"; - fprintf( outStream, "\nwriting out %s...\n", animFileName ); - animFile.close(); - } - - // free( models ); - - } - else - fprintf( outStream, "Error: Not enough Memory for models...\n"); - } - } - // otherwise try to load a model - else if ( model_name != NULL ) - { - - if ( eggFileName == NULL ) - { - eggFileName = - (char *)malloc(sizeof(char)*(strlen( model_name )+13)); - sprintf( eggFileName, "%s", DepointellizeName( model_name ) ); - - if ( make_nurbs ) - strcat( eggFileName, "-nurb" ); - strcat( eggFileName, "-mod.egg" ); - } - - eggFile.open( eggFileName ); - - if ( !eggFile ) - { - fprintf( outStream, "Couldn't open output file: %s\n", - eggFileName ); - exit( 1 ); - } - - if ((result = - SAA_elementLoad(&database, &scene, model_name, &model)) - == SI_SUCCESS) - { - fprintf( outStream, "Loading single model...\n"); - MakeEgg( NULL, NULL, NULL, &scene, &model ); - } - - eggFile << _data << "\n"; - } - } - -} - -/** - * Make egg geometry from a given model. This include textures, tex coords, - * colors, normals, and joints. - */ -void soft2egg:: -MakeEgg( EggGroup *parent, EggJoint *lastJoint, AnimGroup *lastAnim, - SAA_Scene *scene, SAA_Elem *model ) -{ - char *name; - char *fullname; - SAA_ModelType type; - int id = 0; - int numShapes; - int numTri; - int numVert; - int numTexLoc = 0; - int numTexGlb = 0; - int i, j; - float matrix[4][4]; - float *uScale = NULL; - float *vScale = NULL; - float *uOffset = NULL; - float *vOffset = NULL; - SAA_Boolean uv_swap = FALSE; - void *relinfo; - SAA_SubElem *triangles = NULL; - SAA_Elem *materials = NULL; - SAA_SubElem *cvertices = NULL; - SAA_DVector *cvertPos = NULL; - SAA_DVector *vertices = NULL; - SAA_DVector *normals = NULL; - int *indices = NULL; - int *indexMap = NULL; - int *numTexTri = NULL; - SAA_Elem *textures = NULL; - char **texNameArray; - float *uCoords = NULL; - float *vCoords = NULL; - SAA_GeomType gtype = SAA_GEOM_ORIGINAL; - SAA_Boolean visible; - - // find out what type of node we're dealing with - result = SAA_modelGetType( scene, model, &type ); - - if ( verbose >= 1 ) - { - if ( type == SAA_MNILL ) - fprintf( outStream, "encountered null\n"); - else if ( type == SAA_MPTCH ) - fprintf( outStream, "encountered patch\n" ); - else if ( type == SAA_MFACE ) - fprintf( outStream, "encountered face\n" ); - else if ( type == SAA_MSMSH ) - fprintf( outStream, "encountered mesh\n" ); - else if ( type == SAA_MJNT ) - fprintf( outStream, "encountered joint\n" ); - else if ( type == SAA_MSPLN ) - fprintf( outStream, "encountered spline\n" ); - else if ( type == SAA_MMETA ) - fprintf( outStream, "encountered meta element\n" ); - else if ( type == SAA_MBALL ) - fprintf( outStream, "encountered metaball\n" ); - else if ( type == SAA_MNCRV ) - fprintf( outStream, "encountered nurb curve\n" ); - else if ( type == SAA_MNSRF ) - fprintf( outStream, "encountered nurbs surf\n" ); - else - fprintf( outStream, "encountered unknown type: %d\n", type ); - } - - // Get the name of the model - - // Get the FULL name of the model - fullname = GetFullName( scene, model ); - - if ( use_prefix ) - { - // Get the FULL name of the trim curve - name = fullname; - } - else - { - // Get the name of the trim curve - name = GetName( scene, model ); - } - - if ( verbose >= 1 ) - fprintf( outStream, "element name <%s>\n", name ); - - fflush( outStream ); - - // get the model's matrix - SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL, matrix ); - - if ( verbose >= 2 ) - { - fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[0][0], - matrix[0][1], matrix[0][2], matrix[0][3] ); - fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[1][0], - matrix[1][1], matrix[1][2], matrix[1][3] ); - fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[2][0], - matrix[2][1], matrix[2][2], matrix[2][3] ); - fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[3][0], - matrix[3][1], matrix[3][2], matrix[3][3] ); - } - - // check to see if this is a branch we don't want to descend - this will - // prevent creating geometry for animation control structures - if ( (strstr( name, "con-" ) == NULL) && - (strstr( name, "con_" ) == NULL) && - (strstr( name, "fly_" ) == NULL) && - (strstr( name, "fly-" ) == NULL) && - (strstr( name, "camRIG" ) == NULL) && - (strstr( name, "bars" ) == NULL) && - // split - (strstr( fullname, search_prefix ) != NULL) ) - { - - // if making a pose - get deformed geometry - if ( make_pose ) - gtype = SAA_GEOM_DEFORMED; - - // Get the number of key shapes - SAA_modelGetNbShapes( scene, model, &numShapes ); - if ( verbose >= 1 ) - fprintf( outStream, "MakeEgg: num shapes: %d\n", numShapes); - - // if multiple key shapes exist create table entries for each - if ( (numShapes > 0) && make_morph ) - { - has_morph = 1; - - // make sure root morph table exists - if ( morphRoot == NULL ) - morphRoot = animData.CreateTable( animRoot, "morph" ); - - char *tableName; - - // create morph table entry for each key shape (start at second shape - // - as first is the original geometry) - for ( i = 1; i < numShapes; i++ ) - { - tableName = MakeTableName( name, i ); - SAnimTable *table = new SAnimTable( ); - table->name = tableName; - table->fps = anim_rate; - morphRoot->children.push_back( table ); - if ( verbose >= 1 ) - fprintf( outStream, "created table named: '%s'\n", tableName ); - } - - // free( tableName ); - } - - SAA_modelGetNodeVisibility( scene, model, &visible ); - if ( verbose >= 1 ) - fprintf( outStream, "model visibility: %d\n", visible ); - - // Only create egg polygon data if: the node is visible, and its not a - // NULL or a Joint, and we're outputing polys (or if we are outputing - // NURBS and the model is a poly mesh or a face) - if ( visible && - (type != SAA_MNILL) && - (type != SAA_MJNT) && - ((make_poly || - (make_nurbs && ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) - || (!make_poly && !make_nurbs && make_duv && - ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) - ) - { - // If the model is a NURBS in soft, set its step before tesselating - if ( type == SAA_MNSRF ) - SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step ); - - // If the model is a PATCH in soft, set its step before tesselating - else if ( type == SAA_MPTCH ) - SAA_patchSetStep( scene, model, nurbs_step, nurbs_step ); - - // Get the number of triangles - result = SAA_modelGetNbTriangles( scene, model, gtype, id, &numTri); - if ( verbose >= 1 ) - fprintf( outStream, "triangles: %d\n", numTri); - - if ( result != SI_SUCCESS ) - { - if ( verbose >= 1 ) { - fprintf( outStream, - "Error: couldn't get number of triangles!\n" ); - fprintf( outStream, "\tbailing on model: '%s'\n", name ); - } - return; - } - - // check to see if surface is also skeleton... - SAA_Boolean isSkeleton = FALSE; - - SAA_modelIsSkeleton( scene, model, &isSkeleton ); - - // check to see if this surface 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" ) != NULL) ) - { - if ( verbose >= 1 ) - fprintf( outStream, "animating Polys as joint!!!\n" ); - - MakeJoint( scene, lastJoint, lastAnim, model, name ); - } - - // model is not a null and has no triangles! - if ( !numTri ) - { - if ( verbose >= 1 ) - fprintf( outStream, "no triangles!\n"); - } - else - { - // allocate array of triangles - triangles = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTri); - if ( triangles != NULL ) - { - // triangulate model and read the triangles into array - SAA_modelGetTriangles( scene, model, gtype, id, numTri, triangles ); - } - else - fprintf( outStream, "Not enough Memory for triangles...\n"); - - // allocate array of materials - materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTri); - if ( materials != NULL ) - { - // read each triangle's material into array - SAA_triangleGetMaterials( scene, model, numTri, triangles, - materials ); - } - else - fprintf( outStream, "Not enough Memory for materials...\n"); - - // allocate array of textures per triangle - numTexTri = (int *)malloc(sizeof(int)*numTri); - - // find out how many local textures per triangle - for ( i = 0; i < numTri; i++ ) - { - result = SAA_materialRelationGetT2DLocNbElements( scene, - &materials[i], FALSE, &relinfo, &numTexTri[i] ); - - // polytex - if ( result == SI_SUCCESS ) - numTexLoc += numTexTri[i]; - } - - // don't need this anymore... free( numTexTri ); - - // get local textures if present - if ( numTexLoc ) - { - // ASSUME only one texture per material - textures = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTri); - - for ( i = 0; i < numTri; i++ ) - { - // and read all referenced local textures into array - SAA_materialRelationGetT2DLocElements( scene, &materials[i], - TEX_PER_MAT , &textures[i] ); - } - - if ( verbose >= 1 ) - fprintf( outStream, "numTexLoc = %d\n", numTexLoc); - } - // if no local textures, try to get global textures - else - { - SAA_modelRelationGetT2DGlbNbElements( scene, model, - FALSE, &relinfo, &numTexGlb ); - - if ( numTexGlb ) - { - // ASSUME only one texture per model - textures = (SAA_Elem *)malloc(sizeof(SAA_Elem)); - - // get the referenced texture - SAA_modelRelationGetT2DGlbElements( scene, model, - TEX_PER_MAT, textures ); - - if ( verbose >= 1 ) - fprintf( outStream, "numTexGlb = %d\n", numTexGlb); - } - } - - // allocate array of control vertices - cvertices = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTri*3); - if ( cvertices != NULL ) - { - // read each triangle's control vertices into array - SAA_triangleGetCtrlVertices( scene, model, gtype, id, - numTri, triangles, cvertices ); - - if ( verbose >= 2 ) - { - cvertPos = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numTri*3); - SAA_ctrlVertexGetPositions( scene, model, numTri*3, - cvertices, cvertPos); - - for ( i=0; i < numTri*3; i++ ) - { - fprintf( outStream, "cvert[%d] = %f %f %f %f\n", i, - cvertPos[i].x, cvertPos[i].y, cvertPos[i].z, - cvertPos[i].w ); - } - } - } - else - fprintf( outStream, "Not enough Memory for control vertices...\n"); - - // allocate array of control vertex indices this array maps from the - // redundant cvertices array into the unique vertices array - // (cvertices->vertices) - indices = (int *)malloc(sizeof(int)*numTri*3); - if ( indices != NULL ) - { - for ( i=0; i < numTri*3; i++ ) - indices[i] = 0; - - SAA_ctrlVertexGetIndices( scene, model, numTri*3, - cvertices, indices ); - - if ( verbose >= 2 ) - for ( i=0; i < numTri*3; i++ ) - fprintf( outStream, "indices[%d] = %d\n", i, indices[i] ); - } - else - fprintf( outStream, "Not enough Memory for indices...\n"); - - // get number of UNIQUE vertices in model - SAA_modelGetNbTriVertices( scene, model, &numVert ); - - if ( verbose >= 2 ) - fprintf( outStream, "num unique verts = %d\n", numVert ); - - // allocate array of vertices - vertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numVert); - - // get the UNIQUE vertices of all triangles in model - SAA_modelGetTriVertices( scene, model, numVert, vertices ); - - if ( verbose >= 2 ) - { - for ( i=0; i < numVert; i++ ) - { - fprintf( outStream, "vertices[%d] = %f ", i, vertices[i].x ); - fprintf( outStream, "%f %f %f\n", vertices[i].y, - vertices[i].z, vertices[i].w ); - } - } - - // allocate indexMap array we contruct this array to map from the - // unique vertices array to the redundant cvertices array - it will - // save us from doing repetitive searches later - indexMap = MakeIndexMap( indices, numTri*3, numVert ); - - // allocate array of normals - normals = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numTri*3); - if ( normals != NULL ) - { - // read each control vertex's normals into an array - SAA_ctrlVertexGetNormals( scene, model, numTri*3, - cvertices, normals ); - } - else - fprintf( outStream, "Not enough Memory for normals...\n"); - - if ( verbose >= 2 ) - { - for ( i=0; i= 2 ) - { - for ( i=0; i= 2 ) - fprintf( outStream, " tritex[%d] named: %s\n", i, - texNameArray[i] ); - - SAA_texture2DGetUVSwap( scene, &textures[i], &uv_swap ); - - if ( verbose >= 2 ) - if ( uv_swap == TRUE ) - fprintf( outStream, " swapping u and v...\n" ); - - SAA_texture2DGetUScale( scene, &textures[i], &uScale[i] ); - SAA_texture2DGetVScale( scene, &textures[i], &vScale[i] ); - SAA_texture2DGetUOffset( scene, &textures[i], &uOffset[i] ); - SAA_texture2DGetVOffset( scene, &textures[i], &vOffset[i] ); - - if ( verbose >= 2 ) - { - fprintf(outStream, "tritex[%d] uScale: %f vScale: %f\n", i, uScale[i], vScale[i] ); - fprintf(outStream, " uOffset: %f vOffset: %f\n", - uOffset[i], vOffset[i] ); - } - - - SAA_texture2DGetRepeats( scene, &textures[i], &uRepeat, - &vRepeat ); - - if ( verbose >= 2 ) - { - fprintf(outStream, "uRepeat = %d, vRepeat = %d\n", - uRepeat, vRepeat ); - } - } - else - { - if ( verbose >= 2 ) - { - fprintf( outStream, "Invalid texture...\n"); - fprintf( outStream, " tritex[%d] named: (null)\n", i ); - } - } - } - -/* - * debug for ( i = 0; i < numTri; i++ ) { if ( texNameArray[i] != NULL ) - * fprintf( outStream, " tritex[%d] named: %s\n", i, texNameArray[i] ); else - * fprintf( outStream, " tritex[%d] named: (null)\n", i ); } - */ - } - // make sure we have textures before we get t-coords - else if ( numTexGlb ) - { - SAA_Boolean valid; - - // check to see if texture is present - SAA_elementIsValid( scene, textures, &valid ); - - // texture present - get the name and uv info - if ( valid ) - { - SAA_texture2DGetUVSwap( scene, textures, &uv_swap ); - - if ( verbose >= 1 ) - if ( uv_swap == TRUE ) - fprintf( outStream, " swapping u and v...\n" ); - - // allocate arrays for u & v coords - uCoords = (float *)malloc(sizeof(float)*numTri*numTexGlb*3); - vCoords = (float *)malloc(sizeof(float)*numTri*numTexGlb*3); - - for ( i = 0; i < numTri*numTexGlb*3; i++ ) - { - uCoords[i] = vCoords[i] = 0.0f; - } - - // read the u & v coords into the arrays - if ( uCoords != NULL && vCoords != NULL) - { - SAA_triCtrlVertexGetGlobalUVTxtCoords( scene, model, - numTri*3, cvertices, numTexGlb, textures, - uCoords, vCoords ); - } - else - fprintf( outStream, "Not enough Memory for texture coords...\n"); - - if ( verbose >= 2 ) - { - for ( i=0; i= 1 ) - fprintf( outStream, " global tex named: %s\n", - texNameArray ); - - // allocate arrays of texture info - uScale = ( float *)malloc(sizeof(float)); - vScale = ( float *)malloc(sizeof(float)); - uOffset = ( float *)malloc(sizeof(float)); - vOffset = ( float *)malloc(sizeof(float)); - - SAA_texture2DGetUScale( scene, textures, uScale ); - SAA_texture2DGetVScale( scene, textures, vScale ); - SAA_texture2DGetUOffset( scene, textures, uOffset ); - SAA_texture2DGetVOffset( scene, textures, vOffset ); - - if ( verbose >= 1 ) - { - fprintf( outStream, " global tex uScale: %f vScale: %f\n", - *uScale, *vScale ); - fprintf( outStream, " uOffset: %f vOffset: %f\n", - *uOffset, *vOffset ); - } - - SAA_texture2DGetRepeats( scene, textures, &uRepeat, - &vRepeat ); - - if ( verbose >= 2 ) - { - fprintf(outStream, "uRepeat = %d, vRepeat = %d\n", - uRepeat, vRepeat ); - } - } - else fprintf( outStream, "Invalid texture...\n"); - } - - // make the egg vertex pool - EggVertexPool *pool = _data.CreateVertexPool( parent, name ); - - for ( i = 0; i < numVert; i++ ) - { - pfVec3 eggVert; - pfVec3 eggNorm; - - // convert to global coords - SAA_DVector local = vertices[i]; - SAA_DVector global; - - _VCT_X_MAT( global, local, matrix ); - - // set vertices array to reflect global coords vertices[i].x = - // global.x; vertices[i].y = global.y; vertices[i].z = global.z; - - // eggVert.set( vertices[i].x, vertices[i].y, vertices[i].z ); - - // we'll preserve original verts for now - eggVert.set( global.x, global.y, global.z ); - - local = normals[indexMap[i]]; - - _VCT_X_MAT( global, local, matrix ); - - eggNorm.set( global.x, global.y, global.z ); - eggNorm.normalize(); - - pool->AddVertex( eggVert, i ); - pool->Vertex(i)->attrib.SetNormal( eggNorm ); - - // translate local uv's to global and add to vertex pool - if ( numTexLoc && (uCoords != NULL && vCoords !=NULL )) - { - float u, v; - - if ( ignore_tex_offsets ) { - u = uCoords[indexMap[i]]; - v = 1.0f - vCoords[indexMap[i]]; - } else { - u = (uCoords[indexMap[i]] - uOffset[indexMap[i]/3]) / - uScale[indexMap[i]/3]; - - v = 1.0f - ((vCoords[indexMap[i]] - vOffset[indexMap[i]/3]) / - vScale[indexMap[i]/3]); - } - - if ( isNum(u) && isNum(v) ) - { - if ( uv_swap == TRUE ) - pool->Vertex(i)->attrib.SetUV( v, u ); - else - pool->Vertex(i)->attrib.SetUV( u, v ); - } - } - else if ( numTexGlb && (uCoords != NULL && vCoords !=NULL ) ) - { - float u, v; - - if ( ignore_tex_offsets ) { - u = uCoords[indexMap[i]]; - v = 1.0f - vCoords[indexMap[i]]; - } else { - u = (uCoords[indexMap[i]] - *uOffset) / *uScale; - v = 1.0f - (( vCoords[indexMap[i]] - *vOffset ) / *vScale); - } - - if ( isNum(u) && isNum(v) ) - { - if ( uv_swap == TRUE ) - pool->Vertex(i)->attrib.SetUV( v, u ); - else - pool->Vertex(i)->attrib.SetUV( u, v ); - } - } - - // if we've encountered textures and we desire duv anims - if (( numTexLoc || numTexGlb ) && make_duv ) - { - int numExp; - SAA_Elem *tex; - - // grab the current texture - if ( numTexLoc ) - tex = &textures[0]; - else - tex = textures; - - // find how many expressions for this shape - SAA_elementGetNbExpressions( scene, tex, NULL, FALSE, - &numExp ); - - // if it has expressions we'll assume its animated - if ( numExp ) - { - // if animated object make base duv's, animtables for the - // duv's and store the original offsets - strstream uName, vName; - - // create duv target names - uName << name << ".u" << ends; - vName << name << ".v" << ends; - - // only create tables and store offsets on a per model - // basis (not per vertex) - if ( !i ) - { - - // make sure root morph table exists - if ( morphRoot == NULL ) - morphRoot = animData.CreateTable( animRoot, - "morph" ); - - // create morph table entry for each duv - SAnimTable *uTable = new SAnimTable( ); - uTable->name = uName.str(); - uTable->fps = anim_rate; - morphRoot->children.push_back( uTable ); - if ( verbose >= 1 ) - fprintf( outStream, "created duv table named: %s\n", uName.str() ); - - SAnimTable *vTable = new SAnimTable( ); - vTable->name = vName.str(); - vTable->fps = anim_rate; - morphRoot->children.push_back( vTable ); - if ( verbose >= 1 ) - fprintf( outStream, "created duv table named: %s\n", vName.str() ); - - float texOffsets[4]; - - if ( numTexGlb ) - { - texOffsets[0] = *uOffset; - texOffsets[1] = *vOffset; - texOffsets[2] = *uScale; - texOffsets[3] = *vScale; - } - else - { - texOffsets[0] = uOffset[indexMap[i]/3]; - texOffsets[1] = vOffset[indexMap[i]/3]; - texOffsets[2] = uScale[indexMap[i]/3]; - texOffsets[3] = vScale[indexMap[i]/3]; - } - - // remember original texture offsets future reference - SAA_elementSetUserData( scene, model, "TEX_OFFSETS", - sizeof( texOffsets ), TRUE, (void **)&texOffsets ); - } - - EggMorphOffset *duvU; - EggMorphOffset *duvV; - - // generate base duv's for this vertex - duvU = new EggMorphOffset( uName.str(), 1.0 , 0.0 ); - pool->Vertex(i)->attrib.uv_morphs.push_back( *duvU ); - - duvV = new EggMorphOffset( vName.str(), 0.0 , 1.0 ); - pool->Vertex(i)->attrib.uv_morphs.push_back( *duvV ); - - } // if ( numExp ) - - } // if ( numTexLoc || numTexGlb ) - - } // for ( i = 0; i < numVert; i++ ) - - // if model has key shapes, generate vertex offsets - if ( has_morph && make_morph ) - MakeVertexOffsets( scene, model, type, numShapes, numVert, - vertices, matrix, name ); - - - // create vertex ref list for all polygons in the model - EggVertexRef *vref; - - vref = new EggVertexRef( pool); - for ( i = 0; i < numVert; i++ ) - { - // add each vert in pool to last joint for hard skinning - vref->indices.push_back( EggVertexIndex( i ) ); - } - -/* - * hard assign poly geometry if no soft-skinning requested disabled 1199 to - * streamline joint assignments. all hard-skinning now done in - * CleanUpSoftSkin. if ( !make_soft ) { if ( lastJoint != NULL ) { - * lastJoint->vrefs.AddUniqueNode( *vref ); - */ - - // if ( verbose >= 1 ) fprintf( outStream, "hard-skinning %s - // (%d vertices)\n", name, i+1 ); } } - - // make an egg group to hold all triangles - EggGroup *group = _data.CreateGroup( parent, name); - - // make this group the current parent - parent = group; - - EggPolygon *poly = NULL; - EggColor *cref = NULL; - EggTexture *tref = NULL; - - // for each triangle - for ( i = 0; i < numTri*3; i+=3 ) - { - float r,g,b,a; - pfVec4 color; - - // make egg poly for each traingle and reference the appropriate - // vertex in the pool - poly = _data.CreatePolygon( group, pool ); - poly->AddVertex(indices[i]); - poly->AddVertex(indices[i+1]); - poly->AddVertex(indices[i+2]); - - // check for back face flag in model note info - char *modelNoteStr = GetModelNoteInfo( scene, model ); - - if ( modelNoteStr != NULL ) - { - if ( strstr( modelNoteStr, "bface" ) != NULL ) - poly->flags |= EG_BFACE; - } - - // check to see if material is present - SAA_Boolean valid; - SAA_elementIsValid( scene, &materials[i/3], &valid ); - - // material present - get the color - if ( valid ) - { - SAA_materialGetDiffuse( scene, &materials[i/3], &r, &g, &b ); - SAA_materialGetTransparency( scene, &materials[i/3], &a ); - color.set( r, g, b, 1.0f - a ); - } - // no material - default to white - else - color.set( 1.0, 1.0, 1.0, 1.0 ); - - cref = _data.CreateColor(color); - poly->attrib.SetCRef(cref); - - strstream uniqueTexName; - - if (numTexLoc) - { - // polytex - if ( (texNameArray[i/3] != NULL) && - (strcmp(texNameArray[i/3], "NULL") != 0) ) - { - // append unique identifier to texname for this particular - // object - uniqueTexName << name << "-" - << RemovePathName(texNameArray[i/3]); - - tref = _data.CreateTexture( texNameArray[i/3], - uniqueTexName.str() ); - - if ( verbose >= 1 ) - fprintf( outStream, " tritex[%d] named: %s\n", i/3, - texNameArray[i/3] ); - } - } - else if ( numTexGlb ) - { - if ( texNameArray != NULL ) - { - // append unique identifier to texname for this particular - // object - uniqueTexName << name << "-" - << RemovePathName(*texNameArray); - - tref = _data.CreateTexture( *texNameArray, - uniqueTexName.str() ); - - if ( verbose >= 1 ) - fprintf( outStream, " tritex named: %s\n", - *texNameArray ); - } - } - - // set the clamp on the texture - if ( tref != NULL ) - { - if ( uRepeat > 0 ) - tref->wrapu = EggTexture::WM_repeat; - else - tref->wrapu = EggTexture::WM_clamp; - - if ( vRepeat > 1 ) - tref->wrapv = EggTexture::WM_repeat; - else - tref->wrapv = EggTexture::WM_clamp; - - poly->attrib.SetTRef(tref); - } - - } - - // we're done - trash triangles... - SAA_modelClearTriangles( scene, model ); - -/* - * free molloc'd memory free( triangles ); free( materials ); free( normals ); - * free( cvertices ); free( vertices ); free( indices ); free( indexMap ); - */ - - // free these only if they were malloc'd for textures - if (numTexLoc || numTexGlb) - { -/* - * free( textures ); free( uCoords ); free( vCoords ); free( texNameArray ); - * free( uScale ); free( vScale ); free( uOffset ); free( vOffset ); - */ - } - } - } - else - { - // check to see if its a nurbs surface - if ( (type == SAA_MNSRF) && ( visible ) && (( make_nurbs ) - || ( !make_nurbs && !make_poly && make_duv )) ) - { - // check to see if NURBS is also skeleton... - SAA_Boolean isSkeleton = FALSE; - - SAA_modelIsSkeleton( scene, model, &isSkeleton ); - - // check to see if this NURBS 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" ) != NULL) ) - { - MakeJoint( scene, lastJoint, lastAnim, model, name ); - geom_as_joint = 1; - if ( verbose >= 1 ) - fprintf( outStream, "animating NURBS as joint!!!\n" ); - } - - EggNurbsSurface *eggNurbsSurf = new EggNurbsSurface( name ); - int uDegree, vDegree; - - // create nurbs representation of surface - SAA_nurbsSurfaceGetDegree( scene, model, &uDegree, &vDegree ); - eggNurbsSurf->u_order = uDegree + 1; - eggNurbsSurf->v_order = vDegree + 1; - if ( verbose >= 1 ) - { - fprintf( outStream, "nurbs degree: %d u, %d v\n", - uDegree, vDegree ); - fprintf( outStream, "nurbs order: %d u, %d v\n", - uDegree + 1, vDegree + 1 ); - } - - SAA_Boolean uClosed = FALSE; - SAA_Boolean vClosed = FALSE; - - SAA_nurbsSurfaceGetClosed( scene, model, &uClosed, &vClosed); - - if ( verbose >= 1 ) - { - if ( uClosed ) - fprintf( outStream, "nurbs is closed in u...\n"); - if ( vClosed ) - fprintf( outStream, "nurbs is closed in v...\n"); - } - - int uRows, vRows; - SAA_nurbsSurfaceGetNbVertices( scene, model, &uRows, &vRows ); - if ( verbose >= 1 ) - fprintf( outStream, "nurbs vertices: %d u, %d v\n", - uRows, vRows ); - - int uCurves, vCurves; - SAA_nurbsSurfaceGetNbCurves( scene, model, &uCurves, &vCurves ); - if ( verbose >= 1 ) - fprintf( outStream, "nurbs curves: %d u, %d v\n", - uCurves, vCurves ); - - if ( shift_textures ) - { - if ( uClosed ) - // shift starting point on NURBS surface for correct textures - SAA_nurbsSurfaceShiftParameterization( scene, model, -2, 0 ); - - if ( vClosed ) - // shift starting point on NURBS surface for correct textures - SAA_nurbsSurfaceShiftParameterization( scene, model, 0, -2 ); - } - - SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step ); - - // check for back face flag in model note info - char *modelNoteStr = GetModelNoteInfo( scene, model ); - - if ( modelNoteStr != NULL ) - { - if ( strstr( modelNoteStr, "bface" ) != NULL ) - eggNurbsSurf->flags |= EG_BFACE; - } - - int numKnotsU, numKnotsV; - - SAA_nurbsSurfaceGetNbKnots( scene, model, &numKnotsU, &numKnotsV ); - if ( verbose >= 1 ) - fprintf( outStream, "nurbs knots: %d u, %d v\n", - numKnotsU, numKnotsV ); - - double *knotsU, *knotsV; - knotsU = (double *)malloc(sizeof(double)*numKnotsU); - knotsV = (double *)malloc(sizeof(double)*numKnotsV); - SAA_nurbsSurfaceGetKnots( scene, model, gtype, 0, - numKnotsU, numKnotsV, knotsU, knotsV ); - - if ( verbose >= 2 ) - fprintf( outStream, "u knots:\n" ); - - AddKnots( eggNurbsSurf->u_knots, knotsU, numKnotsU, uClosed, uDegree ); - if ( verbose >= 2 ) - fprintf( outStream, "v knots:\n" ); - - AddKnots( eggNurbsSurf->v_knots, knotsV, numKnotsV, vClosed, vDegree); - - // free( knotsU ); free( knotsV ); - - // set sub_div so we can see it in perfly - eggNurbsSurf->u_subdiv = (uRows-1)*nurbs_step; - eggNurbsSurf->v_subdiv = (vRows-1)*nurbs_step; - - SAA_modelGetNbVertices( scene, model, &numVert ); - - if ( verbose >= 2 ) - fprintf( outStream, "%d CV's\n", numVert ); - - // get the CV's - vertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numVert); - SAA_modelGetVertices( scene, model, gtype, 0, - numVert, vertices ); - - // create pool of NURBS vertices - EggVertexPool *pool = _data.CreateVertexPool( parent, name ); - eggNurbsSurf->SetVertexPool( pool ); - - // create vertex ref list for all cv's in the model - EggVertexRef *vref; - - vref = new EggVertexRef( pool); - - for ( int k = 0; k= 2 ) - { - fprintf( outStream, "original cv[%d] = %f %f %f %f\n", k, - vertices[k].x, vertices[k].y, vertices[k].z, - vertices[k].w ); - } - - pfVec4 eggVert; - - // convert to global coords - SAA_DVector global; - - _VCT_X_MAT( global, vertices[k], matrix ); - - // preserve original weight - global.w = vertices[k].w; - - // normalize coords to weight - global.x *= global.w; - global.y *= global.w; - global.z *= global.w; - - // this code is commented out because I am no longer sending - // global data to the other routines (ie makevertexoffset) - - // set vertices array to reflect global coords vertices[k].x = - // global.x; vertices[k].y = global.y; vertices[k].z = - // global.z; vertices[k].w = global.w; - - // if ( verbose >= 2 ) { fprintf( outStream, "global cv[%d] = - // %f %f %f %f\n", k, vertices[k].x, vertices[k].y, - // vertices[k].z, vertices[k].w ); } - - // eggVert.set( vertices[k].x, vertices[k].y, vertices[k].z, - // vertices[k].w ); - - if ( verbose >= 2 ) - { - fprintf( outStream, "global cv[%d] = %f %f %f %f\n", k, - global.x, global.y, global.z, - global.w ); - } - - eggVert.set( global.x, global.y, global.z, - global.w ); - - // populate vertex pool - pool->AddVertex( eggVert, k ); - - // add vref's to NURBS info - eggNurbsSurf->AddVertex( k ); - - // add each vert in pool to vref for hard skinning - vref->indices.push_back( EggVertexIndex( k ) ); - - // check to see if the NURB is closed in u - if ( uClosed ) - { - // add first uDegree verts to end of row - if ( (k % uRows) == ( uRows - 1) ) - for ( int i = 0; i < uDegree; i++ ) - { - // add vref's to NURBS info - eggNurbsSurf->AddVertex( i+((k/uRows)*uRows) ); - - // add each vert to vref - vref->indices.push_back( - EggVertexIndex( i+((k/uRows)*uRows) ) ); - } - } - } - -/* - * if hard skinned or this nurb is also a joint disabled 1199 to streamline - * joint assignments. all hard skinning now done in CleanUpSoftSkin. if - * (!make_soft || geom_as_joint) { add the new cv references to the last joint - * for hard skinning only if ( lastJoint != NULL ) { - * lastJoint->vrefs.AddUniqueNode( *vref ); geom_as_joint = 0; if ( verbose >= - * 1 ) fprintf( outStream, "Doing NURBS hard skinning...\n"); } } - */ - - // check to see if the NURB is closed in v - if ( vClosed && !uClosed ) - { - // add first vDegree rows of verts to end of list - for ( int i = 0; i < vDegree*uRows; i++ ) - eggNurbsSurf->AddVertex( i ); - } - // check to see if the NURB is closed in u and v - else if ( vClosed && uClosed ) - { - // add the first (degree) v verts and a few extra - for good - // measure - for ( i = 0; i < vDegree; i++ ) - { - // add first vDegree rows of verts to end of list - for ( j = 0; j < uRows; j++ ) - eggNurbsSurf->AddVertex( j+(i*uRows) ); - - // if u is closed to we have added uDegree verts onto the - // ends of the rows - add them here too - for ( k = 0; k < uDegree; k++ ) - eggNurbsSurf->AddVertex( k+(i*uRows)+((k/uRows)*uRows) ); - } - - } - - // get the color of the NURBS surface - int numNurbMats; - EggColor *nurbCref; - pfVec4 nurbColor; - - SAA_modelRelationGetMatNbElements( scene, model, FALSE, &relinfo, - &numNurbMats ); - - if ( verbose >= 1 ) - fprintf( outStream, "nurbs surf has %d materials\n", - numNurbMats ); - - if ( numNurbMats ) - { - float r,g,b,a; - - materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numNurbMats); - - SAA_modelRelationGetMatElements( scene, model, relinfo, - numNurbMats, materials ); - - SAA_materialGetDiffuse( scene, &materials[0], &r, &g, &b ); - SAA_materialGetTransparency( scene, &materials[0], &a ); - nurbColor.set( r, g, b, 1.0f - a ); - // nurbColor.set( r, g, b, 1.0 ); - - nurbCref = _data.CreateColor(nurbColor); - eggNurbsSurf->attrib.SetCRef(nurbCref); - - // get the texture of the NURBS surface from the material - int numNurbTexLoc = 0; - int numNurbTexGlb = 0; - - // ASSUME only one texture per material - SAA_Elem nurbTex; - - // find out how many local textures per NURBS surface ASSUME - // it only has one material - SAA_materialRelationGetT2DLocNbElements( scene, &materials[0], - FALSE, &relinfo, &numNurbTexLoc ); - - // if present, get local textures - if ( numNurbTexLoc ) - { - if ( verbose >= 1 ) - fprintf( outStream, "%s had %d local tex\n", name, - numNurbTexLoc ); - - // get the referenced texture - SAA_materialRelationGetT2DLocElements( scene, &materials[0], - TEX_PER_MAT, &nurbTex ); - - } - // if no locals, try to get globals - else - { - SAA_modelRelationGetT2DGlbNbElements( scene, model, - FALSE, &relinfo, &numNurbTexGlb ); - - if ( numNurbTexGlb ) - { - if ( verbose >= 1 ) - fprintf( outStream, "%s had %d global tex\n", name, - numNurbTexGlb ); - - // get the referenced texture - SAA_modelRelationGetT2DGlbElements( scene, - model, TEX_PER_MAT, &nurbTex ); - } - } - - // add tex ref's if we found any textures - if ( numNurbTexLoc || numNurbTexGlb) - { - char *texName = NULL; - char *uniqueTexName = NULL; - EggTexture *tref; - pfMatrix nurbTexMat; - - - // convert the texture to .rgb and adjust name - texName = ConvertTexture( scene, &nurbTex ); - - // append unique identifier to texname for this particular - // object - uniqueTexName = (char *)malloc(sizeof(char)* - (strlen(name)+strlen(texName)+3) ); - sprintf( uniqueTexName, "%s-%s", name, - RemovePathName(texName) ); - - if ( verbose >= 1 ) - { - fprintf( outStream, "creating tref %s\n", - uniqueTexName ); - } - - tref = _data.CreateTexture( texName, uniqueTexName ); - - uScale = ( float *)malloc(sizeof(float)); - vScale = ( float *)malloc(sizeof(float)); - uOffset = ( float *)malloc(sizeof(float)); - vOffset = ( float *)malloc(sizeof(float)); - - // get texture offset info - SAA_texture2DGetUScale( scene, &nurbTex, uScale ); - SAA_texture2DGetVScale( scene, &nurbTex, vScale ); - SAA_texture2DGetUOffset( scene, &nurbTex, uOffset ); - SAA_texture2DGetVOffset( scene, &nurbTex, vOffset ); - SAA_texture2DGetUVSwap( scene, &nurbTex, &uv_swap ); - - - if ( verbose >= 1 ) - { - fprintf( outStream, "nurbTex uScale: %f\n", *uScale ); - fprintf( outStream, "nurbTex vScale: %f\n", *vScale ); - fprintf( outStream, "nurbTex uOffset: %f\n", *uOffset ); - fprintf( outStream, "nurbTex vOffset: %f\n", *vOffset ); - if ( uv_swap ) - fprintf( outStream, "nurbTex u & v swapped!\n" ); - else - fprintf( outStream, "nurbTex u & v NOT swapped\n" ); - } - - nurbTexMat.makeIdent(); - - if ( !ignore_tex_offsets ) - { - if ( uv_swap ) - { - nurbTexMat[0][0] = 0.0f; - nurbTexMat[1][1] = 0.0f; - nurbTexMat[0][1] = 1 / *vScale; - nurbTexMat[1][0] = 1 / *uScale; - nurbTexMat[2][1] = -(*uOffset / *uScale); - nurbTexMat[2][0] = -(*vOffset / *vScale); - } - else - { - nurbTexMat[0][0] = 1 / *uScale; - nurbTexMat[1][1] = 1 / *vScale; - nurbTexMat[2][0] = -(*uOffset / *uScale); - nurbTexMat[2][1] = -(*vOffset / *vScale); - } - } - - - // call printMat - if ( verbose >= 2 ) - { - fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[0][0], - nurbTexMat[0][1], nurbTexMat[0][2], nurbTexMat[0][3] ); - fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[1][0], - nurbTexMat[1][1], nurbTexMat[1][2], nurbTexMat[1][3] ); - fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[2][0], - nurbTexMat[2][1], nurbTexMat[2][2], nurbTexMat[2][3] ); - fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[3][0], - nurbTexMat[3][1], nurbTexMat[3][2], nurbTexMat[3][3] ); - } - - - tref->tex_mat = nurbTexMat; - tref->flags |= EFT_TRANSFORM; - - eggNurbsSurf->attrib.SetTRef(tref); - - } - - // if we've encountered textures and we desire duv anims - if (( numNurbTexLoc || numNurbTexGlb ) && make_duv ) - { - int numExp; - - // find how many expressions for this shape - SAA_elementGetNbExpressions( scene, &nurbTex, NULL, FALSE, - &numExp ); - - // if it has expressions we'll assume its animated - if ( numExp ) - { - if ( verbose > 1 ) - printf( "nurbTex has %d expressions...\n", numExp ); - - // if animated object make base duv's, animtables for - // the duv's and store the original offsets - strstream uName, vName; - - // create duv target names - uName << name << ".u" << ends; - vName << name << ".v" << ends; - - // make sure root morph table exists - if ( morphRoot == NULL ) - morphRoot = animData.CreateTable( animRoot, - "morph" ); - - // create morph table entry for each duv - SAnimTable *uTable = new SAnimTable( ); - uTable->name = uName.str(); - uTable->fps = anim_rate; - morphRoot->children.push_back( uTable ); - if ( verbose >= 1 ) - fprintf( outStream, "created duv table named: %s\n", uName.str() ); - - SAnimTable *vTable = new SAnimTable( ); - vTable->name = vName.str(); - vTable->fps = anim_rate; - morphRoot->children.push_back( vTable ); - if ( verbose >= 1 ) - fprintf( outStream, "created duv table named: %s\n", vName.str() ); - - float texOffsets[4]; - - texOffsets[0] = *uOffset; - texOffsets[1] = *vOffset; - texOffsets[2] = *uScale; - texOffsets[3] = *vScale; - - // remember original texture offsets future reference - SAA_elementSetUserData( scene, model, "TEX_OFFSETS", - sizeof( texOffsets ), TRUE, (void **)&texOffsets ); - - // create UV's and duv's for each vertex - for( i = 0; i < numVert; i++ ) - { - pfVec2 tmpUV; - EggMorphOffset *duvU; - EggMorphOffset *duvV; - - // create uv's so we can store duv's - eggNurbsSurf->CalcActualUV( i, tmpUV ); - pool->Vertex(i)->attrib.SetUV( tmpUV[0], tmpUV[1] ); - - // generate base duv's for this vertex - duvU = new EggMorphOffset(uName.str(), 1.0 , 0.0); - pool->Vertex(i)->attrib.uv_morphs.push_back(*duvU); - - duvV = new EggMorphOffset(vName.str(), 0.0 , 1.0); - pool->Vertex(i)->attrib.uv_morphs.push_back(*duvV); - } - - } // if ( numExp ) - } // if ( numTexLoc || numTexGlb ) - - // free( uScale ); free( vScale ); free( uOffset ); free( - // vOffset ); - - // free( materials ); - } - else - { - // no material present - default to white - nurbColor.set( 1.0, 1.0, 1.0, 1.0 ); - } - - // check NURBS surface for trim curves - int numTrims; - bool isTrim = TRUE; - SAA_SubElem *trims; - - SAA_nurbsSurfaceGetNbTrimCurves( scene, model, SAA_TRIMTYPE_TRIM, - &numTrims ); - - if ( verbose >= 1 ) - fprintf( outStream, "nurbs surf has %d trim curves\n", - numTrims ); - - if ( numTrims) - { - trims = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTrims); - - if ( trims ) - { - SAA_nurbsSurfaceGetTrimCurves( scene, model, - gtype, 0, SAA_TRIMTYPE_TRIM, numTrims, - trims ); - - MakeSurfaceCurve( scene, model, parent, eggNurbsSurf, - numTrims, trims, isTrim ); - } - - // free( trims ); - } - - // check NURBS surface for surface curves - isTrim = FALSE; - - SAA_nurbsSurfaceGetNbTrimCurves( scene, model, - SAA_TRIMTYPE_PROJECTION, &numTrims ); - - if ( verbose >= 1 ) - fprintf( outStream, "nurbs surf has %d surface curves\n", - numTrims ); - - if ( numTrims) - { - trims = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTrims); - - if ( trims ) - { - SAA_nurbsSurfaceGetTrimCurves( scene, model, - gtype, 0, SAA_TRIMTYPE_PROJECTION, - numTrims, trims ); - - MakeSurfaceCurve( scene, model, parent, eggNurbsSurf, - numTrims, trims, isTrim ); - } - - // free( trims ); - } - - // push the NURBS into the egg data - parent->children.push_back( eggNurbsSurf ); - - // if model has key shapes, generate vertex offsets - if ( has_morph && make_morph ) - MakeVertexOffsets( scene, model, type, numShapes, numVert, - vertices, matrix, name ); - - - // free( vertices ); - - } - - // check to see if its a NURBS curve - else if ( (type == SAA_MNCRV) && ( visible ) && ( make_nurbs ) ) - { - // ignore for now make the NURBS curve and push it into the egg - // data parent->children.push_back( MakeNurbsCurve( scene, model, - // parent, matrix, name ) ); - } - else if ( type == SAA_MJNT ) - { - MakeJoint( scene, lastJoint, lastAnim, model, name ); - if ( verbose >= 1 ) - fprintf( outStream, "encountered IK joint: %s\n", name ); - } - - // it must be a NULL - else - { - SAA_AlgorithmType algo; - - SAA_modelGetAlgorithm( scene, model, &algo ); - if ( verbose >= 1 ) - fprintf( outStream, "null algorithm: %d\n", algo ); - - if ( algo == SAA_ALG_INV_KIN ) - { - MakeJoint( scene, lastJoint, lastAnim, model, name ); - if ( verbose >= 1 ) - fprintf( outStream, "encountered IK root: %s\n", name ); - } - else if ( algo == SAA_ALG_INV_KIN_LEAF ) - { - MakeJoint( scene, lastJoint, lastAnim, model, name ); - if ( verbose >= 1 ) - fprintf( outStream, "encountered IK leaf: %s\n", name ); - } - else if ( algo == SAA_ALG_STANDARD ) - { - SAA_Boolean isSkeleton = FALSE; - - if ( verbose >= 1 ) - fprintf( outStream, "encountered Standard null: %s\n", name); - - 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" ) != NULL) ) - { - MakeJoint( scene, lastJoint, lastAnim, model, name ); - if ( verbose >= 1 ) - fprintf( outStream, "animating Standard null!!!\n" ); - } - } - else - if ( verbose >= 1 ) - fprintf( outStream, "encountered some other NULL: %d\n", - algo ); - } - } - - - // check for children... - int numChildren; - int thisChild; - SAA_Elem *children; - - SAA_modelGetNbChildren( scene, model, &numChildren ); - if ( verbose >= 1 ) - fprintf( outStream, "Model children: %d\n", numChildren ); - - if ( numChildren ) - { - children = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numChildren); - SAA_modelGetChildren( scene, model, numChildren, children ); - if ( children != NULL ) - { - for ( thisChild = 0; thisChild < numChildren; thisChild++ ) - { - if ( verbose >= 1 ) - fprintf( outStream, "\negging child %d...\n", thisChild); - MakeEgg( parent, lastJoint, lastAnim, scene, - &children[thisChild] ); - } - } - else - fprintf( outStream, "Not enough Memory for children...\n"); - // free( children ); - } - fflush( outStream ); - } - else - if ( verbose >= 1 ) - fprintf( outStream, "Don't descend this branch!\n" ); - - // we are done for the most part - start cleaning up memory free( name ); -} - - -/** - * Given a scene and lists of u and v samples create a an egg NURBS curve of - * degree two from the samples - */ -void soft2egg:: -MakeSurfaceCurve( SAA_Scene *scene, SAA_Elem *model, EggGroup *parent, - EggNurbsSurface *&nurbsSurf, int numTrims, SAA_SubElem *trims, - bool isTrim ) -{ - int i; - long totalSamples = 0; - long *numSamples; - double *uSamples; - double *vSamples; - SAA_Elem *trimCurves; - char *name; - - // get UV coord data - numSamples = (long *)malloc(sizeof(long)*numTrims); - - SAA_surfaceCurveGetNbLinearSamples( scene, model, numTrims, trims, - numSamples ); - - for ( i = 0; i < numTrims; i++ ) - { - totalSamples += numSamples[i]; - if ( verbose >= 2 ) - fprintf( outStream, "numSamples[%d] = %d\n", i, numSamples[i] ); - } - - if ( verbose >= 2 ) - fprintf( outStream, "total samples = %ld\n", totalSamples ); - - uSamples = (double *)malloc(sizeof(double)*totalSamples); - vSamples = (double *)malloc(sizeof(double)*totalSamples); - - SAA_surfaceCurveGetLinearSamples( scene, model, numTrims, trims, - numSamples, uSamples, vSamples ); - - if ( verbose >= 2 ) - for ( long li = 0; li < totalSamples; li++ ) - fprintf( outStream, "master list cv[%ld] = %f, %f\n", li, - uSamples[li], vSamples[li] ); - - trimCurves = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTrims); - - SAA_surfaceCurveExtract( scene, model, numTrims, trims, trimCurves ); - - // if it's a trim create a trim to assign trim curves to - EggNurbsSurface::Trim *eggTrim = new EggNurbsSurface::Trim(); - - // for each trim curve, make an egg curve and add it to the trims of the - // NURBS surface - for ( i = 0; i < numTrims; i++ ) - { - if ( use_prefix ) - { - // Get the FULL name of the trim curve - name = GetFullName( scene, &trimCurves[i] ); - } - else - { - // Get the name of the trim curve - name = GetName( scene, &trimCurves[i] ); - } - - if ( isTrim ) - { - // add to trim list - EggNurbsSurface::Loop *eggLoop = new EggNurbsSurface::Loop(); - eggLoop->push_back( MakeUVNurbsCurve( i, numSamples, uSamples, - vSamples, parent, name ) ); - eggTrim->push_back( *eggLoop ); - } - else - // add to curve list - nurbsSurf->curves.push_back( MakeUVNurbsCurve( i, numSamples, uSamples, vSamples, parent, name ) ); - } - - if ( isTrim ) - // pus trim list onto trims list - nurbsSurf->trims.push_back( *eggTrim ); - - // free( name ); free( trimCurves ); free( uSamples ); free( vSamples ); -} - -/** - * Given a scene and lists of u and v samples create a an egg NURBS curve of - * degree two from the samples - */ -EggNurbsCurve *soft2egg:: -MakeUVNurbsCurve( int numCurve, long *numSamples, double *uSamples, - double *vSamples, EggGroup *parent, char *name ) -{ - EggNurbsCurve *eggNurbsCurve = new EggNurbsCurve( name ); - - eggNurbsCurve->order = 2; - - - if ( verbose >= 2 ) - fprintf( outStream, "nurbs UV curve %s:\n", name ); - - // set sub_div so we can see it in perfly eggNurbsCurve->subdiv = - // numSamples[numCurve]4; perfly chokes on big numbers - keep it - // reasonable - eggNurbsCurve->subdiv = 150; - - // create pool of NURBS vertices - EggVertexPool *pool = _data.CreateVertexPool( parent, name ); - eggNurbsCurve->SetVertexPool( pool ); - - // calculate offset to this curve's samples in list of all curve samples - int offset = 0; - - for ( int o = 0; o < numCurve; o++ ) - offset += numSamples[o]; - - for ( int k = 0; k= 2 ) - fprintf( outStream, "cv[%d] = %f %f %f\n", k, eggVert[0], - eggVert[1], eggVert[2] ); - - // populate vertex pool - pool->AddVertex( eggVert, k ); - - // add vref's to NURBS info - eggNurbsCurve->AddVertex( k ); - } - - // create numSamples[numCurve]+2 knots - eggNurbsCurve->knots.push_back( 0 ); - for ( k = 0; k < numSamples[numCurve]; k++ ) - eggNurbsCurve->knots.push_back( k ); - eggNurbsCurve->knots.push_back( numSamples[numCurve] - 1 ); - - // set color to bright green for now - EggColor *nurbCref; - pfVec4 nurbColor; - - nurbColor.set( 0.5, 1.0, 0.5, 1.0 ); - nurbCref = _data.CreateColor(nurbColor); - eggNurbsCurve->attrib.SetCRef(nurbCref); - - return( eggNurbsCurve ); -} - -/** - * Given a scene and a NURBS curve model create the the appropriate egg - * structures - */ -EggNurbsCurve *soft2egg:: -MakeNurbsCurve( SAA_Scene *scene, SAA_Elem *model, EggGroup *parent, - float matrix[4][4], char *name ) -{ - EggNurbsCurve *eggNurbsCurve = new EggNurbsCurve( name ); - int degree; - - if ( verbose >= 2 ) - fprintf( outStream, "nurbs curve %s:\n", name ); - - // create nurbs representation of surface - SAA_nurbsCurveGetDegree( scene, model, °ree ); - eggNurbsCurve->order = degree + 1; - if ( verbose >= 2 ) - fprintf( outStream, "nurbs curve order: %d\n", degree + 1 ); - - SAA_nurbsCurveSetStep( scene, model, nurbs_step ); - - SAA_Boolean closed = FALSE; - - SAA_nurbsCurveGetClosed( scene, model, &closed ); - if ( closed ) - if ( verbose >= 2 ) - fprintf( outStream, "nurbs curve is closed...\n"); - - int numKnots; - - SAA_nurbsCurveGetNbKnots( scene, model, &numKnots ); - if ( verbose >= 2 ) - fprintf( outStream, "nurbs curve knots: %d\n", numKnots ); - double *knots; - knots = (double *)malloc(sizeof(double)*numKnots); - SAA_nurbsCurveGetKnots( scene, model, SAA_GEOM_ORIGINAL, 0, - numKnots, knots ); - - AddKnots( eggNurbsCurve->knots, knots, numKnots, closed, degree ); - - // free( knots ); - - int numCV; - - SAA_modelGetNbVertices( scene, model, &numCV ); - if ( verbose >= 2 ) - fprintf( outStream, "%d CV's (=? %d)\n", numCV, (numKnots-(degree+1)) ); - - // set sub_div so we can see it in perfly - eggNurbsCurve->subdiv = (numCV-1)*nurbs_step; - - // get the CV's - SAA_DVector *cvArray; - cvArray = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV); - SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0, - numCV, cvArray ); - - // create pool of NURBS vertices - EggVertexPool *pool = _data.CreateVertexPool( parent, name ); - eggNurbsCurve->SetVertexPool( pool ); - - for ( int k = 0; k= 2 ) - fprintf( outStream, "cv[%d] = %f %f %f %f\n", k, cvArray[k].x, - cvArray[k].y, cvArray[k].z, cvArray[k].w ); - - pfVec4 eggVert; - - // convert to global coords - SAA_DVector local = cvArray[k]; - SAA_DVector global; - - _HVCT_X_MAT( global, local, matrix ); - - eggVert.set( global.x, global.y, global.z, global.w ); - - // populate vertex pool - pool->AddVertex( eggVert, k ); - - // add vref's to NURBS info - eggNurbsCurve->AddVertex( k ); - } - - if ( closed ) - { - // need to replicate first (degree) vertices - for ( k = 0; k < degree; k++ ) - { - eggNurbsCurve->AddVertex( k ); - if ( verbose >= 2 ) - fprintf( outStream, "adding cv[%d] = %f %f %f %f\n", k, - cvArray[k].x, cvArray[k].y, cvArray[k].z, cvArray[k].w ); - } - } - - // free( cvArray ); - - // set color to bright green for now - EggColor *nurbCref; - pfVec4 nurbColor; - - nurbColor.set( 0.5, 1.0, 0.5, 1.0 ); - nurbCref = _data.CreateColor(nurbColor); - eggNurbsCurve->attrib.SetCRef(nurbCref); - - return( eggNurbsCurve ); -} - -/** - * Given a parametric surface, and its knots, create the appropriate egg - * structure by filling in Soft's implicit knots and assigning the rest to - * eggKnots. - */ -void soft2egg:: -AddKnots( perf_vector &eggKnots, double *knots, int numKnots, - SAA_Boolean closed, int degree ) -{ - int k = 0; - double lastKnot = knots[0]; - double *newKnots; - - // add initial implicit knot(s) - if ( closed ) - { - int i = 0; - newKnots = (double *)malloc(sizeof(double)*degree); - - // need to add (degree) number of knots - for ( k = numKnots - 1; k >= numKnots - degree; k-- ) - { - // we have to know these in order to calculate next knot value so - // hold them in temp array - newKnots[i] = lastKnot - (knots[k] - knots[k-1]); - lastKnot = newKnots[i]; - i++; - } - for ( k = degree - 1; k >= 0; k-- ) - { - eggKnots.push_back( newKnots[k] ); - if ( verbose >= 2 ) - fprintf( outStream, "knots[%d] = %f\n", k, newKnots[k] ); - } - - // free( newKnots ); - } - else - { - eggKnots.push_back( knots[k] ); - if ( verbose >= 2 ) - fprintf( outStream, "knots[%d] = %f\n", k, knots[k] ); - } - - // add the regular complement of knots - for (k = 0; k < numKnots; k++) - { - eggKnots.push_back( knots[k] ); - if ( verbose >= 2 ) - fprintf( outStream, "knots[%d] = %f\n", k+1, knots[k] ); - } - - lastKnot = knots[numKnots-1]; - - // add trailing implicit knots - if ( closed ) - { - - // need to add (degree) number of knots - for ( k = 1; k <= degree; k++ ) - { - eggKnots.push_back( lastKnot + (knots[k] - knots[k-1]) ); - if ( verbose >= 2 ) - fprintf( outStream, "knots[%d] = %f\n", k, - lastKnot + (knots[k] - knots[k-1]) ); - lastKnot = lastKnot + (knots[k] - knots[k-1]); - } - } - else - { - eggKnots.push_back( knots[k-1] ); - if ( verbose >= 2 ) - fprintf( outStream, "knots[%d] = %f\n", k+1, knots[k-1] ); - } -} - -/** - * Given a name, a parent and a model create a new a new EggJoint for that - * model. - */ -void soft2egg:: -MakeJoint( SAA_Scene *scene, EggJoint *&lastJoint, AnimGroup *&lastAnim, - SAA_Elem *model, char *name ) -{ - float matrix[4][4]; - pfMatrix Matrix; - EggJoint *joint; - SAA_Boolean globalFlag = FALSE; - int scale_joint = 0; - - - // this is a quick fix to make scaled skeletons possible if the parent - // contains the keyword "scale" make this joint a global root joint - // instead of a child... - if (lastJoint != NULL) - { - if ( strstr( lastJoint->name.Str(), "scale" ) != NULL ) - { - scale_joint = 1; - if ( verbose >= 1 ) - fprintf( outStream, "scale joint flag set!\n" ); - } - } - - // if not root, flatten is false, and last joint had no scaling applied to - // it, then create joint in skeleton tree - if ( (lastJoint != NULL) && !flatten && !scale_joint ) - { - if ( verbose >= 1 ) - { - fprintf( outStream, "lastJoint = %s\n", lastJoint->name.Str() ); - fprintf( outStream, "getting local transform\n" ); - } - - SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ), - TRUE, (void **)&globalFlag ); - - // get the local matrix - SAA_modelGetMatrix( scene, model, SAA_COORDSYS_LOCAL, matrix ); - - // make this into a pfMatrix - Matrix[0][0] = matrix[0][0]; - Matrix[0][1] = matrix[0][1]; - Matrix[0][2] = matrix[0][2]; - Matrix[0][3] = matrix[0][3]; - Matrix[1][0] = matrix[1][0]; - Matrix[1][1] = matrix[1][1]; - Matrix[1][2] = matrix[1][2]; - Matrix[1][3] = matrix[1][3]; - Matrix[2][0] = matrix[2][0]; - Matrix[2][1] = matrix[2][1]; - Matrix[2][2] = matrix[2][2]; - Matrix[2][3] = matrix[2][3]; - Matrix[3][0] = matrix[3][0]; - Matrix[3][1] = matrix[3][1]; - Matrix[3][2] = matrix[3][2]; - Matrix[3][3] = matrix[3][3]; - - joint = _data.CreateJoint( lastJoint, name ); - joint->transform = Matrix; - } - // if we already have a root attach this joint to it - else if (foundRoot) - { - if ( verbose >= 1 ) - fprintf( outStream, "getting global transform\n" ); - - globalFlag = TRUE; - - SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ), - TRUE, (void *)&globalFlag ); - - // get the global matrix - SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL, matrix ); - - // make this into a pfMatrix - Matrix[0][0] = matrix[0][0]; - Matrix[0][1] = matrix[0][1]; - Matrix[0][2] = matrix[0][2]; - Matrix[0][3] = matrix[0][3]; - Matrix[1][0] = matrix[1][0]; - Matrix[1][1] = matrix[1][1]; - Matrix[1][2] = matrix[1][2]; - Matrix[1][3] = matrix[1][3]; - Matrix[2][0] = matrix[2][0]; - Matrix[2][1] = matrix[2][1]; - Matrix[2][2] = matrix[2][2]; - Matrix[2][3] = matrix[2][3]; - Matrix[3][0] = matrix[3][0]; - Matrix[3][1] = matrix[3][1]; - Matrix[3][2] = matrix[3][2]; - Matrix[3][3] = matrix[3][3]; - - if ( verbose >= 1 ) - fprintf( outStream, "attaching orphan chain to root\n" ); - - joint = _data.CreateJoint( rootJnt, name ); - joint->transform = Matrix; - lastAnim = rootAnim; - } - // if root, make a seperate tree for skeleton and create required Table - // for the Egg heirarchy - else - { - if ( verbose >= 1 ) - fprintf( outStream, "getting global transform\n" ); - - globalFlag = TRUE; - - SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ), - TRUE, (void *)&globalFlag ); - - // get the global matrix - SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL, matrix ); - - // make this into a pfMatrix - Matrix[0][0] = matrix[0][0]; - Matrix[0][1] = matrix[0][1]; - Matrix[0][2] = matrix[0][2]; - Matrix[0][3] = matrix[0][3]; - Matrix[1][0] = matrix[1][0]; - Matrix[1][1] = matrix[1][1]; - Matrix[1][2] = matrix[1][2]; - Matrix[1][3] = matrix[1][3]; - Matrix[2][0] = matrix[2][0]; - Matrix[2][1] = matrix[2][1]; - Matrix[2][2] = matrix[2][2]; - Matrix[2][3] = matrix[2][3]; - Matrix[3][0] = matrix[3][0]; - Matrix[3][1] = matrix[3][1]; - Matrix[3][2] = matrix[3][2]; - Matrix[3][3] = matrix[3][3]; - - rootJnt = _data.CreateJoint( skeleton, "root" ); - rootJnt->transform.makeIdent(); - if ( verbose >= 1 ) - fprintf( outStream, "setting skeleton root\n" ); - rootJnt->flags |= EF_TRANSFORM; - - joint = _data.CreateJoint( rootJnt, name ); - joint->transform = Matrix; - foundRoot = TRUE; - if ( verbose >= 1 ) - fprintf( outStream, "found first chain\n" ); - - // make skeleton table - AnimGroup *skeletonTable; - skeletonTable = animData.CreateTable( animRoot, "" ); - rootAnim = animData.CreateTable( skeletonTable, "root" ); - XfmSAnimTable *table = new XfmSAnimTable( ); - table->name = "xform"; - table->fps = anim_rate; - rootAnim->children.push_back( table ); - lastAnim = rootAnim; - } - - joint->flags |= EF_TRANSFORM; - - // if ( make_anim) { - AnimGroup *anim = animData.CreateTable( lastAnim, name ); - XfmSAnimTable *table = new XfmSAnimTable( ); - if ( verbose >= 1 ) - fprintf( outStream, "created anim table: %s\n", "xform" ); - table->name = "xform"; - table->fps = anim_rate; - anim->children.push_back( table ); - lastAnim = anim; - // } - - // make this joint current parent of chain - lastJoint = joint; -} - - -/** - * Given a skeleton part find its envelopes (if any) get the vertices - * associated with the envelopes and their weights and make vertex ref's for - * the joint - */ -void soft2egg:: -MakeSoftSkin( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models, - int numModels, char *name ) -{ - int numEnv; - SAA_ModelType type; - SAA_Elem *envelopes; - - if ( verbose >= 1 ) - fprintf( outStream, "\n>found skeleton part( %s )!\n", name ); - - SAA_skeletonGetNbEnvelopes( scene, model, &numEnv ); - - if ( numEnv ) - { - // it's got envelopes - must be soft skinned - if ( verbose >= 1 ) - fprintf( outStream, "numEnv = %d\n", numEnv ); - - // allocate envelope array - envelopes = ( SAA_Elem *)malloc( sizeof( SAA_Elem )*numEnv ); - - if ( envelopes != NULL ) - { - int thisEnv; - SAA_EnvType envType; - bool hasEnvVertices = 0; - - SAA_skeletonGetEnvelopes( scene, model, numEnv, envelopes ); - - for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) - { - if ( verbose >= 1 ) - fprintf( outStream, "env[%d]: ", thisEnv ); - - SAA_envelopeGetType( scene, &envelopes[thisEnv], &envType ); - - if ( envType == SAA_ENVTYPE_NONE ) - { - if ( verbose >= 1 ) - fprintf( outStream, "envType = none\n" ); - } - else if ( envType == SAA_ENVTYPE_FLXLCL ) - { - if ( verbose >= 1 ) - fprintf( outStream, "envType = flexible, local\n" ); - hasEnvVertices = 1; - } - else if ( envType == SAA_ENVTYPE_FLXGLB ) - { - if ( verbose >= 1 ) - fprintf( outStream, "envType = flexible, global\n" ); - hasEnvVertices = 1; - } - else if ( envType == SAA_ENVTYPE_RGDGLB ) - { - if ( verbose >= 1 ) - fprintf( outStream, "envType = rigid, global\n" ); - hasEnvVertices = 1; - } - else - { - if ( verbose >= 1 ) - fprintf( outStream, "envType = unknown\n" ); - } - } - - if ( hasEnvVertices) - { - int *numEnvVertices; - SAA_SubElem *envVertices = NULL; - - numEnvVertices = (int *)malloc(sizeof(int)*numEnv); - - SAA_envelopeGetNbCtrlVertices( scene, model, numEnv, - envelopes, numEnvVertices ); - - if ( numEnvVertices != NULL ) - { - int totalEnvVertices = 0; - int i,j,k; - - for( i = 0; i < numEnv; i++ ) - { - totalEnvVertices += numEnvVertices[i]; - if ( verbose >= 1 ) - fprintf( outStream, "numEnvVertices[%d] = %d\n", - i, numEnvVertices[i] ); - } - - - if ( verbose >= 1 ) - fprintf( outStream, "total env verts = %d\n", - totalEnvVertices ); - - if ( totalEnvVertices ) - { - envVertices = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*totalEnvVertices); - - if ( envVertices != NULL ) - { - - SAA_envelopeGetCtrlVertices( scene, model, - numEnv, envelopes, numEnvVertices, envVertices); - - // loop through for each envelope - for ( i = 0; i < numEnv; i++ ) - { - float *weights = NULL; - int vertArrayOffset = 0; - - if ( verbose >= 2 ) - fprintf( outStream, "\nenvelope[%d]:\n", i ); - - weights = (float *)malloc(sizeof(float)*numEnvVertices[i]); - - if ( weights ) - { - char *envName; - int *vpoolMap = NULL; - - for ( j = 0; j < i; j++ ) - vertArrayOffset += numEnvVertices[j]; - - if ( verbose >= 1 ) - fprintf( outStream, - "envVertArray offset = %d\n", - vertArrayOffset ); - - // get the weights of the envelope vertices - SAA_ctrlVertexGetEnvelopeWeights( - scene, model, &envelopes[i], - numEnvVertices[i], - &envVertices[vertArrayOffset], weights ); - - // Get the name of the envelope model - if ( use_prefix ) - { - // Get the FULL name of the envelope - envName = GetFullName( scene, &envelopes[i] ); - } - else - { - // Get the name of the envelope - envName = GetName( scene, &envelopes[i] ); - } - - if ( verbose >= 1 ) - fprintf( outStream, "envelope name %s\n", envName ); - - // find out if envelope geometry is poly or nurb - // SAA_modelGetType( scene, FindModelByName( - // envName, scene, models, numModels ), &type ); - - SAA_modelGetType( scene, &envelopes[i], &type ); - - if ( verbose >= 1 ) - { - fprintf( outStream, "envelope model type "); - - if ( type == SAA_MSMSH ) - fprintf( outStream, "MESH\n" ); - else if ( type == SAA_MNSRF ) - fprintf( outStream, "NURBS\n" ); - else - fprintf( outStream, "OTHER\n" ); - } - - int *envVtxIndices = NULL; - envVtxIndices = (int *)malloc(sizeof(int)*numEnvVertices[i]); - - // Get the envelope vertex indices - SAA_ctrlVertexGetIndices( scene, &envelopes[i], numEnvVertices[i], - &envVertices[vertArrayOffset], envVtxIndices ); - - // find out how many vertices the model has - int modelNumVert; - - SAA_modelGetNbVertices( scene, &envelopes[i], &modelNumVert ); - - SAA_DVector *modelVertices = NULL; - modelVertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*modelNumVert); - - // get the model vertices - SAA_modelGetVertices( scene, &envelopes[i], - SAA_GEOM_ORIGINAL, 0, modelNumVert, - modelVertices ); - - // create array of global model coords - SAA_DVector *globalModelVertices = NULL; - globalModelVertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*modelNumVert); - float matrix[4][4]; - - // tranform local model vert coords to global - - // first get the global matrix - SAA_modelGetMatrix( scene, &envelopes[i], SAA_COORDSYS_GLOBAL, matrix ); - - // populate array of global model verts - for ( j = 0; j < modelNumVert; j++ ) - { - _VCT_X_MAT( globalModelVertices[j], - modelVertices[j], matrix ); - } - - // find the egg vertex pool that corresponds to - // this envelope model - EggVertexPool *envPool = - (EggVertexPool *)(_data.pools.FindName( envName )); - // If we are outputting triangles: create an array - // that maps from a referenced vertex in the - // envelope to a corresponding vertex in the egg - // vertex pool if ( (type == SAA_MNSRF) && - // !make_nurbs ) - if ( !make_nurbs || (type == SAA_MSMSH) ) - { - vpoolMap = FindClosestTriVert( envPool, - globalModelVertices, modelNumVert ); - } - - - if ( envPool != NULL ) - { - - // find the egg joint that corresponds to this - // model - EggJoint *joint = - (EggJoint *)(skeleton->FindDescendent( name )); - - // this doesn't seem to be necessary 4799 EggJoint - // *parent = (EggJoint *)joint->parent; - // assert(parent->IsA(NT_EggJoint)); - - // for every envelope vertex - for (j = 0; j < numEnvVertices[i]; j++) - { - double scaledWeight = weights[j]/ 100.0f; - - // make sure its in legal range - if (( envVtxIndices[j] < modelNumVert ) - && ( envVtxIndices[j] >= 0 )) - { - if ( (type == SAA_MNSRF) && make_nurbs ) - { - // assign all referenced control vertices - joint->AddVertex( envPool->Vertex(envVtxIndices[j]), scaledWeight ); - - if ( verbose >= 2 ) - fprintf( outStream, - "%d: adding vref to cv %d with weight %f\n", - j, envVtxIndices[j], scaledWeight ); - - envPool->Vertex(envVtxIndices[j])->AddJoint( joint, scaledWeight ); - // set flag to show this vertex has been - // assigned - envPool->Vertex(envVtxIndices[j])->multipleJoints = 1; - } - else - { - // assign all the tri verts associated - // with this control vertex to joint - for ( k = 0; k < envPool->NumVertices(); k++ ) - { - if ( vpoolMap[k] == envVtxIndices[j] ) - { - - // add each vert in pool to last joint - // for soft skinning - joint->AddVertex(envPool->Vertex(k), - scaledWeight); - - if ( verbose >= 2 ) - fprintf( outStream, - "%d: adding vref from cv %d to vert %d with weight %f(vpool)\n", - j, envVtxIndices[j], k, scaledWeight ); - - envPool->Vertex(k)->AddJoint( joint, scaledWeight ); - // set flag to show this vertex has - // been assigned - envPool->Vertex(k)->multipleJoints = 1; - } - } - } - } - else - if ( verbose >= 2 ) - fprintf( outStream, - "%d: Omitted vref from cv %d with weight %f (out of range 0 to %d )\n", - j, envVtxIndices[j], scaledWeight, modelNumVert ); - } - - } - else - if ( verbose >= 2 ) - fprintf( outStream, "Couldn't find vpool %s!\n", envName ); - - // free( modelVertices ); free( - // globalModelVertices ); free( envVtxIndices ); - // free( envName ); - } //if (weights) - // free( weights ); - - } // for i - - } // if (envVertices != NULL) - else - fprintf( outStream, "Not enough memory for envelope vertices...\n"); - // free( envVertices ); - } // if (totalEnvVertices) - else - if ( verbose >= 1 ) - fprintf( outStream, "No envelope vertices present...\n"); - - // free( numEnvVertices ); - - } // if (numEnvVertices != NULL) - - } // if (hasEnvVertices) - - } // if (envelopes != NULL) - else - fprintf( outStream, "Not enough memory for envelopes...\n" ); - - // free( envelopes ); - - } //if (numEnv) - - else - if ( verbose >= 1 ) - fprintf( outStream, "Skeleton member has no envelopes...\n" ); -} - - -/** - * Given a model, make sure all its vertices have been soft assigned. If not - * hard assign to the last joint we saw. - */ -void soft2egg:: -CleanUpSoftSkin( SAA_Scene *scene, SAA_Elem *model, char *name ) -{ - static EggJoint *joint; - SAA_Elem parent; - SAA_ModelType type; - SAA_Boolean skel; - - // find out what type of node we're dealing with - SAA_modelGetType( scene, model, &type ); - - char *parentName; - int level; - SAA_Elem *searchNode = model; - - if ( verbose >= 1 ) - fprintf( outStream, "\nCleaning up model %s\n", name ); - - // this step is weird - I think I want it here but it seems to break some - // models. Files like props-props_wh_cookietime.3-0 in - // fulrndpubvrmlchipchips_adventurecharzone1roomswarehouse_final need to - // do the "if (skel)" bit. - - // am I a skeleton too? - SAA_modelIsSkeleton( scene, model, &skel ); - - // if not look for the last skeleton part - if ( skel ) - parentName = name; - else do - { - SAA_elementGetHierarchyLevel( scene, searchNode, &level ); - - // make sure we don't try to get the root's parent - if ( level ) - { - SAA_modelGetParent( scene, searchNode, &parent ); - - if ( use_prefix ) - { - // Get the FULL name of the parent - parentName = GetFullName( scene, &parent ); - } - else - { - // Get the name of the parent - parentName = GetName( scene, &parent ); - } - - SAA_modelGetType( scene, &parent, &type ); - - SAA_modelIsSkeleton( scene, &parent, &skel ); - - if ( verbose >= 1 ) - fprintf( outStream, "model %s, level %d, type %d, skel %d\n", - parentName, level, type, skel ); - - searchNode = &parent; - } - else - { - // we reached the root of the tree - parentName = NULL; - if ( verbose >= 1 ) - fprintf( outStream, "at root of tree! level %d\n", level ); - break; - } - - // look until parent is a joint or acts like one - } while ( !skel && ( strstr( parentName,"joint") == NULL )); - - EggJoint *thisJoint = NULL; - - if ( parentName != NULL ) - { - if ( verbose >= 1 ) - { - fprintf( outStream, "found model parent joint %s\n", parentName); - fprintf( outStream, "looking for joint %s\n", parentName ); - } - thisJoint = (EggJoint *)(skeleton->FindDescendent( parentName )); - } - else - if ( verbose >= 1 ) - fprintf( outStream, "Couldn't find parent joint!\n"); - - if ( thisJoint != NULL ) - { - joint = thisJoint; - if ( verbose >= 1 ) - fprintf( outStream, "setting joint to %s\n", parentName ); - - // find the vpool for this model - EggVertexPool *vPool = - (EggVertexPool *)(_data.pools.FindName( name )); - - if (vPool != NULL) - { - int i; - double membership; - int numVerts = vPool->NumVertices() ; - - - if ( verbose >= 1 ) - fprintf( outStream, "found vpool %s w/ %d verts\n", - name, numVerts ); - - for ( i = 0; i < numVerts; i++ ) - { - if ( vPool->Vertex(i)->multipleJoints != 1 ) - { - if ( verbose >= 1 ) - { - fprintf( outStream, "vpool %s vert %d", name, i ); - fprintf( outStream, " not assigned!\n" ); - } - - // hard skin this vertex - joint->AddVertex( vPool->Vertex(i), 1.0f ); - } - else - { - membership = vPool->Vertex(i)->NetMembership(); - - - if ( verbose >= 1 ) - { - fprintf( outStream, "vpool %s vert %d", name, - i ); - fprintf( outStream, " has membership %f\n", - membership ); - } - - if ( membership == 0 ) - { - if ( verbose >= 1 ) - fprintf( outStream, "adding full weight..\n" ); - - // hard skin this vertex - joint->AddVertex( vPool->Vertex(i), 1.0f ); - } - } - } - } - else - if ( verbose >= 1 ) - fprintf( outStream, "couldn't find vpool %s\n", name ); - } - else - { - if ( parentName != NULL ) - if ( verbose >= 1 ) - fprintf( outStream, "Couldn't find joint %s\n", parentName ); - } -} - -/** - * Given a scene and a skeleton part ,get all the position, rotation, and - * scale for the skeleton part for this frame and write them out as Egg - * animation tables. - */ -void soft2egg:: -MakeAnimTable( SAA_Scene *scene, SAA_Elem *skeletonPart, char *name ) -{ - - if ( skeletonPart != NULL ) - { - float i,j,k; - float h,p,r; - float x,y,z; - int size; - SAA_Boolean globalFlag = FALSE; - SAA_Boolean bigEndian; - - if ( verbose >= 1 ) - fprintf( outStream, "\n\nanimating child %s\n", name ); - - SAA_elementGetUserDataSize( scene, skeletonPart, "GLOBAL", &size ); - - if ( size != 0 ) - SAA_elementGetUserData( scene, skeletonPart, "GLOBAL", - sizeof( SAA_Boolean), &bigEndian, (void *)&globalFlag ); - - if ( globalFlag ) - { - if ( verbose >= 1 ) - fprintf( outStream, " using global matrix\n" ); - - // get SAA orientation - SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &p, &h, &r ); - - // get SAA translation - SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &x, &y, &z ); - - // get SAA scaling - SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &i, &j, &k ); - } - else - { - if ( verbose >= 1 ) - fprintf( outStream, "using local matrix\n" ); - - // get SAA orientation - SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &p, &h, &r ); - - // get SAA translation - SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &x, &y, &z ); - - // get SAA scaling - SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &i, &j, &k ); - } - - - if ( verbose >= 2 ) - fprintf( outStream, "\nanim data: %f %f %f\n\t%f %f %f\n\t%f %f %f\n", - i, j, k, h, p, r, x, y, z ); - - // find the appropriate anim table for this skeleton part - AnimGroup *thisGroup; - XfmSAnimTable *thisTable; - - // find the anim table associated with this group - thisGroup = (AnimGroup *)(animRoot->FindDescendent( name )); - if ( verbose >= 2 ) - fprintf( outStream, "\nlooking for anim group %s\n", name ); - if ( thisGroup != NULL ) - { - thisTable = (XfmSAnimTable *)(thisGroup->FindDescendent( "xform" )); - - if ( thisTable != NULL ) - { - thisTable->sub_tables[0].AddElement( i ); - thisTable->sub_tables[1].AddElement( j ); - thisTable->sub_tables[2].AddElement( k ); - thisTable->sub_tables[3].AddElement( p ); - thisTable->sub_tables[4].AddElement( h ); - thisTable->sub_tables[5].AddElement( r ); - thisTable->sub_tables[6].AddElement( x ); - thisTable->sub_tables[7].AddElement( y ); - thisTable->sub_tables[8].AddElement( z ); - } - else - fprintf( outStream, "Couldn't allocate anim table\n" ); - } - else - if ( verbose >= 2 ) - fprintf( outStream, "Couldn't find anim group %s\n", name ); - } - else - { - if ( verbose >= 2 ) - fprintf( outStream, "Cannot build anim table - no skeleton\n" ); - } -} - -/** - * Given a scene, a model , the vertices of its original shape and its name - * find the difference between the geometry of its key shapes and the models - * original geometry and add morph vertices to the egg data to reflect these - * changes. - */ -void soft2egg:: -MakeVertexOffsets( SAA_Scene *scene, SAA_Elem *model, SAA_ModelType type, - int numShapes, int numOrigVert, SAA_DVector *originalVerts, float - matrix[4][4], char *name ) -{ - int i, j; - int offset; - int numCV; - char *mTableName; - SAA_DVector *shapeVerts = NULL; - SAA_DVector *uniqueVerts = NULL; - - if ( (type == SAA_MNSRF) && make_nurbs ) - SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step ); - - SAA_modelGetNbVertices( scene, model, &numCV ); - - // get the shape verts - uniqueVerts = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV); - SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0, - numCV, uniqueVerts ); - - if ( verbose >= 2 ) - fprintf( outStream, "%d CV's\n", numCV ); - - if ( verbose >= 2 ) - { - for ( i = 0; i < numCV; i++ ) - fprintf( outStream, "uniqueVerts[%d] = %f %f %f %f\n", i, - uniqueVerts[i].x, uniqueVerts[i].y, - uniqueVerts[i].z, uniqueVerts[i].w ); - } - - // iterate through for each key shape (except original) - for ( i = 1; i < numShapes; i++ ) - { - mTableName = MakeTableName( name, i ); - - if ( verbose >= 1 ) - { - fprintf( outStream, "\nMaking geometry offsets for %s...\n", - mTableName ); - - if ( (type == SAA_MNSRF) && make_nurbs ) - fprintf( outStream, "calculating NURBS morphs...\n" ); - else - fprintf( outStream, "calculating triangle morphs...\n" ); - } - - // get the shape verts - shapeVerts = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV); - SAA_modelGetVertices( scene, model, SAA_GEOM_SHAPE, i+1, - numCV, shapeVerts ); - - if ( verbose >= 2 ) - { - for ( j=0; j < numCV; j++ ) - { - fprintf( outStream, "shapeVerts[%d] = %f %f %f\n", j, - shapeVerts[j].x, shapeVerts[j].y, shapeVerts[j].z ); - } - } - - // find the appropriate vertex pool - EggVertexPool *vPool = - (EggVertexPool *)(_data.pools.FindName( name )); - - // for every original vertex, compare to the corresponding key shape - // vertex and see if a vertex offset is needed - for ( j=0; j < numOrigVert; j++ ) - { - double dx, dy, dz; - - if ( (type == SAA_MNSRF) && make_nurbs ) - { - // dx = shapeVerts[j].x - - // (originalVerts[j].xoriginalVerts[j].w); dy = - // shapeVerts[j].y - (originalVerts[j].yoriginalVerts[j].w); - // dz = shapeVerts[j].z - - // (originalVerts[j].zoriginalVerts[j].w); - dx = shapeVerts[j].x - originalVerts[j].x; - dy = shapeVerts[j].y - originalVerts[j].y; - dz = shapeVerts[j].z - originalVerts[j].z; - } - else - { - // we need to map from original vertices to triangle shape - // vertices here - offset = findShapeVert( originalVerts[j], uniqueVerts, - numCV ); - - dx = shapeVerts[offset].x - originalVerts[j].x; - dy = shapeVerts[offset].y - originalVerts[j].y; - dz = shapeVerts[offset].z - originalVerts[j].z; - } - - if ( verbose >= 2 ) - { - fprintf( outStream, "oVert[%d] = %f %f %f %f\n", j, - originalVerts[j].x, originalVerts[j].y, - originalVerts[j].z, originalVerts[j].w ); - - if ( (type == SAA_MNSRF) && make_nurbs ) - { - fprintf( outStream, "global shapeVerts[%d] = %f %f %f %f\n", j, shapeVerts[j].x, shapeVerts[j].y, - shapeVerts[j].z, shapeVerts[j].w ); - } - else - { - fprintf( outStream, - "global shapeVerts[%d] = %f %f %f\n", offset, - shapeVerts[offset].x, - shapeVerts[offset].y, - shapeVerts[offset].z ); - } - - fprintf( outStream, "%d: dx = %f, dy = %f, dz = %f\n", j, - dx, dy, dz ); - } - - // if change isn't negligible, make a morph vertex entry - double total = fabs(dx)+fabs(dy)+fabs(dz); - if ( total > 0.00001 ) - { - if ( vPool != NULL ) - { - // create offset - EggMorphOffset *dxyz = - new EggMorphOffset( mTableName, dx, dy, dz ); - - EggVertex *eggVert; - - // get the appropriate egg vertex - eggVert = vPool->Vertex(j); - - // add the offset to the vertex - eggVert->morphs.push_back( *dxyz ); - } - else - fprintf( outStream, "Error: couldn't find vertex pool %s\n", name ); - } // if total - } //for j - } //for i -} - - -/** - * Given a scene, a model, a name and a frame time, determine what type of - * shape interpolation is used and call the appropriate function to extract - * the shape weight info for this frame... - */ -void soft2egg:: -MakeMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models, - int numModels, char *name, float time ) -{ - int numShapes; - SAA_AnimInterpType type; - - // Get the number of key shapes - SAA_modelGetNbShapes( scene, model, &numShapes ); - - if ( numShapes > 0 ) - { - if ( verbose >= 1 ) - fprintf( outStream, "MakeMorphTable: %s: num shapes: %d\n", - name, numShapes); - - SAA_modelGetShapeInterpolation( scene, model, &type ); - - if ( type == SAA_ANIM_LINEAR || type == SAA_ANIM_CARDINAL ) - { - MakeLinearMorphTable( scene, model, numShapes, name, time ); - } - else // must be weighted... - { - // check first for expressions - MakeExpressionMorphTable( scene, model, models, numModels, - numShapes, name, time ); - } - - } -} - - -/** - * Given a scene, a model, its name, and the time, get the shape fcurve for - * the model and determine the shape weights for the given time and use them - * to populate the morph table. - */ -void soft2egg:: -MakeLinearMorphTable( SAA_Scene *scene, SAA_Elem *model, int numShapes, - char *name, float time ) -{ - int i; - SAA_Elem fcurve; - float curveVal; - SAnimTable *thisTable; - char *tableName; - - if ( verbose >= 1 ) - fprintf( outStream, "linear interp, getting fcurve\n" ); - - SAA_modelFcurveGetShape( scene, model, &fcurve ); - - SAA_fcurveEval( scene, &fcurve, time, &curveVal ); - - if ( verbose >= 2 ) - fprintf( outStream, "at time %f, fcurve for %s = %f\n", time, - name, curveVal ); - - float nextVal = 0.0f; - - // populate morph table values for this frame - for ( i = 1; i < numShapes; i++ ) - { - // derive table name from the model name - tableName = MakeTableName( name, i ); - - if ( verbose >= 2 ) - fprintf( outStream, "Linear: looking for table '%s'\n", tableName ); - - // find the morph table associated with this key shape - thisTable = (SAnimTable *)(morphRoot->FindDescendent( tableName )); - - if ( thisTable != NULL ) - { - if ( i == (int)curveVal ) - { - if ( curveVal - i == 0 ) - { - thisTable->AddElement( 1.0f ); - if ( verbose >= 2 ) - fprintf( outStream, "adding element 1.0f\n" ); - } - else - { - thisTable->AddElement( 1.0f - (curveVal - i) ); - nextVal = curveVal - i; - if ( verbose >= 2 ) - fprintf( outStream, "adding element %f\n", 1.0f - (curveVal - i) ); - } - } - else - { - if ( nextVal ) - { - thisTable->AddElement( nextVal ); - nextVal = 0.0f; - if ( verbose >= 2 ) - fprintf( outStream, "adding element %f\n", nextVal ); - } - else - { - thisTable->AddElement( 0.0f ); - if ( verbose >= 2 ) - fprintf( outStream, "adding element 0.0f\n" ); - } - } - - if ( verbose >= 2 ) - fprintf( outStream, " to '%s'\n", tableName ); - } - else - fprintf( outStream, "%d: Couldn't find table '%s'\n", - i, tableName ); - } - -} - -/** - * Given a scene, a model, a list of all models in the scene, the number of - * models in the scece, the number of key shapes for this model, the name of - * the model and the current time, determine what method of controlling the - * shape weights is used and call the appropriate routine. - */ -void soft2egg:: -MakeWeightedMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models, - int numModels, int numShapes, char *name, float time ) -{ - SI_Error result; - SAA_Elem *weightCurves; - float curveVal; - SAnimTable *thisTable; - char *tableName; - - // allocate array of weight curves (one for each shape) - weightCurves = ( SAA_Elem *)malloc( sizeof( SAA_Elem ) * numShapes ); - - result = SAA_modelFcurveGetShapeWeights( - scene, model, numShapes, weightCurves ); - - if ( result == SI_SUCCESS ) - { - for ( int i = 1; i < numShapes; i++ ) - { - SAA_fcurveEval( scene, &weightCurves[i], time, &curveVal ); - - // make sure soft gave us a - // reasonable number - if (!isNum(curveVal)) - curveVal = 0.0f; - - if ( verbose >= 2 ) - fprintf( outStream, "at time %f, weightCurve[%d] for %s = %f\n", time, i, name, curveVal ); - - - // derive table name from the model name - tableName = MakeTableName( name, i ); - - // find and populate shape - // table - if ( verbose >= 2 ) - fprintf( outStream, "Weight: looking for table '%s'\n", - tableName ); - - // find the morph table associated with this key shape - thisTable = (SAnimTable *)(morphRoot->FindDescendent( tableName )); - - if ( thisTable != NULL ) - { - thisTable->AddElement( curveVal ); - if ( verbose >= 2 ) - fprintf( outStream, "adding element %f\n", curveVal ); - } - else - fprintf( outStream, "%d: Couldn't find table '%s'\n", - i, tableName ); - } - } -} - - -/** - * Given a scene, a model and its number of key shapes generate a morph table - * describing transitions btwn the key shapes by evaluating the positions of - * the controlling sliders. - */ -void soft2egg:: -MakeExpressionMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models, - int numModels, int numShapes, char *name, float time ) -{ - int j; - SAnimTable *thisTable; - char *tableName; - char *sliderName; - char *track; - int numExp; - SAA_Elem *expressions; - float expVal; - float sliderVal; - - // populate morph table values for this frame - - // compose track name - track = NULL; - - // find how many expressions for this shape - SAA_elementGetNbExpressions( scene, model, track, FALSE, &numExp ); - - if ( verbose >= 2 ) - fprintf( outStream, "%s has %d RHS expressions\n", name, numExp ); - - if ( numExp ) - { - // get the expressions for this shape - expressions = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numExp); - - if ( verbose >= 1 ) - fprintf( outStream, "getting %d RHS expressions...\n", numExp ); - - result = SAA_elementGetExpressions( scene, model, track, FALSE, - numExp, expressions ); - - if ( !result ) - { - for ( j = 1; j < numExp; j++ ) - { - if ( verbose >= 2 ) - { - // debug see what we got - int numvars; - - SAA_expressionGetNbVars( scene, &expressions[j], &numvars ); - - int *varnamelen; - int *varstrlen; - int expstrlen; - - varnamelen = (int *)malloc(sizeof(int)*numvars); - varstrlen = (int *)malloc(sizeof(int)*numvars); - - SAA_expressionGetStringLengths( scene, &expressions[j], - numvars, varnamelen, varstrlen, &expstrlen ); - - int *varnamesizes; - int *varstrsizes; - - varnamesizes = (int *)malloc(sizeof(int)*numvars); - varstrsizes = (int *)malloc(sizeof(int)*numvars); - - for ( int k = 0; k < numvars; k++ ) - { - varnamesizes[k] = varnamelen[k] + 1; - varstrsizes[k] = varstrlen[k] + 1; - } - - int expstrsize = expstrlen + 1; - - char **varnames; - char **varstrs; - - varnames = (char **)malloc(sizeof(char *)*numvars); - varstrs = (char **)malloc(sizeof(char *)*numvars); - - for ( k = 0; k < numvars; k++ ) - { - varnames[k] = (char *)malloc(sizeof(char)* - varnamesizes[k]); - - varstrs[k] = (char *)malloc(sizeof(char)* - varstrsizes[k]); - } - - char *expstr = (char *)malloc(sizeof(char)* expstrsize ); - - SAA_expressionGetStrings( scene, &expressions[j], numvars, - varnamesizes, varstrsizes, expstrsize, varnames, - varstrs, expstr ); - - if ( verbose >= 2 ) - { - fprintf( outStream, "expression = '%s'\n", expstr ); - fprintf( outStream, "has %d variables\n", numvars ); - } - } //if verbose - - if ( verbose >= 2 ) - fprintf( outStream, "evaling expression...\n" ); - - SAA_expressionEval( scene, &expressions[j], time, &expVal ); - - if ( verbose >= 2 ) - fprintf( outStream, "time %f: exp val %f\n", - time, expVal ); - - // derive table name from the model name - tableName = MakeTableName( name, j ); - - if ( verbose >= 2 ) - fprintf( outStream, "Exp: looking for table '%s'\n", - tableName ); - - // find the morph table associated with this key shape - thisTable = (SAnimTable *) - (morphRoot->FindDescendent( tableName )); - - if ( thisTable != NULL ) - { - thisTable->AddElement( expVal ); - if ( verbose >= 1 ) - fprintf( outStream, "%d: adding element %f to %s\n", - j, expVal, tableName ); - fflush( outStream ); - } - else - { - fprintf( outStream, "%d: Couldn't find table '%s'", j, - tableName ); - - fprintf( outStream, " for value %f\n", expVal ); - } - } - } - else - fprintf( outStream, "couldn't get expressions!!!\n" ); - } - else - // no expression, use weight curves - MakeWeightedMorphTable( scene, model, models, numModels, - numShapes, name, time ); - -} - - -/** - * Given a scene, a POLYGON model, and the name of the that model, get the u - * and v offsets for the current frame. - */ -void soft2egg:: -MakeTexAnim( SAA_Scene *scene, SAA_Elem *model, char *modelName ) -{ - if ( verbose >= 1 ) - fprintf( outStream, "\n\nmaking texture animation for %s...\n", - modelName ); - - // get the color of the surface - int numMats; - pfVec4 Color; - SAA_Elem *materials; - void *relinfo; - - SAA_modelRelationGetMatNbElements( scene, model, FALSE, &relinfo, - &numMats ); - - if ( verbose >= 2 ) - fprintf( outStream, "surface has %d materials\n", numMats ); - - if ( numMats ) - { - float r,g,b,a; - - materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numMats); - - SAA_modelRelationGetMatElements( scene, model, relinfo, - numMats, materials ); - - SAA_materialGetDiffuse( scene, &materials[0], &r, &g, &b ); - SAA_materialGetTransparency( scene, &materials[0], &a ); - Color.set( r, g, b, 1.0f - a ); - - int numTexLoc = 0; - int numTexGlb = 0; - - // ASSUME only one texture per material - SAA_Elem tex; - - // find out how many local textures per surface ASSUME it only has one - // material - SAA_materialRelationGetT2DLocNbElements( scene, &materials[0], - FALSE, &relinfo, &numTexLoc ); - - // if present, get local textures - if ( numTexLoc ) - { - if ( verbose >= 1 ) - fprintf( outStream, "%s had %d local tex\n", modelName, - numTexLoc ); - - // get the referenced texture - SAA_materialRelationGetT2DLocElements( scene, &materials[0], - TEX_PER_MAT, &tex ); - - } - // if no locals, try to get globals - else - { - SAA_modelRelationGetT2DGlbNbElements( scene, model, - FALSE, &relinfo, &numTexGlb ); - - if ( numTexGlb ) - { - if ( verbose >= 1 ) - fprintf( outStream, "%s had %d global tex\n", modelName, numTexGlb ); - - // get the referenced texture - SAA_modelRelationGetT2DGlbElements( scene, - model, TEX_PER_MAT, &tex ); - } - } - - // add tex ref's if we found any textures - if ( numTexLoc || numTexGlb) - { - char *fullTexName = NULL; - char *texName = NULL; - char *uniqueTexName = NULL; - int texNameLen; - - // get its name - SAA_texture2DGetPicNameLength( scene, &tex, &texNameLen); - fullTexName = (char *)malloc(sizeof(char)*++texNameLen); - SAA_texture2DGetPicName( scene, &tex, texNameLen, - fullTexName ); - - // append unique identifier to texname for this particular object - uniqueTexName = (char *)malloc(sizeof(char)* - (strlen(modelName)+strlen(texName)+3) ); - sprintf( uniqueTexName, "%s-%s", modelName, texName ); - if ( verbose >= 2 ) - fprintf( outStream, "referencing tref %s\n", - uniqueTexName ); - - float uScale; - float vScale; - float uOffset; - float vOffset; - SAA_Boolean uv_swap = FALSE; - - // get texture offset info - SAA_texture2DGetUScale( scene, &tex, &uScale ); - SAA_texture2DGetVScale( scene, &tex, &vScale ); - SAA_texture2DGetUOffset( scene, &tex, &uOffset ); - SAA_texture2DGetVOffset( scene, &tex, &vOffset ); - SAA_texture2DGetUVSwap( scene, &tex, &uv_swap ); - - - if ( verbose >= 2 ) - { - fprintf( outStream, "tex uScale: %f\n", uScale ); - fprintf( outStream, "tex vScale: %f\n", vScale ); - fprintf( outStream, "tex uOffset: %f\n", uOffset ); - fprintf( outStream, "tex vOffset: %f\n", vOffset ); - if ( uv_swap ) - fprintf( outStream, "nurbTex u & v swapped!\n" ); - else - fprintf( outStream, "nurbTex u & v NOT swapped\n" ); - } - - - // find the vpool for this model - EggVertexPool *vPool = - (EggVertexPool *)(_data.pools.FindName( modelName )); - - // if we found the pool - if ( vPool != NULL ) - { - // generate duv's for model - float oldOffsets[4]; - double u, v, du, dv; - int size; - SAA_Boolean bigEndian; - - SAA_elementGetUserDataSize( scene, model, "TEX_OFFSETS", &size ); - - if ( size != 0 ) - { - // remember original texture offsets future reference - SAA_elementGetUserData( scene, model, "TEX_OFFSETS", - size, &bigEndian, (void *)&oldOffsets ); - - // get the original scales and offsets - u = oldOffsets[0]; - v = oldOffsets[1]; - - du = u - uOffset; - dv = v - vOffset; - - if ( verbose >= 1 ) - { - fprintf( outStream, "original u = %f, v = %f\n", - u, v ); - fprintf( outStream, "u = %f, v = %f\n", - uOffset, vOffset ); - fprintf( outStream, "du = %f, dv = %f\n", - du, dv ); - } - - strstream uName, vName; - - // create duv target names - uName << modelName << ".u" << ends; - vName << modelName << ".v" << ends; - - // find the appropriate table to store the duv animation - // info into - SAnimTable *thisTable; - - // find the duv U table associated with this model - thisTable = (SAnimTable *)(morphRoot->FindDescendent( - uName.str() )); - - if ( thisTable != NULL ) - { - thisTable->AddElement( du ); - if ( verbose >= 1 ) - fprintf( outStream, "adding element %f to %s\n", - du, uName.str() ); - } - else - fprintf( outStream, "Couldn't find uTable %s\n", - uName.str() ); - - // find the duv V table associated with this model - thisTable = (SAnimTable *)(morphRoot->FindDescendent( - vName.str() )); - - if ( thisTable != NULL ) - { - thisTable->AddElement( dv ); - if ( verbose >= 1 ) - fprintf( outStream, "adding element %f to %s\n", - dv, uName.str() ); - } - else - fprintf( outStream, "Couldn't find vTable %s\n", - uName.str() ); - } - } - else - if ( verbose >= 2 ) - fprintf( outStream, "Couldn't find vpool %s\n", modelName ); - } - - // free( materials ); - } -} -#endif - -/** - * Instantiate converter and process a file - */ -EXPCL_MISC SI_Error soft2egg(int argc, char *argv[]) { - // pass control to the c++ system - init_soft2egg(argc, argv); - return SI_SUCCESS; -} -#ifdef __cplusplus -} -#endif diff --git a/pandatool/src/softegg/softEggGroupUserData.I b/pandatool/src/softegg/softEggGroupUserData.I deleted file mode 100644 index c6d2a5082c..0000000000 --- a/pandatool/src/softegg/softEggGroupUserData.I +++ /dev/null @@ -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; -} diff --git a/pandatool/src/softegg/softEggGroupUserData.cxx b/pandatool/src/softegg/softEggGroupUserData.cxx deleted file mode 100644 index 1705b2b285..0000000000 --- a/pandatool/src/softegg/softEggGroupUserData.cxx +++ /dev/null @@ -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; diff --git a/pandatool/src/softegg/softEggGroupUserData.h b/pandatool/src/softegg/softEggGroupUserData.h deleted file mode 100644 index b8aa6ca892..0000000000 --- a/pandatool/src/softegg/softEggGroupUserData.h +++ /dev/null @@ -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 diff --git a/pandatool/src/softegg/softNodeDesc.cxx b/pandatool/src/softegg/softNodeDesc.cxx deleted file mode 100644 index ff0f624a20..0000000000 --- a/pandatool/src/softegg/softNodeDesc.cxx +++ /dev/null @@ -1,1310 +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.cxx - * @author masad - * @date 2003-10-03 - */ - -#include "softNodeDesc.h" -#include "config_softegg.h" -#include "eggGroup.h" -#include "eggXfmSAnim.h" -#include "eggSAnimData.h" -#include "softToEggConverter.h" -#include "dcast.h" - -using std::endl; - -TypeHandle SoftNodeDesc::_type_handle; - -/** - * - */ -SoftNodeDesc:: -SoftNodeDesc(SoftNodeDesc *parent, const std::string &name) : - Namable(name), - _parent(parent) -{ - _model = nullptr; - _egg_group = nullptr; - _egg_table = nullptr; - _anim = nullptr; - _joint_type = JT_none; - - // Add ourselves to our parent. - if (_parent != nullptr) { - softegg_cat.spam() << "parent name " << _parent->get_name(); - _parent->_children.push_back(this); - } - - // set the _parentJoint to Null - _parentJoint = nullptr; - - fullname = nullptr; - - numTexLoc = 0; - numTexGlb = 0; - - uScale = nullptr; - vScale = nullptr; - uOffset = nullptr; - vOffset = nullptr; - - valid; - uv_swap; - // SAA_Boolean visible; - numTexTri = nullptr; - textures = nullptr; - materials = nullptr; - triangles = nullptr; - gtype = SAA_GEOM_ORIGINAL; -} - -/** - * - */ -SoftNodeDesc:: -~SoftNodeDesc() { - // I think it is a mistake to try to delete this. This was one member of an - // entire array allocated at once; you can't delete individual elements of - // an array. - - // Screw cleanup, anyway--we'll just let the array leak. - /* - if (_model != (SAA_Elem *)NULL) { - delete _model; - } - */ -} - -/** - * Indicates an associated between the SoftNodeDesc and some SAA_Elem - * instance. - */ -void SoftNodeDesc:: -set_model(SAA_Elem *model) { - _model = model; -} - -/** - * Sometimes, parent is not known at node creation As soon as it is known, set - * the parent - */ -void SoftNodeDesc:: -set_parent(SoftNodeDesc *parent) { - if (_parent) { - softegg_cat.spam() << endl; - /* - softegg_cat.spam() << " expected _parent to be null!?\n"; - if (_parent == parent) - softegg_cat.spam() << " parent already set\n"; - else { - softegg_cat.spam() << " current parent " << _parent->get_name() << " new parent " - << parent << endl; - } - */ - return; - } - _parent = parent; - softegg_cat.spam() << " set parent to " << _parent->get_name() << endl; - - // Add ourselves to our parent. - _parent->_children.push_back(this); -} - -/** - * Sometimes, parent is not known at node creation As soon as it is known, set - * the parent - */ -void SoftNodeDesc:: -force_set_parent(SoftNodeDesc *parent) { - if (_parent) - softegg_cat.spam() << " current parent " << _parent->get_name(); - - _parent = parent; - - if (_parent) - softegg_cat.spam() << " new parent " << _parent->get_name() << endl; - - // Add ourselves to our parent. - _parent->_children.push_back(this); -} - -/** - * Returns true if a Soft dag path has been associated with this node, false - * otherwise. - */ -bool SoftNodeDesc:: -has_model() const { - return (_model != nullptr); -} - -/** - * Returns the SAA_Elem * associated with this node. It is an error to call - * this unless has_model() returned true. - */ -SAA_Elem *SoftNodeDesc:: -get_model() const { - nassertr(_model != nullptr, _model); - return _model; -} - -/** - * Returns true if the node should be treated as a joint by the converter. - */ -bool SoftNodeDesc:: -is_joint() const { - // return _joint_type == JT_joint || _joint_type == JT_pseudo_joint; - return _joint_type == JT_joint; -} - -/** - * Returns true if the node should be treated as a junk by the converter. - */ -bool SoftNodeDesc:: -is_junk() const { - return _joint_type == JT_junk; -} - -/** - * sets the _joint_type to JT_joint - */ -void SoftNodeDesc:: -set_joint() { - _joint_type = JT_joint; -} -/** - * Returns true if the node is the parent or ancestor of a joint. - */ -bool SoftNodeDesc:: -is_joint_parent() const { - return _joint_type == JT_joint_parent; -} - -/** - * Recursively clears the egg pointers from this node and all children. - */ -void SoftNodeDesc:: -clear_egg() { - _egg_group = nullptr; - _egg_table = nullptr; - _anim = nullptr; - - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - child->clear_egg(); - } -} - -/** - * Indicates that this node has at least one child that is a joint or a - * pseudo-joint. - */ -void SoftNodeDesc:: -mark_joint_parent() { - if (_joint_type == JT_none) { - _joint_type = JT_joint_parent; - softegg_cat.spam() << " marked parent " << get_name(); - } - else - softegg_cat.spam() << " ?parent " << get_name() << " joint type " << _joint_type; - - if (_parent != nullptr) { - _parent->mark_joint_parent(); - } - softegg_cat.spam() << endl; -} - -/** - * Walks the hierarchy, if a node is joint, make sure all its parents are - * marked JT_joint_parent - */ -void SoftNodeDesc:: -check_joint_parent() { - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - if (child->is_joint()) { - softegg_cat.spam() << "child " << child->get_name(); - mark_joint_parent(); - } - child->check_joint_parent(); - } -} - -/** - * check to see if this is a branch we don't want to descend - this will - * prevent creating geometry for animation control structures - */ -void SoftNodeDesc:: -check_junk(bool parent_junk) { - const char *name = get_name().c_str(); - - if (parent_junk) { - _joint_type = JT_junk; - softegg_cat.spam() << "junk node " << get_name() << endl; - } - if ( (strstr(name, "con-") != nullptr) || - (strstr(name, "con_") != nullptr) || - (strstr(name, "fly_") != nullptr) || - (strstr(name, "fly-") != nullptr) || - (strstr(name, "camRIG") != nullptr) || - (strstr(name, "cam_rig") != nullptr) || - (strstr(name, "bars") != nullptr) ) - { - _joint_type = JT_junk; - softegg_cat.spam() << "junk node " << get_name() << endl; - parent_junk = true; - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - softegg_cat.spam() << child->get_name() << ","; - } - softegg_cat.spam() << endl; - } - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - child->check_junk(parent_junk); - } -} - -/** - * check to see if this is a selected branch we want to descend - this will - * prevent creating geometry for other parts - */ -bool SoftNodeDesc:: -is_partial(char *search_prefix) { - const char *name = fullname; - - // if no search prefix then return false - if (!search_prefix) - return false; - // if name is search_prefix, return false - if (strstr(name, search_prefix) != nullptr) { - softegg_cat.debug() << "matched " << name << " "; - return false; - } - // if name is not search_prefix, look in its parent - if (strstr(name, search_prefix) == nullptr) { - softegg_cat.debug() << "node " << name << " "; - if (_parent) - return _parent->is_partial(search_prefix); - } - // neither name nor its parent is search_prefix - return true; -} - -/** - * Go through the ancestors and figure out who is the immediate _parentJoint - * of this node - */ -void SoftNodeDesc:: -set_parentJoint(SAA_Scene *scene, SoftNodeDesc *lastJoint) { - if (is_junk()) - return; - // set its parent joint to the lastJoint - _parentJoint = lastJoint; - softegg_cat.spam() << get_name() << ": parent joint set to :" << lastJoint; - if (lastJoint) - softegg_cat.spam() << "(" << lastJoint->get_name() << ")"; - softegg_cat.spam() << endl; - - // is this node a joint? - SAA_Boolean isSkeleton = false; - if (has_model()) - SAA_modelIsSkeleton( scene, get_model(), &isSkeleton ); - - // if already a joint or name has "joint" in it - const char *name = get_name().c_str(); - if (is_joint() || isSkeleton || strstr(name, "joint") != nullptr) { - lastJoint = this; - } - if ( _parentJoint && strstr( _parentJoint->get_name().c_str(), "scale" ) != nullptr ) { - // make sure _parentJoint didn't have the name "joint" in it - if (strstr(_parentJoint->get_name().c_str(), "joint") == nullptr) { - _parentJoint = nullptr; - // _parentJoint = lastJoint = NULL; - softegg_cat.spam() << "scale joint flag set!\n"; - } - } - - // look in the children - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - child->set_parentJoint(scene, lastJoint); - } -} - -/** - * Walks the hierarchy, looking for non-joint nodes that are both children and - * parents of a joint. These nodes are deemed to be pseudo joints, since the - * converter must treat them as joints. - */ -void SoftNodeDesc:: -check_pseudo_joints(bool joint_above) { - if (_joint_type == JT_joint_parent && joint_above) { - // This is one such node: it is the parent of a joint (JT_joint_parent is - // set), and it is the child of a joint (joint_above is set). - _joint_type = JT_pseudo_joint; - softegg_cat.debug() << "pseudo " << get_name() << " case1\n"; - } - - if (_joint_type == JT_joint) { - // If this node is itself a joint, then joint_above is true for all child - // nodes. - joint_above = true; - } - - // Don't bother traversing further if _joint_type is none or junk, since - // that means this node has no joint children. - if (_joint_type != JT_none && _joint_type != JT_junk) { - - bool any_joints = false; - Children::const_iterator ci; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - child->check_pseudo_joints(joint_above); - if (child->is_joint()) { - softegg_cat.spam() << get_name() << " any_joint true by " << child->get_name() << endl; - any_joints = true; - } - } - - // If any children qualify as joints, then any sibling nodes that are - // parents of joints are also elevated to joints. - if (any_joints) { - bool all_joints = true; - for (ci = _children.begin(); ci != _children.end(); ++ci) { - SoftNodeDesc *child = (*ci); - if (child->_joint_type == JT_joint_parent) { - child->_joint_type = JT_pseudo_joint; - softegg_cat.debug() << "pseudo " << child->get_name() << " case2 by parent " << get_name() << "\n"; - } else if (child->_joint_type == JT_none || child->_joint_type == JT_junk) { - all_joints = false; - } - } - - if (all_joints || any_joints) { - // Finally, if all children or at least one is a joint, then we are - // too. - if (_joint_type == JT_joint_parent) { - _joint_type = JT_pseudo_joint; - softegg_cat.debug() << "pseudo " << get_name() << " case3\n"; - } - } - } - } - else - softegg_cat.spam() << "found null joint " << get_name() << endl; -} - -/** - * Extracts the transform on the indicated Soft node, and applies it to the - * corresponding Egg node. - */ -void SoftNodeDesc:: -get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global) { - // Get the model's matrix - int scale_joint = 0; - - if (!global && _parentJoint && !stec.flatten && !scale_joint) { - - SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_LOCAL, matrix ); - softegg_cat.debug() << get_name() << " using local matrix :parent "; - - } else { - - SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_GLOBAL, matrix ); - softegg_cat.debug() << get_name() << " using global matrix :parent "; - - } - - if (_parentJoint && !stec.flatten) - softegg_cat.debug() << _parentJoint->get_name() << endl; - else - softegg_cat.debug() << _parentJoint << endl; - - - softegg_cat.spam() << "model matrix = " << matrix[0][0] << " " << matrix[0][1] << " " << matrix[0][2] << " " << matrix[0][3] << "\n"; - softegg_cat.spam() << "model matrix = " << matrix[1][0] << " " << matrix[1][1] << " " << matrix[1][2] << " " << matrix[1][3] << "\n"; - softegg_cat.spam() << "model matrix = " << matrix[2][0] << " " << matrix[2][1] << " " << matrix[2][2] << " " << matrix[2][3] << "\n"; - softegg_cat.spam() << "model matrix = " << matrix[3][0] << " " << matrix[3][1] << " " << matrix[3][2] << " " << matrix[3][3] << "\n"; - - if (!global && is_joint()) { - LMatrix4d m4d(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3], - matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3], - matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3], - matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]); - if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) { - egg_group->set_transform3d(m4d); - softegg_cat.spam() << "set transform in egg_group\n"; - } - } - return; -} - -/** - * Extracts the transform on the indicated Soft node, as appropriate for a - * joint in an animated character, and applies it to the indicated node. This - * is different from get_transform() in that it does not respect the - * _transform_type flag, and it does not consider the relative transforms - * within the egg file. more added functionality: now fills in components of - * anim (EffXfmSAnim) class (masad). - */ -void SoftNodeDesc:: -get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global) { - // SI_Error result; - SAA_Elem *skeletonPart = _model; - const char *name = get_name().c_str(); - - if ( skeletonPart != nullptr ) { - PN_stdfloat i,j,k; - PN_stdfloat h,p,r; - PN_stdfloat x,y,z; - int scale_joint = 0; - - softegg_cat.spam() << "\n\nanimating child " << name << endl; - - if (_parentJoint && !stec.flatten && !scale_joint ) { - softegg_cat.debug() << "using local matrix\n"; - - // get SAA orientation - SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &p, &h, &r ); - - // get SAA translation - SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &x, &y, &z ); - - // get SAA scaling - SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL, - &i, &j, &k ); - } else { - softegg_cat.debug() << " using global matrix\n"; - - // get SAA orientation - SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &p, &h, &r ); - - // get SAA translation - SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &x, &y, &z ); - - // get SAA scaling - SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL, - &i, &j, &k ); - } - - softegg_cat.spam() << "\nanim data: " << i << " " << j << " " << k << endl; - softegg_cat.spam() << "\t" << p << " " << h << " " << r << endl; - softegg_cat.spam() << "\t" << x << " " << y << " " << z << endl; - - // Encode the component multiplication ordering in the egg file. - // SoftImage always uses this order, regardless of the setting of temp- - // hpr-fix. - anim->set_order("sphrt"); - - // Add each component by their names - anim->add_component_data("i", i); - anim->add_component_data("j", j); - anim->add_component_data("k", k); - anim->add_component_data("p", p); - anim->add_component_data("h", h); - anim->add_component_data("r", r); - anim->add_component_data("x", x); - anim->add_component_data("y", y); - anim->add_component_data("z", z); - } - else { - softegg_cat.debug() << "Cannot build anim table - no skeleton\n"; - } -} - -/** - * Converts the indicated Soft polyset to a bunch of EggPolygons and parents - * them to the indicated egg group. - */ -void SoftNodeDesc:: -load_poly_model(SAA_Scene *scene, SAA_ModelType type) { - SI_Error result; - const char *name = get_name().c_str(); - - int i; - int id = 0; - - // if making a pose - get deformed geometry - if ( stec.make_pose ) - gtype = SAA_GEOM_DEFORMED; - - // If the model is a PATCH in soft, set its step before tesselating - else if ( type == SAA_MPTCH ) - SAA_patchSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step ); - - // Get the number of triangles - result = SAA_modelGetNbTriangles( scene, _model, gtype, id, &numTri); - softegg_cat.spam() << "triangles: " << numTri << "\n"; - - if ( result != SI_SUCCESS ) { - softegg_cat.spam() << "Error: couldn't get number of triangles!\n"; - softegg_cat.debug() << "\tbailing on model: " << name << "\n"; - return; - } - - // check to see if surface is also skeleton... - SAA_Boolean isSkeleton = FALSE; - - SAA_modelIsSkeleton( scene, _model, &isSkeleton ); - - // check to see if this surface 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) - softegg_cat.spam() << "is Skeleton? " << isSkeleton << "\n"; - - /*************************************************************************************/ - - // model is not a null and has no triangles! - if ( !numTri ) { - softegg_cat.spam() << "no triangles!\n"; - } - else { - // allocate array of triangles - triangles = (SAA_SubElem *) new SAA_SubElem[numTri]; - if (!triangles) { - softegg_cat.info() << "Not enough Memory for triangles...\n"; - exit(1); - } - // triangulate model and read the triangles into array - SAA_modelGetTriangles( scene, _model, gtype, id, numTri, triangles ); - softegg_cat.spam() << "got triangles\n"; - - /***********************************************************************************/ - - // allocate array of materials (Asad: it gives a warning if try to get one - // triangle at a time...investigate later read each triangle's material - // into array - materials = (SAA_Elem*) new SAA_Elem[numTri]; - SAA_triangleGetMaterials( scene, _model, numTri, triangles, materials ); - if (!materials) { - softegg_cat.info() << "Not enough Memory for materials...\n"; - exit(1); - } - softegg_cat.spam() << "got materials\n"; - - /***********************************************************************************/ - - // allocate array of textures per triangle - numTexTri = new int[numTri]; - const void *relinfo; - - // find out how many local textures per triangle - for (i = 0; i < numTri; i++) { - result = SAA_materialRelationGetT2DLocNbElements( scene, &materials[i], FALSE, - &relinfo, &numTexTri[i] ); - // polytex - if ( result == SI_SUCCESS ) - numTexLoc += numTexTri[i]; - } - - // don't need this anymore... free( numTexTri ); - - // get local textures if present - if ( numTexLoc ) { - softegg_cat.spam() << "numTexLoc = " << numTexLoc << endl; - - // allocate arrays of texture info - uScale = new PN_stdfloat[numTri]; - vScale = new PN_stdfloat[numTri]; - uOffset = new PN_stdfloat[numTri]; - vOffset = new PN_stdfloat[numTri]; - texNameArray = new char *[numTri]; - uRepeat = new int[numTri]; - vRepeat = new int[numTri]; - - // ASSUME only one texture per material - textures = new SAA_Elem[numTri]; - - for ( i = 0; i < numTri; i++ ) { - // and read all referenced local textures into array - SAA_materialRelationGetT2DLocElements( scene, &materials[i], - TEX_PER_MAT , &textures[i] ); - - // initialize the array value - texNameArray[i] = nullptr; - // initialize the repeats - uRepeat[i] = vRepeat[i] = 0; - - // see if this triangle has texture info - if (numTexTri[i] == 0) - continue; - - // check to see if texture is present - result = SAA_elementIsValid( scene, &textures[i], &valid ); - - if ( result != SI_SUCCESS ) - softegg_cat.spam() << "SAA_elementIsValid failed!!!!\n"; - - // texture present - get the name and uv info - if ( valid ) { - // according to drose, we don't need to convert .pic files to .rgb, - // panda can now read the .pic files. - texNameArray[i] = stec.GetTextureName(scene, &textures[i]); - - softegg_cat.spam() << " tritex[" << i << "] named: " << texNameArray[i] << endl; - - SAA_texture2DGetUVSwap( scene, &textures[i], &uv_swap ); - - if ( uv_swap == TRUE ) - softegg_cat.spam() << " swapping u and v...\n" ; - - SAA_texture2DGetUScale( scene, &textures[i], &uScale[i] ); - SAA_texture2DGetVScale( scene, &textures[i], &vScale[i] ); - SAA_texture2DGetUOffset( scene, &textures[i], &uOffset[i] ); - SAA_texture2DGetVOffset( scene, &textures[i], &vOffset[i] ); - - softegg_cat.spam() << "tritex[" << i << "] uScale: " << uScale[i] << " vScale: " << vScale[i] << endl; - softegg_cat.spam() << " uOffset: " << uOffset[i] << " vOffset: " << vOffset[i] << endl; - - SAA_texture2DGetRepeats( scene, &textures[i], &uRepeat[i], &vRepeat[i] ); - softegg_cat.spam() << "uRepeat = " << uRepeat[i] << ", vRepeat = " << vRepeat[i] << endl; - } - else { - softegg_cat.spam() << "Invalid texture...\n"; - softegg_cat.spam() << " tritex[" << i << "] named: (null)\n"; - } - } - } - else { // if no local textures, try to get global textures - SAA_modelRelationGetT2DGlbNbElements( scene, _model, - FALSE, &relinfo, &numTexGlb ); - if ( numTexGlb ) { - // ASSUME only one texture per model - textures = new SAA_Elem; - // get the referenced texture - SAA_modelRelationGetT2DGlbElements( scene, _model, - TEX_PER_MAT, textures ); - softegg_cat.spam() << "numTexGlb = " << numTexGlb << endl; - // check to see if texture is present - SAA_elementIsValid( scene, textures, &valid ); - if ( valid ) { // texture present - get the name and uv info - SAA_texture2DGetUVSwap( scene, textures, &uv_swap ); - - if ( uv_swap == TRUE ) - softegg_cat.spam() << " swapping u and v...\n"; - - // according to drose, we don't need to convert .pic files to .rgb, - // panda can now read the .pic files. - texNameArray = new char *[1]; - *texNameArray = stec.GetTextureName(scene, textures); - - uRepeat = new int; - vRepeat = new int; - - softegg_cat.spam() << " global tex named: " << *texNameArray << endl; - - // allocate arrays of texture info - uScale = new PN_stdfloat; - vScale = new PN_stdfloat; - uOffset = new PN_stdfloat; - vOffset = new PN_stdfloat; - - SAA_texture2DGetUScale( scene, textures, uScale ); - SAA_texture2DGetVScale( scene, textures, vScale ); - SAA_texture2DGetUOffset( scene, textures, uOffset ); - SAA_texture2DGetVOffset( scene, textures, vOffset ); - - softegg_cat.spam() << " global tex uScale: " << *uScale << " vScale: " << *vScale << endl; - softegg_cat.spam() << " uOffset: " << *uOffset << " vOffset: " << *vOffset << endl; - - SAA_texture2DGetRepeats( scene, textures, uRepeat, vRepeat ); - softegg_cat.spam() << "uRepeat = " << *uRepeat << ", vRepeat = " << *vRepeat << endl; - } - else { - softegg_cat.spam() << "Invalid Texture...\n"; - } - } - } - } - softegg_cat.spam() << "got textures" << endl; -} - -/** - * Converts the indicated Soft polyset to a bunch of EggPolygons and parents - * them to the indicated egg group. - */ -void SoftNodeDesc:: -load_nurbs_model(SAA_Scene *scene, SAA_ModelType type) { - SI_Error result; - const char *name = get_name().c_str(); - - // if making a pose - get deformed geometry - if ( stec.make_pose ) - gtype = SAA_GEOM_DEFORMED; - - // If the model is a NURBS in soft, set its step before tesselating - if ( type == SAA_MNSRF ) - SAA_nurbsSurfaceSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step ); - - // get the materials - /***********************************************************************************/ - const void *relinfo; - - SAA_modelRelationGetMatNbElements( scene, get_model(), FALSE, &relinfo, - &numNurbMats ); - - softegg_cat.spam() << "nurbs surf has " << numNurbMats << " materials\n"; - - if ( numNurbMats ) { - materials = new SAA_Elem[numNurbMats]; - if (!materials) { - softegg_cat.info() << "Out Of Memory on allocating materials\n"; - exit(1); - } - - SAA_modelRelationGetMatElements( scene, get_model(), relinfo, - numNurbMats, materials ); - - softegg_cat.spam() << "got materials\n"; - - // get the textures - /***********************************************************************************/ - numNurbTexLoc = 0; - numNurbTexGlb = 0; - - // find out how many local textures per NURBS surface ASSUME it only has - // one material - SAA_materialRelationGetT2DLocNbElements( scene, &materials[0], FALSE, &relinfo, &numNurbTexLoc ); - - // if present, get local textures - if ( numNurbTexLoc ) { - softegg_cat.spam() << name << " had " << numNurbTexLoc << " local tex\n"; - nassertv(numNurbTexLoc == 1); - - textures = new SAA_Elem[numNurbTexLoc]; - - // get the referenced texture - SAA_materialRelationGetT2DLocElements( scene, &materials[0], TEX_PER_MAT, &textures[0] ); - - } - // if no locals, try to get globals - else { - SAA_modelRelationGetT2DGlbNbElements( scene, get_model(), FALSE, &relinfo, &numNurbTexGlb ); - - if ( numNurbTexGlb ) { - softegg_cat.spam() << name << " had " << numNurbTexGlb << " global tex\n"; - nassertv(numNurbTexGlb == 1); - - textures = new SAA_Elem[numNurbTexGlb]; - - // get the referenced texture - SAA_modelRelationGetT2DGlbElements( scene, get_model(), TEX_PER_MAT, &textures[0] ); - } - } - - if ( numNurbTexLoc || numNurbTexGlb) { - - // allocate the texture name array - texNameArray = new char *[1]; - // allocate arrays of texture info - uScale = new PN_stdfloat; - vScale = new PN_stdfloat; - uOffset = new PN_stdfloat; - vOffset = new PN_stdfloat; - uRepeat = new int; - vRepeat = new int; - - // check to see if texture is present - result = SAA_elementIsValid( scene, &textures[0], &valid ); - - if ( result != SI_SUCCESS ) - softegg_cat.spam() << "SAA_elementIsValid failed!!!!\n"; - - // texture present - get the name and uv info - if ( valid ) { - // according to drose, we don't need to convert .pic files to .rgb, - // panda can now read the .pic files. - texNameArray[0] = stec.GetTextureName(scene, &textures[0]); - - softegg_cat.spam() << " tritex[0] named: " << texNameArray[0] << endl; - - SAA_texture2DGetUVSwap( scene, &textures[0], &uv_swap ); - - if ( uv_swap == TRUE ) - softegg_cat.spam() << " swapping u and v...\n" ; - - SAA_texture2DGetUScale( scene, &textures[0], uScale ); - SAA_texture2DGetVScale( scene, &textures[0], vScale ); - SAA_texture2DGetUOffset( scene, &textures[0], uOffset ); - SAA_texture2DGetVOffset( scene, &textures[0], vOffset ); - - softegg_cat.spam() << "tritex[0] uScale: " << *uScale << " vScale: " << *vScale << endl; - softegg_cat.spam() << " uOffset: " << *uOffset << " vOffset: " << *vOffset << endl; - - SAA_texture2DGetRepeats( scene, &textures[0], uRepeat, vRepeat ); - softegg_cat.spam() << "uRepeat = " << *uRepeat << ", vRepeat = " << *vRepeat << endl; - } - else { - softegg_cat.spam() << "Invalid texture...\n"; - softegg_cat.spam() << " tritex[0] named: (null)\n"; - } - } - - softegg_cat.spam() << "got textures\n"; - } -} - -/** - * given a vertex, find its corresponding shape vertex and return its index. - */ -int SoftNodeDesc:: -find_shape_vert(LPoint3d p3d, SAA_DVector *vertices, int numVert) { - int i, found = 0; - - for (i = 0; i < numVert && !found ; i++) { - if ((p3d[0] == vertices[i].x) && - (p3d[1] == vertices[i].y) && - (p3d[2] == vertices[i].z)) { - found = 1; - softegg_cat.spam() << "found shape vert at index " << i << endl; - } - } - - if (!found ) - i = -1; - else - i--; - - return i; -} - -/** - * Given a scene, a model , the vertices of its original shape and its name - * find the difference between the geometry of its key shapes and the models - * original geometry and add morph vertices to the egg data to reflect these - * changes. - */ -void SoftNodeDesc:: -make_vertex_offsets(int numShapes) { - int i, j; - int offset; - int numCV; - char tableName[_MAX_PATH]; - SAA_DVector *shapeVerts = nullptr; - SAA_DVector *uniqueVerts = nullptr; - SAA_Elem *model = get_model(); - SAA_Scene *scene = &stec.scene; - - EggVertexPool *vpool = nullptr; - std::string vpool_name = get_name() + ".verts"; - EggNode *t = stec._tree.get_egg_root()->find_child(vpool_name); - if (t) - DCAST_INTO_V(vpool, t); - - int numOrigVert = (int) vpool->size(); - EggVertexPool::iterator vi; - - if ((type == SAA_MNSRF) && stec.make_nurbs) - SAA_nurbsSurfaceSetStep( scene, model, stec.nurbs_step, stec.nurbs_step ); - - SAA_modelGetNbVertices( scene, model, &numCV ); - - // get the shape verts - uniqueVerts = new SAA_DVector[numCV]; - SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0, - numCV, uniqueVerts ); - - softegg_cat.spam() << numCV << " CV's\n"; - - for ( i = 0; i < numCV; i++ ) - // convert vertices to global - _VCT_X_MAT( uniqueVerts[i], uniqueVerts[i], matrix); - softegg_cat.spam() << "uniqueVerts[" << i << "] = " << uniqueVerts[i].x << " " << uniqueVerts[i].y - << " " << uniqueVerts[i].z << " " << uniqueVerts[i].w << endl; - - // iterate through for each key shape (except original) - for ( i = 1; i < numShapes; i++ ) { - - sprintf(tableName, "%s.%d", get_name().c_str(), i); - - softegg_cat.spam() << "\nMaking geometry offsets for " << tableName << "...\n"; - - if ((type == SAA_MNSRF) && stec.make_nurbs) - softegg_cat.spam() << "calculating NURBS morphs...\n"; - else - softegg_cat.spam() << "calculating triangle morphs...\n"; - - // get the shape verts - shapeVerts = new SAA_DVector[numCV]; - SAA_modelGetVertices( scene, model, SAA_GEOM_SHAPE, i+1, numCV, shapeVerts ); - - for ( j=0; j < numCV; j++ ) { - // convert vertices to global - _VCT_X_MAT( shapeVerts[j], shapeVerts[j], matrix); - - softegg_cat.spam() << "shapeVerts[" << j << "] = " << shapeVerts[j].x << " " - << shapeVerts[j].y << " " << shapeVerts[j].z << endl; - } - softegg_cat.spam() << endl; - - // for every original vertex, compare to the corresponding key shape - // vertex and see if a vertex offset is needed - j = 0; - for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++j) { - - double dx, dy, dz; - EggVertex *vert = (*vi); - LPoint3d p3d = vert->get_pos3(); - - softegg_cat.spam() << "oVert[" << j << "] = " << p3d[0] << " " << p3d[1] << " " << p3d[2] << endl; - if ((type == SAA_MNSRF) && stec.make_nurbs) { - dx = shapeVerts[j].x - p3d[0]; - dy = shapeVerts[j].y - p3d[1]; - dz = shapeVerts[j].z - p3d[2]; - - softegg_cat.spam() << "global shapeVerts[" << j << "] = " << shapeVerts[j].x << " " - << shapeVerts[j].y << " " << shapeVerts[j].z << " " << shapeVerts[j].w << endl; - } - else { - // we need to map from original vertices to triangle shape vertices - // here - offset = find_shape_vert(p3d, uniqueVerts, numCV); - - dx = shapeVerts[offset].x - p3d[0]; - dy = shapeVerts[offset].y - p3d[1]; - dz = shapeVerts[offset].z - p3d[2]; - - softegg_cat.spam() << "global shapeVerts[" << offset << "] = " << shapeVerts[offset].x << " " - << shapeVerts[offset].y << " " << shapeVerts[offset].z << endl; - } - - softegg_cat.spam() << j << ": dx = " << dx << ", dy = " << dy << ", dz = " << dz << endl; - - // if change isn't negligible, make a morph vertex entry - double total = fabs(dx)+fabs(dy)+fabs(dz); - if ( total > 0.00001 ) { - if ( vpool != nullptr ) { - // create offset - LVector3d p(dx, dy, dz); - EggMorphVertex *dxyz = new EggMorphVertex(tableName, p); - // add the offset to the vertex - vert->_dxyzs.insert(*dxyz); - } - else - softegg_cat.spam() << "Error: couldn't find vertex pool " << vpool_name << endl; - - } // if total - } //for j - } //for i -} - -/** - * Given a scene, a model, a name and a frame time, determine what type of - * shape interpolation is used and call the appropriate function to extract - * the shape weight info for this frame... - */ -void SoftNodeDesc:: -make_morph_table( PN_stdfloat time ) { - int numShapes; - SAA_Elem *model = nullptr; - SAA_AnimInterpType type; - SAA_Scene *scene = &stec.scene; - - if (has_model()) - model = get_model(); - else - return; - - // Get the number of key shapes - SAA_modelGetNbShapes( scene, model, &numShapes ); - - if ( numShapes <= 0 ) { - return; - } - - stec.has_morph = true; - - softegg_cat.spam() << "make_morph_table: " << get_name() << " : num shapes: " << numShapes << endl; - - SAA_modelGetShapeInterpolation( scene, model, &type ); - - if ( type == SAA_ANIM_LINEAR || type == SAA_ANIM_CARDINAL ) { - softegg_cat.spam() << "linear morph" << endl; - make_linear_morph_table( numShapes, time ); - } - else { // must be weighted... - // check first for expressions - softegg_cat.spam() << "expression morph" << endl; - make_expression_morph_table( numShapes, time ); - } -} - -/** - * Given a scene, a model, its name, and the time, get the shape fcurve for - * the model and determine the shape weights for the given time and use them - * to populate the morph table. - */ -void SoftNodeDesc:: -make_linear_morph_table(int numShapes, PN_stdfloat time) { - int i; - PN_stdfloat curveVal; - char tableName[_MAX_PATH]; - SAA_Elem fcurve; - // SAnimTable *thisTable; - EggSAnimData *anim; - SAA_Elem *model = get_model(); - SAA_Scene *scene = &stec.scene; - - softegg_cat.spam() << "linear interp, getting fcurve\n"; - - SAA_modelFcurveGetShape( scene, model, &fcurve ); - - SAA_fcurveEval( scene, &fcurve, time, &curveVal ); - - softegg_cat.spam() << "at time " << time << ", fcurve for " << get_name() << " = " << curveVal << endl; - - PN_stdfloat nextVal = 0.0f; - - // populate morph table values for this frame - for ( i = 1; i < numShapes; i++ ) { - // derive table name from the model name - sprintf(tableName, "%s.%d", get_name().c_str(), i); - - softegg_cat.spam() << "Linear: looking for table '" << tableName << "'\n"; - - // find the morph table associated with this key shape - anim = stec.find_morph_table(tableName); - - if ( anim != nullptr ) { - if ( i == (int)curveVal ) { - if ( curveVal - i == 0 ) { - anim->add_data(1.0f ); - softegg_cat.spam() << "adding element 1.0f\n"; - } - else { - anim->add_data(1.0f - (curveVal - i)); - nextVal = curveVal - i; - softegg_cat.spam() << "adding element " << 1.0f - (curveVal - i) << endl; - } - } - else { - if ( nextVal ) { - anim->add_data(nextVal ); - nextVal = 0.0f; - softegg_cat.spam() << "adding element " << nextVal << endl; - } - else { - anim->add_data(0.0f); - softegg_cat.spam() << "adding element 0.0f\n"; - } - } - - softegg_cat.spam() <<" to '" << tableName << "'\n"; - } - else - softegg_cat.spam() << i << " : Couldn't find table '" << tableName << "'\n"; - } -} - -/** - * Given a scene, a model, a list of all models in the scene, the number of - * models in the scece, the number of key shapes for this model, the name of - * the model and the current time, determine what method of controlling the - * shape weights is used and call the appropriate routine. - */ -void SoftNodeDesc:: -make_weighted_morph_table(int numShapes, PN_stdfloat time) { - PN_stdfloat curveVal; - SI_Error result; - char tableName[_MAX_PATH]; - SAA_Elem *weightCurves; - // SAnimTable *thisTable; - EggSAnimData *anim; - SAA_Elem *model = get_model(); - SAA_Scene *scene = &stec.scene; - - // allocate array of weight curves (one for each shape) - weightCurves = new SAA_Elem[numShapes]; - - result = SAA_modelFcurveGetShapeWeights(scene, model, numShapes, weightCurves); - - if ( result == SI_SUCCESS ) { - for ( int i = 1; i < numShapes; i++ ) { - SAA_fcurveEval( scene, &weightCurves[i], time, &curveVal ); - - // make sure soft gave us a reasonable number if (!isNum(curveVal)) - // curveVal = 0.0f; - - softegg_cat.spam() << "at time " << time << ", weightCurve[" << i << "] for " << get_name() << " = " << curveVal << endl; - - // derive table name from the model name - sprintf(tableName, "%s.%d", get_name().c_str(), i); - - // find and populate shape table - softegg_cat.spam() << "Weight: looking for table '" << tableName << "'\n"; - - // find the morph table associated with this key shape - anim = stec.find_morph_table(tableName); - - if ( anim != nullptr ) { - anim->add_data(curveVal); - softegg_cat.spam() << "adding element " << curveVal << endl; - } - else - softegg_cat.spam() << i << " : Couldn't find table '" << tableName << "'\n"; - } - } -} - -/** - * Given a scene, a model and its number of key shapes generate a morph table - * describing transitions btwn the key shapes by evaluating the positions of - * the controlling sliders. - */ -void SoftNodeDesc:: -make_expression_morph_table(int numShapes, PN_stdfloat time) -{ - // int j; - int numExp; - char *track; - // PN_stdfloat expVal; PN_stdfloat sliderVal; char *tableName; char - // *sliderName; SAnimTable *thisTable; - SAA_Elem *expressions; - SI_Error result; - - SAA_Elem *model = get_model(); - SAA_Scene *scene = &stec.scene; - - // populate morph table values for this frame - - // compose track name - track = nullptr; - - // find how many expressions for this shape - SAA_elementGetNbExpressions( scene, model, track, FALSE, &numExp ); - - softegg_cat.spam() << get_name() << " has " << numExp << " RHS expressions\n"; - - if ( numExp ) { - // get the expressions for this shape - expressions = new SAA_Elem[numExp]; - softegg_cat.spam() << "getting " << numExp << " RHS expressions...\n"; - - result = SAA_elementGetExpressions( scene, model, track, FALSE, - numExp, expressions ); - /* - if ( !result ) { - for ( j = 1; j < numExp; j++ ) { - if ( verbose >= 2 ) - { - // debug see what we got - int numvars; - - SAA_expressionGetNbVars( scene, &expressions[j], &numvars ); - - int *varnamelen; - int *varstrlen; - int expstrlen; - - varnamelen = (int *)malloc(sizeof(int)*numvars); - varstrlen = (int *)malloc(sizeof(int)*numvars); - - SAA_expressionGetStringLengths( scene, &expressions[j], - numvars, varnamelen, varstrlen, &expstrlen ); - - int *varnamesizes; - int *varstrsizes; - - varnamesizes = (int *)malloc(sizeof(int)*numvars); - varstrsizes = (int *)malloc(sizeof(int)*numvars); - - for ( int k = 0; k < numvars; k++ ) - { - varnamesizes[k] = varnamelen[k] + 1; - varstrsizes[k] = varstrlen[k] + 1; - } - - int expstrsize = expstrlen + 1; - - char **varnames; - char **varstrs; - - varnames = (char **)malloc(sizeof(char *)*numvars); - varstrs = (char **)malloc(sizeof(char *)*numvars); - - for ( k = 0; k < numvars; k++ ) - { - varnames[k] = (char *)malloc(sizeof(char)* - varnamesizes[k]); - - varstrs[k] = (char *)malloc(sizeof(char)* - varstrsizes[k]); - } - - char *expstr = (char *)malloc(sizeof(char)* expstrsize ); - - SAA_expressionGetStrings( scene, &expressions[j], numvars, - varnamesizes, varstrsizes, expstrsize, varnames, - varstrs, expstr ); - - if ( verbose >= 2 ) - { - fprintf( outStream, "expression = '%s'\n", expstr ); - fprintf( outStream, "has %d variables\n", numvars ); - } - } //if verbose - - if ( verbose >= 2 ) - fprintf( outStream, "evaling expression...\n" ); - - SAA_expressionEval( scene, &expressions[j], time, &expVal ); - - if ( verbose >= 2 ) - fprintf( outStream, "time %f: exp val %f\n", - time, expVal ); - - // derive table name from the model name - tableName = MakeTableName( name, j ); - - if ( verbose >= 2 ) - fprintf( outStream, "Exp: looking for table '%s'\n", - tableName ); - - // find the morph table associated with this key shape - anim = (SAnimTable *) - (morphRoot->FindDescendent( tableName )); - - if ( anim != NULL ) - { - anim->AddElement( expVal ); - if ( verbose >= 1 ) - fprintf( outStream, "%d: adding element %f to %s\n", - j, expVal, tableName ); - fflush( outStream ); - } - else - { - fprintf( outStream, "%d: Couldn't find table '%s'", j, - tableName ); - - fprintf( outStream, " for value %f\n", expVal ); - } - } - } - else - fprintf( outStream, "couldn't get expressions!!!\n" ); - */ - } - else { - softegg_cat.spam() << "weighted morph" << endl; - // no expression, use weight curves - make_weighted_morph_table(numShapes, time ); - } -} diff --git a/pandatool/src/softegg/softNodeDesc.h b/pandatool/src/softegg/softNodeDesc.h deleted file mode 100644 index c6512b7dda..0000000000 --- a/pandatool/src/softegg/softNodeDesc.h +++ /dev/null @@ -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 - -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 diff --git a/pandatool/src/softegg/softNodeTree.cxx b/pandatool/src/softegg/softNodeTree.cxx deleted file mode 100644 index 3b5be3252b..0000000000 --- a/pandatool/src/softegg/softNodeTree.cxx +++ /dev/null @@ -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 - -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; -} diff --git a/pandatool/src/softegg/softNodeTree.h b/pandatool/src/softegg/softNodeTree.h deleted file mode 100644 index afbef5877b..0000000000 --- a/pandatool/src/softegg/softNodeTree.h +++ /dev/null @@ -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 - -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 NodesByName; - NodesByName _nodes_by_name; - - typedef pvector Nodes; - Nodes _nodes; -}; - -#endif diff --git a/pandatool/src/softegg/softToEggConverter.cxx b/pandatool/src/softegg/softToEggConverter.cxx deleted file mode 100644 index 44dafefb62..0000000000 --- a/pandatool/src/softegg/softToEggConverter.cxx +++ /dev/null @@ -1,2122 +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.cxx - * @author masad - * @date 2003-09-25 - */ - -#include "softToEggConverter.h" -#include "config_softegg.h" -#include "softEggGroupUserData.h" - -#include "eggData.h" -#include "eggGroup.h" -#include "eggTable.h" -#include "eggVertex.h" -#include "eggComment.h" -#include "eggVertexPool.h" -#include "eggNurbsSurface.h" -#include "eggNurbsCurve.h" -#include "eggPolygon.h" -#include "eggPrimitive.h" -#include "eggTexture.h" -#include "eggTextureCollection.h" -#include "eggXfmSAnim.h" -#include "eggSAnimData.h" -#include "string_utils.h" -#include "dcast.h" - -using std::endl; -using std::string; - -SoftToEggConverter stec; - -const int TEX_PER_MAT = 1; - -/** - * - */ -SoftToEggConverter:: -SoftToEggConverter(const string &program_name) : - _program_name(program_name) -{ - _from_selection = false; - _polygon_output = false; - _polygon_tolerance = 0.01; - /* - _respect_maya_double_sided = maya_default_double_sided; - _always_show_vertex_color = maya_default_vertex_color; - */ - _transform_type = TT_model; - - database_name = nullptr; - scene_name = nullptr; - model_name = nullptr; - animFileName = nullptr; - eggFileName = nullptr; - tex_path = nullptr; - eggGroupName = nullptr; - tex_filename = nullptr; - search_prefix = nullptr; - result = SI_SUCCESS; - - // skeleton = new EggGroup(); - foundRoot = FALSE; - // animRoot = NULL; morphRoot = NULL; - geom_as_joint = 0; - make_anim = 0; - make_nurbs = 0; - make_poly = 0; - make_soft = 0; - make_morph = 1; - make_duv = 1; - make_dart = TRUE; - has_morph = 0; - make_pose = 0; - // animData.is_z_up = FALSE; - nurbs_step = 1; - anim_start = -1000; - anim_end = -1000; - anim_rate = 24; - pose_frame = -1; - verbose = 0; - flatten = 0; - shift_textures = 0; - ignore_tex_offsets = 0; - use_prefix = 0; -} - -/** - * - */ -SoftToEggConverter:: -SoftToEggConverter(const SoftToEggConverter ©) : - _from_selection(copy._from_selection), - /* - _maya(copy._maya), - */ - _polygon_output(copy._polygon_output), - _polygon_tolerance(copy._polygon_tolerance), - /* - _respect_maya_double_sided(copy._respect_maya_double_sided), - _always_show_vertex_color(copy._always_show_vertex_color), - */ - _transform_type(copy._transform_type) -{ -} - -/** - * - */ -SoftToEggConverter:: -~SoftToEggConverter() { - /* - close_api(); - */ -} -/** - * Displays the "what is this program" message, along with the usage message. - * Should be overridden in base classes to describe the current program. - */ -void SoftToEggConverter:: -Help() -{ - softegg_cat.info() << - "soft2egg takes a SoftImage scene or model\n" - "and outputs its contents as an egg file\n"; - - Usage(); -} - -/** - * Displays the usage message. - */ -void SoftToEggConverter:: -Usage() { - softegg_cat.info() - << "\nUsage:\n" - // << _commandName << " [opts] (must specify -m or -s)\n\n" - << "soft" << " [opts] (must specify -m or -s)\n\n" - << "Options:\n"; - - ShowOpts(); - softegg_cat.info() << "\n"; -} - -/** - * Displays the valid options. Should be extended in base classes to show - * additional options relevant to the current program. - */ -void SoftToEggConverter:: -ShowOpts() -{ - softegg_cat.info() << - " -r - Used to provide soft with the resource\n" - " Defaults to '/ful/ufs/soft371_mips2/3D/rsrc'.\n" - " -d - Database path.\n" - " -s - Indicates that a scene will be converted.\n" - " -m - Indicates that a model will be converted.\n" - " -t - Specify path to place converted textures.\n" - " -T - Specify filename for texture map listing.\n" - " -S - Specify step for nurbs surface triangulation.\n" - " -M - Specify model output filename. Defaults to scene name.\n" - " -A - Specify anim output filename. Defaults to scene name.\n" - " -N - Specify egg group name.\n" - " -k - Enable soft assignment for geometry.\n" - " -n - Specify egg NURBS representation instead of poly's.\n" - " -p - Specify egg polygon output for geometry.\n" - " -P - Specify frame number for static pose.\n" - " -b - Specify starting frame for animation (default = first).\n" - " -e - Specify ending frame for animation (default = last).\n" - " -f - Specify frame rate for animation playback.\n" - " -a - Compile animation tables if animation present.\n" - " -F - Ignore hierarchy and build a completely flat skeleton.\n" - " -v - Set debug level.\n" - " -x - Shift NURBS parameters to preserve Alias textures.\n" - " -i - Ignore Soft texture uv offsets.\n" - " -u - Use Soft prefix in model names.\n" - " -c - Cancel morph conversion.\n" - " -C - Cancel duv conversion.\n" - " -D - Don't make the output model a character.\n" - " -o - Convert only models with given prefix.\n"; - - // EggBase::ShowOpts(); -} - -/** - * Calls getopt() to parse the command-line switches. Calls HandleGetopts() - * to interpret each switch. Returns true if the parsing was successful; - * false if there was an error. Adjusts argc and argv to remove the switches - * from the parameter list. - */ -bool SoftToEggConverter:: -DoGetopts(int &argc, char **&argv) { - bool okflag = true; - int i = 0; - softegg_cat.info() << "argc " << argc << "\n"; - if (argc <2) { - Usage(); - okflag = false; - } - while( i < argc ) { - strcat(_commandLine, argv[i]); - strcat(_commandLine, " "); - ++i; - } - softegg_cat.info() << endl << _commandLine << endl; - - i = 1; - while ((i < argc) && (argv[i][0] == '-') && okflag) { - softegg_cat.info() << "arg " << i << " is " << argv[i] << "\n"; - okflag = HandleGetopts(i, argc, argv); - } - return okflag; -} - -/** - * increment idx based on what kind of option parsed Supported options are as - * follows: r:d:s:m:t:P:b:e:f:T:S:M:A:N:v:o:FhknpaxiucCD - */ -bool SoftToEggConverter:: -HandleGetopts(int &idx, int argc, char **argv) -{ - bool okflag = true; - - char flag = argv[idx][1]; // skip the '-' from option - - switch (flag) - { - case 'r': // Set the resource path for soft. - if ( strcmp( argv[idx+1], "" ) ) { - // Get the path. - rsrc_path = argv[idx+1]; - softegg_cat.info() << "using rsrc path " << rsrc_path << "\n"; - } - ++idx; - break; - - case 'd': // Set the database path. - if ( strcmp( argv[idx+1], "" ) ) { - // Get the path. - database_name = argv[idx+1]; - softegg_cat.info() << "using database " << database_name << "\n"; - } - ++idx; - break; - - case 's': // Check if its a scene. - if ( strcmp( argv[idx+1], "" ) ) { - // Get scene name. - scene_name = argv[idx+1]; - softegg_cat.info() << "loading scene " << scene_name << "\n"; - } - ++idx; - break; - - case 'm': // Check if its a model. - if ( strcmp( argv[idx+1], "" ) ) { - // Get model name. - model_name = argv[idx+1]; - softegg_cat.info() << "loading model " << model_name << endl; - } - ++idx; - break; - - case 't': // Get converted texture path. - if ( strcmp( argv[idx+1], "" ) ) { - // Get tex path name. - tex_path = argv[idx+1]; - softegg_cat.info() << "texture path: " << tex_path << endl; - } - ++idx; - break; - - case 'T': // Specify texture list filename. - if ( strcmp( argv[idx+1], "") ) { - // Get the name. - tex_filename = argv[idx+1]; - softegg_cat.info() << "creating texture list file: " << tex_filename << endl; - } - ++idx; - break; - - case 'S': // Set NURBS step. - if ( strcmp( argv[idx+1], "" ) ) { - nurbs_step = atoi(argv[idx+1]); - softegg_cat.info() << "NURBS step: " << nurbs_step << endl; - } - ++idx; - break; - - case 'M': // Set model output file name. - if ( strcmp( argv[idx+1], "" ) ) { - eggFileName = argv[idx+1]; - softegg_cat.info() << "Model output filename: " << eggFileName << endl; - } - ++idx; - break; - - case 'A': // Set anim output file name. - if ( strcmp( argv[idx+1], "" ) ) { - animFileName = argv[idx+1]; - softegg_cat.info() << "Anim output filename: " << animFileName << endl; - } - ++idx; - break; - - case 'N': // Set egg model name. - if ( strcmp( argv[idx+1], "" ) ) { - eggGroupName = argv[idx+1]; - softegg_cat.info() << "Egg group name: " << eggGroupName << endl; - } - ++idx; - break; - - case 'o': // Set search_prefix. - if ( strcmp( argv[idx+1], "" ) ) { - search_prefix = argv[idx+1]; - softegg_cat.info() << "Only converting models with prefix: " << search_prefix << endl; - } - ++idx; - break; - - case 'h': // print help message - Help(); - exit(1); - break; - - case 'c': // Cancel morph animation conversion - make_morph = FALSE; - softegg_cat.info() << "canceling morph conversion\n"; - break; - - case 'C': // Cancel uv animation conversion - make_duv = FALSE; - softegg_cat.info() << "canceling uv animation conversion\n"; - break; - - case 'D': // Omit the Dart flag - make_dart = FALSE; - softegg_cat.info() << "making a non-character model\n"; - break; - - case 'k': // Enable soft skinning - // make_soft = TRUE; fprintf( outStream, "enabling soft skinning\n" ); - softegg_cat.info() << "-k flag no longer necessary\n"; - break; - - case 'n': // Generate egg NURBS output - make_nurbs = TRUE; - softegg_cat.info() << "outputting egg NURBS info\n"; - break; - - case 'p': // Generate egg polygon output - make_poly = TRUE; - softegg_cat.info() << "outputting egg polygon info\n"; - break; - - case 'P': // Generate static pose from given frame - if ( strcmp( argv[idx+1], "" ) ) { - make_pose = TRUE; - pose_frame = atoi(argv[idx+1]); - softegg_cat.info() << "generating static pose from frame " << pose_frame << endl; - } - ++idx; - break; - - case 'a': // Compile animation tables. - make_anim = TRUE; - softegg_cat.info() << "attempting to compile anim tables\n"; - break; - - case 'F': // Build a flat skeleton. - flatten = TRUE; - softegg_cat.info() << "building a flat skeleton!!!\n"; - break; - - case 'x': // Shift NURBS parameters to preserve Alias textures. - shift_textures = TRUE; - softegg_cat.info() << "shifting NURBS parameters...\n"; - break; - - case 'i': // Ignore Soft uv texture offsets - ignore_tex_offsets = TRUE; - softegg_cat.info() << "ignoring texture offsets...\n"; - break; - - case 'u': // Use Soft prefix in model names - use_prefix = TRUE; - softegg_cat.info() << "using prefix in model names...\n"; - break; - - - case 'v': // print debug messages. - if ( strcmp( argv[idx+1], "" ) ) { - verbose = atoi(argv[idx+1]); - softegg_cat.info() << "using debug level " << verbose << endl; - } - ++idx; - break; - - case 'b': // Set animation start frame. - anim_start = atoi(argv[idx]+2); - softegg_cat.info() << "animation starting at frame: " << anim_start << endl; - break; - - case 'e': /// Set animation end frame. - anim_end = atoi(argv[idx]+2); - softegg_cat.info() << "animation ending at frame: " << anim_end << endl; - break; - - case 'f': /// Set animation frame rate. - if ( strcmp( argv[idx+1], "" ) ) { - anim_rate = atoi(argv[idx+1]); - softegg_cat.info() << "animation frame rate: " << anim_rate << endl; - } - ++idx; - break; - - default: - softegg_cat.info() << flag << " flag not supported\n"; - okflag = false; - } - idx++; - return (okflag); -} - -/** - * Allocates and returns a new copy of the converter. - */ -SomethingToEggConverter *SoftToEggConverter:: -make_copy() { - return new SoftToEggConverter(*this); -} - -/** - * Returns the English name of the file type this converter supports. - */ -string SoftToEggConverter:: -get_name() const { - return "Soft"; -} - -/** - * Returns the common extension of the file type this converter supports. - */ -string SoftToEggConverter:: -get_extension() const { - return "mb"; -} - -/** - * Returns the English name of the file type this converter supports. - */ -SoftNodeDesc *SoftToEggConverter:: -find_node(string name) { - return _tree.get_node(name); -} - -/** - * Given a texture element, return texture name with given tex_path - */ -char *SoftToEggConverter:: -GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) { - char *fileName = new char[_MAX_PATH]; - char tempName[_MAX_PATH]; - SAA_texture2DGetPicName( scene, texture, _MAX_PATH, tempName ); - - if (tex_path) { - // softegg_cat.spam() << "tempName :" << tempName << endl; - strcpy(fileName, tex_path); - - // do some processing on the name string - char *tmpName = nullptr; - tmpName = strrchr(tempName, '/'); - if (tmpName) - tmpName++; - else - tmpName = tempName; - - // softegg_cat.spam() << "tmpName : " << tmpName << endl; - strcat(fileName, "/"); - strcat(fileName, tmpName); - } - else { - strcpy(fileName, tempName); - } - - strcat(fileName, ".pic"); - // softegg_cat.spam() << "fileName : " << fileName << endl; - - return fileName; -} - -/** - * Handles the reading of the input file and converting it to egg. Returns - * true if successful, false otherwise. - * - * This is designed to be as generic as possible, generally in support of run- - * time loading. Also see convert_soft(). - */ -bool SoftToEggConverter:: -convert_file(const Filename &filename) { - if (!open_api()) { - softegg_cat.error() - << "Soft is not available.\n"; - return false; - } - if (_character_name.empty()) { - _character_name = filename.get_basename_wo_extension(); - } - return convert_soft(false); -} - -/** - * Fills up the egg_data structure according to the global soft model data. - * Returns true if successful, false if there is an error. If from_selection - * is true, the converted geometry is based on that which is selected; - * otherwise, it is the entire Soft scene. - */ -bool SoftToEggConverter:: -convert_soft(bool from_selection) { - bool all_ok = true; - - _from_selection = from_selection; - _textures.clear(); - - PT(EggData) egg_data = new EggData; - set_egg_data(egg_data); - softegg_cat.spam() << "eggData " << get_egg_data() << "\n"; - - // append the command line - softegg_cat.info() << _commandLine << endl; - get_egg_data()->insert(get_egg_data()->begin(), new EggComment("", _commandLine)); - - if (_egg_data->get_coordinate_system() != CS_default) { - softegg_cat.spam() << "coordinate system is not default\n"; - exit(1); - } - - _tree._use_prefix = use_prefix; - _tree._search_prefix = search_prefix; - all_ok = _tree.build_complete_hierarchy(scene, database); - - // Lets see if we have gotten the hierarchy right _tree.print_hierarchy(); - // exit(1); - - char *root_name = _tree.GetRootName( eggFileName ); - - softegg_cat.debug() << "main group name: " << root_name << endl; - if (root_name) - _character_name = root_name; - - if (make_poly || make_nurbs) { - // Specify that the texture names should be relative to the output file. - Filename output_filename(eggFileName); - _path_replace->_path_store = PS_relative; - _path_replace->_path_directory = output_filename.get_dirname(); - - if (!convert_char_model()) { - all_ok = false; - } - - // generate soft skinning assignments if desired - if (!make_soft_skin()) { - all_ok = false; - } - - // sometimes you need to hard assign some vertices - if (!cleanup_soft_skin()) { - all_ok = false; - } - - // reparent_decals(get_egg_data()); - softegg_cat.info() << "Converted Softimage file\n"; - - // write out the egg model file - _egg_data->write_egg(output_filename); - softegg_cat.info() << "Wrote Egg file " << output_filename << endl; - } - if (make_anim) { - if (!convert_char_chan()) { - all_ok = false; - } - - // reparent_decals(get_egg_data()); - softegg_cat.info() << "Converted Softimage file\n"; - - // write out the egg model file - _egg_data->write_egg(Filename(animFileName)); - softegg_cat.info() << "Wrote Anim file " << animFileName << endl; - } - return all_ok; -} - -/** - * Attempts to open the Soft API if it was not already open, and returns true - * if successful, or false if there is an error. - */ -bool SoftToEggConverter:: -open_api() { - if ((scene_name == nullptr && model_name == nullptr) || database_name == nullptr) { - Usage(); - exit( 1 ); - } - if ((result = SAA_Init(rsrc_path, FALSE)) != SI_SUCCESS) { - softegg_cat.info() << "Error: Couldn't get resource path!\n"; - exit( 1 ); - } - // cout << "got past init" << endl; - if ((result = SAA_databaseLoad(database_name, &database)) != SI_SUCCESS) { - softegg_cat.info() << "Error: Couldn't load database!\n"; - exit( 1 ); - } - // cout << "got past database load" << endl; - if ((result = SAA_sceneGetCurrent(&scene)) != SI_SUCCESS) { - softegg_cat.info() << "Error: Couldn't get current scene!\n"; - exit( 1 ); - } - // cout << "got past get current" << endl; - if ((result = SAA_sceneLoad( &database, scene_name, &scene )) != SI_SUCCESS) { - softegg_cat.info() << "Error: Couldn't load scene " << scene_name << "!\n"; - exit( 1 ); - } - // cout << "got past scene load" << endl; - if ( SAA_updatelistGet( &scene ) == SI_SUCCESS ) { - PN_stdfloat time; - - softegg_cat.info() << "setting Scene to frame " << pose_frame << "...\n"; - // SAA_sceneSetPlayCtrlCurrentFrame( &scene, pose_frame ); - SAA_frame2Seconds( &scene, pose_frame, &time ); - SAA_updatelistEvalScene( &scene, time ); - if ( make_pose ) - SAA_sceneFreeze(&scene); - } - - // if no egg filename specified, make up a name - if ( eggFileName == nullptr ) { - string madeName; - string tempName(scene_name); - string::size_type end = tempName.find(".dsc"); - if (end != string::npos) { - madeName.assign(tempName.substr(0,end)); - if ( make_nurbs ) - madeName.insert(madeName.size(), "-nurb"); - madeName.insert(madeName.size(), ".egg" ); - } - eggFileName = new char[madeName.size()+1]; - strcpy(eggFileName, madeName.c_str()); - - // if no anim filename specified, make up a name - if ( animFileName == nullptr ) { - madeName.assign(tempName.substr(0,end)); - madeName.insert(madeName.size(), "-chan.egg"); - animFileName = new char[strlen(scene_name)+ 10]; - strcpy(animFileName, madeName.c_str()); - } - } - - return true; -} - -/** - * Closes the Soft API, if it was previously opened. Caution! Soft appears - * to call exit() when its API is closed. - */ -void SoftToEggConverter:: -close_api() { - // don't know yet -} - -/** - * Converts the file as an animatable character model, with joints and vertex - * membership. - */ -bool SoftToEggConverter:: -convert_char_model() { - softegg_cat.spam() << "character name " << _character_name << "\n"; - EggGroup *char_node = new EggGroup(eggGroupName); - get_egg_data()->add_child(char_node); - char_node->set_dart_type(EggGroup::DT_default); - - return convert_hierarchy(char_node); -} - -/** - * Given a tablename, it either creates a new eggSAnimData structure (if - * doesn't exist) or locates it. - */ -EggSAnimData *SoftToEggConverter:: -find_morph_table(char *name) { - EggSAnimData *anim = nullptr; - MorphTable::iterator mt; - for (mt = _morph_table.begin(); mt != _morph_table.end(); ++mt) { - anim = (*mt); - if (!strcmp(anim->get_name().c_str(), name)) - return anim; - } - - // create an entry - anim = new EggSAnimData(name); - anim->set_fps(_tree._fps); - _morph_table.push_back(anim); - morph_node->add_child(anim); - return anim; -} - -/** - * Converts the animation as a series of tables to apply to the character - * model, as retrieved earlier via AC_model. - */ -bool SoftToEggConverter:: -convert_char_chan() { - int start_frame = -1; - int end_frame = -1; - int frame_inc, frame; - double output_frame_rate = anim_rate; - - PN_stdfloat time; - - EggTable *root_table_node = new EggTable(); - get_egg_data()->add_child(root_table_node); - EggTable *bundle_node = new EggTable(eggGroupName); - bundle_node->set_table_type(EggTable::TT_bundle); - root_table_node->add_child(bundle_node); - EggTable *skeleton_node = new EggTable(""); - bundle_node->add_child(skeleton_node); - - morph_node = new EggTable("morph"); - - // Set the frame rate before we start asking for anim tables to be created. - SAA_sceneGetPlayCtrlStartFrame(&scene, &start_frame); - SAA_sceneGetPlayCtrlEndFrame(&scene, &end_frame); - SAA_sceneGetPlayCtrlFrameStep( &scene, &frame_inc ); - if (frame_inc != 1) // Hmmm...some files gave me frame_inc of 0, that can't be good - frame_inc = 1; - - softegg_cat.info() << "animation start frame: " << start_frame << " end frame: " << end_frame << endl; - softegg_cat.info() << "animation frame inc: " << frame_inc << endl; - - _tree._fps = output_frame_rate / frame_inc; - // _tree.clear_egg(get_egg_data(), NULL, root_node); - _tree.clear_egg(get_egg_data(), nullptr, skeleton_node); - - // Now we can get the animation data by walking through all of the frames, - // one at a time, and getting the joint angles at each frame. - - // This is just a temporary EggGroup to receive the transform for each joint - // each frame. - PT(EggGroup) tgroup = new EggGroup; - - int num_nodes = _tree.get_num_nodes(); - int i; - - // MTime frame(start_frame, MTime::uiUnit()); MTime frame_stop(end_frame, - // MTime::uiUnit()); start at first frame and go to last - if (make_pose) { - start_frame = pose_frame; - end_frame = pose_frame; - } - if (anim_start > 0) - start_frame = anim_start; - if (anim_end > 0) - end_frame = anim_end; - for ( frame = start_frame; frame <= end_frame; frame += frame_inc) { - SAA_frame2Seconds( &scene, frame, &time ); - // softegg_cat.spam() << "got time " << time << endl; - if (!make_pose) { - SAA_updatelistEvalScene( &scene, time ); - } - softegg_cat.spam() << "\n> animating frame " << frame << endl; - - // if (softegg_cat.is_debug()) { softegg_cat.debug(false) - softegg_cat.info() << "frame " << time << "\n"; - // } else { We have to write to cerr instead of softegg_cat to allow - // flushing without writing a newline. std::cerr << "." << std::flush; } - // MGlobal::viewFrame(frame); - - for (i = 0; i < num_nodes; i++) { - SoftNodeDesc *node_desc = _tree.get_node(i); - - if (node_desc->is_partial(search_prefix)) { - softegg_cat.debug() << endl; - continue; - } - if (make_morph) { - node_desc->make_morph_table(time); - } - if (node_desc->is_joint()) { - softegg_cat.spam() << "-----joint " << node_desc->get_name() << "\n"; - EggXfmSAnim *anim = _tree.get_egg_anim(node_desc); - // following function fills in the anim structure - node_desc->get_joint_transform(&scene, tgroup, anim, TRUE); - } - } - - // frame += frame_inc; - } - - if (has_morph) - bundle_node->add_child(morph_node); - - // Now optimize all of the tables we just filled up, for no real good - // reason, except that it makes the resulting egg file a little easier to - // read. - for (i = 0; i < num_nodes; i++) { - SoftNodeDesc *node_desc = _tree.get_node(i); - if (node_desc->is_partial(search_prefix)) - continue; - - if (node_desc->is_joint()) { - _tree.get_egg_anim(node_desc)->optimize(); - } - } - - softegg_cat.info(false) - << "\n"; - - return true; -} - -/** - * Generates egg structures for each node in the Soft hierarchy. - */ -bool SoftToEggConverter:: -convert_hierarchy(EggGroupNode *egg_root) { - int num_nodes = _tree.get_num_nodes(); - - _tree.clear_egg(get_egg_data(), egg_root, nullptr); - softegg_cat.spam() << "num_nodes = " << num_nodes << endl; - for (int i = 0; i < num_nodes; i++) { - if (!process_model_node(_tree.get_node(i))) { - return false; - } - softegg_cat.debug() << i << endl; - } - return true; -} - -/** - * Converts the indicated Soft node (given a MDagPath, similar in concept to - * Panda's NodePath) to the corresponding Egg structure. Returns true if - * successful, false if an error was encountered. - */ -bool SoftToEggConverter:: -process_model_node(SoftNodeDesc *node_desc) { - EggGroup *egg_group = nullptr; - const char *name = nullptr; - char *fullname = nullptr; - SAA_ModelType type; - - name = node_desc->get_name().c_str(); - softegg_cat.debug() << "element name <" << name << ">\n"; - - if (node_desc->is_junk()) { - softegg_cat.spam() << "no processing, it is junk\n"; - return true; - } - - // split - if (node_desc->is_partial(search_prefix)) { - softegg_cat.debug() << endl; - return true; - } - else - softegg_cat.debug() << endl << name << ":being processed" << endl; - - egg_group = _tree.get_egg_group(node_desc); - - // find out what type of node we're dealing with - SAA_modelGetType( &scene, node_desc->get_model(), &type ); - - softegg_cat.debug() << "encountered "; - switch(type){ - case SAA_MNILL: - softegg_cat.debug() << "null\n"; - break; - case SAA_MPTCH: - softegg_cat.debug() << "patch\n"; - break; - case SAA_MFACE: - softegg_cat.debug() << "face\n"; - // break; - case SAA_MSMSH: - softegg_cat.debug() << "mesh\n"; - node_desc->get_transform(&scene, egg_group, TRUE); - make_polyset(node_desc, egg_group, type); - break; - case SAA_MJNT: - softegg_cat.debug() << "joint"; - softegg_cat.debug() << " joint type " << node_desc->is_joint() << endl; - break; - case SAA_MSPLN: - softegg_cat.debug() << "spline\n"; - break; - case SAA_MMETA: - softegg_cat.debug() << "meta element\n"; - break; - case SAA_MBALL: - softegg_cat.debug() << "meta ball\n"; - break; - case SAA_MNCRV: - softegg_cat.debug() << "nurbs curve\n"; - break; - case SAA_MNSRF: - softegg_cat.debug() << "nurbs surf\n"; - node_desc->get_transform(&scene, egg_group, TRUE); - make_nurb_surface(node_desc, egg_group, type); - break; - default: - softegg_cat.debug() << "unknown type: " << type << "\n"; - } - - if (node_desc->is_joint()) - node_desc->get_transform(&scene, egg_group, FALSE); - - return true; -} - -/** - * Converts the indicated Soft polyset to a bunch of EggPolygons and parents - * them to the indicated egg group. - */ -void SoftToEggConverter:: -make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) { - int id = 0; - int i, idx; - int numShapes; - SAA_Boolean valid; - SAA_Boolean visible; - PN_stdfloat *uCoords = nullptr; - PN_stdfloat *vCoords = nullptr; - string name = node_desc->get_name(); - - SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible ); - softegg_cat.spam() << "model visibility: " << visible << endl; - - // Only create egg polygon data if: the node is visible, and its not a NULL - // or a Joint, and we're outputing polys (or if we are outputing NURBS and - // the model is a poly mesh or a face) - if ( visible && - (type != SAA_MNILL) && - (type != SAA_MJNT) && - ((make_poly || - (make_nurbs && ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) || - (!make_poly && !make_nurbs && make_duv && - ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) - ) - { - // Get the number of key shapes - SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes ); - softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl; - - // load all node data from soft for this node_desc - node_desc->load_poly_model(&scene, type); - - string vpool_name = name + ".verts"; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - vpool->set_highest_index(0); - - // add the vertices in the _tree._root node, so that they will be - // written out first in egg file. This solves a problem of soft- - // skinning trying to access vertex pool before it is defined. - - _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool); - - // We will need to transform all vertices from world coordinate space - // into the vertex space appropriate to this node. Usually, this is the - // same thing as world coordinate space, and this matrix will be - // identity; but if the node is under an instance (particularly, for - // instance, a billboard) then the vertex space will be different from - // world space. - LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv(); - - // Asad: change from soft2egg.c. Here I am trying to get one triangles - // vertices not all - for (idx=0; idxnumTri; ++idx) { - EggPolygon *egg_poly = new EggPolygon; - egg_group->add_child(egg_poly); - - softegg_cat.spam() << "processing polygon " << idx << endl; - - // Is this a double sided polygon? meaning check for back face flag - char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() ); - if ( modelNoteStr != nullptr ) { - if ( strstr( modelNoteStr, "bface" ) != nullptr ) - egg_poly->set_bface_flag(TRUE); - } - - // read each triangle's control vertices into array - SAA_SubElem cvertices[3]; - SAA_triangleGetCtrlVertices( &scene, node_desc->get_model(), node_desc->gtype, id, 1, node_desc->triangles+idx, cvertices ); - - // read control vertices in this triangle - SAA_DVector cvertPos[3]; - SAA_ctrlVertexGetPositions( &scene, node_desc->get_model(), 3, cvertices, cvertPos); - - // read indices of each vertices in this triangle - int indices[3]; - indices[0] = indices[1] = indices[2] = 0; - SAA_ctrlVertexGetIndices( &scene, node_desc->get_model(), 3, cvertices, indices ); - - // read each control vertex's normals into an array - SAA_DVector normals[3]; - SAA_ctrlVertexGetNormals( &scene, node_desc->get_model(), 3, cvertices, normals ); - for (i=0; i<3; ++i) - softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " << normals[i].y - << " " << normals[i].z << " " << normals[i].w << "\n"; - - // allocate arrays for u & v coords - if (node_desc->textures) { - if (node_desc->numTexLoc && node_desc->numTexTri[idx]) { - // allocate arrays for u & v coords I think there are one texture - // per triangle hence we need only 3 corrdinates - uCoords = new PN_stdfloat[3]; - vCoords = new PN_stdfloat[3]; - - // read the u & v coords into the arrays - if ( uCoords != nullptr && vCoords != nullptr) { - for ( i = 0; i < 3; i++ ) - uCoords[i] = vCoords[i] = 0.0f; - - // TODO: investigate the coord_cnt parameter... - SAA_ctrlVertexGetUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices, - 3, uCoords, vCoords ); - } - else - softegg_cat.info() << "Not enough Memory for texture coords...\n"; - -#if 1 - for ( i=0; i<3; i++ ) - softegg_cat.spam() << "texcoords[" << i << "] = ( " << uCoords[i] << " , " << vCoords[i] <<" )\n"; -#endif - } - else if (node_desc->numTexGlb) { - // allocate arrays for u & v coords - uCoords = new PN_stdfloat[node_desc->numTexGlb*3]; - vCoords = new PN_stdfloat[node_desc->numTexGlb*3]; - - for ( i = 0; i < node_desc->numTexGlb*3; i++ ) { - uCoords[i] = vCoords[i] = 0.0f; - } - - // read the u & v coords into the arrays - if ( uCoords != nullptr && vCoords != nullptr) { - SAA_triCtrlVertexGetGlobalUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices, - node_desc->numTexGlb, node_desc->textures, uCoords, vCoords ); - } - else - softegg_cat.info() << "Not enough Memory for texture coords...\n"; - } - } - - for ( i=0; i < 3; i++ ) { - EggVertex vert; - - // There are some conversions needed from local matrix to global - // coords - SAA_DVector local = cvertPos[i]; - SAA_DVector global = {0}; - - _VCT_X_MAT( global, local, node_desc->matrix ); - - softegg_cat.spam() << "indices[" << i << "] = " << indices[i] << "\n"; - softegg_cat.spam() << "cvert[" << i << "] = " << cvertPos[i].x << " " << cvertPos[i].y - << " " << cvertPos[i].z << " " << cvertPos[i].w << "\n"; - softegg_cat.spam() << " global cvert[" << i << "] = " << global.x << " " << global.y - << " " << global.z << " " << global.w << "\n"; - - // LPoint3d p3d(cvertPos[i].x, cvertPos[i].y, cvertPos[i].z); - LPoint3d p3d(global.x, global.y, global.z); - p3d = p3d * vertex_frame_inv; - vert.set_pos(p3d); - - local = normals[i]; - _VCT_X_MAT( global, local, node_desc->matrix ); - - softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " << normals[i].y - << " " << normals[i].z << " " << normals[i].w << "\n"; - softegg_cat.spam() << " global normals[" << i <<"] = " << global.x << " " << global.y - << " " << global.z << " " << global.w << "\n"; - - LVector3d n3d(global.x, global.y, global.z); - n3d = n3d * vertex_frame_inv; - vert.set_normal(n3d); - - // if texture present set the texture coordinates - if (node_desc->textures) { - PN_stdfloat u, v; - - if (uCoords && vCoords) { - u = uCoords[i]; - v = 1.0f - vCoords[i]; - softegg_cat.spam() << "texcoords[" << i << "] = " << u << " " - << v << endl; - - vert.set_uv(LTexCoordd(u, v)); - // vert.set_uv(LTexCoordd(uCoords[i], vCoords[i])); - } - } - vert.set_external_index(indices[i]); - egg_poly->add_vertex(vpool->create_unique_vertex(vert)); - - // check to see if material is present - PN_stdfloat r,g,b,a; - SAA_elementIsValid( &scene, &node_desc->materials[idx], &valid ); - // material present - get the color - if ( valid ) { - SAA_materialGetDiffuse( &scene, &node_desc->materials[idx], &r, &g, &b ); - SAA_materialGetTransparency( &scene, &node_desc->materials[idx], &a ); - egg_poly->set_color(LColor(r, g, b, 1.0f - a)); - softegg_cat.spam() << "color r = " << r << " g = " << g << " b = " << b << " a = " << 1.0f - a << "\n"; - } - else { // no material - default to white - egg_poly->set_color(LColor(1.0, 1.0, 1.0, 1.0)); - softegg_cat.spam() << "default color\n"; - } - - /* - // keep a one to one copy in this node's vpool - EggVertex *t_vert = new EggVertex(vert); - if (!t_vert) { - softegg_cat.spam() << "out of memeory " << endl; - nassertv(t_vert != NULL); - } - node_desc->get_vpool()->add_vertex(t_vert, indices[i]); - */ - - softegg_cat.spam() << "\n"; - } - - // Now apply the shader. - if (node_desc->textures != nullptr) { - if (node_desc->numTexLoc && node_desc->numTexTri[idx]) { - if (!strstr(node_desc->texNameArray[idx], "noIcon")) - set_shader_attributes(node_desc, *egg_poly, idx); - else - softegg_cat.spam() << "texname :" << node_desc->texNameArray[idx] << endl; - } - else { - if (!strstr(node_desc->texNameArray[0], "noIcon")) - set_shader_attributes(node_desc, *egg_poly, 0); - else - softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl; - } - } - } - // if model has key shapes, generate vertex offsets - if ( numShapes > 0 && make_morph ) - node_desc->make_vertex_offsets( numShapes); - } -} - -/** - * Converts the indicated Soft nurbs set to a bunch of EggPolygons and parents - * them to the indicated egg group. - */ -void SoftToEggConverter:: -make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) { - int id = 0; - int i, j, k; - int numShapes; - SAA_Boolean valid; - SAA_Boolean visible; - PN_stdfloat *uCoords = nullptr; - PN_stdfloat *vCoords = nullptr; - string name = node_desc->get_name(); - - SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible ); - softegg_cat.spam() << "model visibility: " << visible << endl; - softegg_cat.spam() << "nurbs!!!surface!!!" << endl; - - // check to see if its a nurbs surface - if ( (type == SAA_MNSRF) && ( visible ) && (( make_nurbs ) - || ( !make_nurbs && !make_poly && make_duv )) ) - { - // Get the number of key shapes - SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes ); - softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl; - - // load all node data from soft for this node_desc - node_desc->load_nurbs_model(&scene, type); - - string vpool_name = name + ".verts"; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - vpool->set_highest_index(0); - - // add the vertices in the _tree._egg_root node, so that they will be - // written out first in egg file. This solves a problem of soft- - // skinning trying to access vertex pool before it is defined. - - // _tree.get_egg_root()->add_child(vpool); - _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool); - - // egg_group->add_child(vpool); - - /* - // create a copy of vpool in node_desc which will be used later for - // soft_skinning - node_desc->create_vpool(vpool_name); - */ - - int uRows, vRows; - int uKnots, vKnots; - int uExtra, vExtra; - int uDegree, vDegree; - int uCurves, vCurves; - - vector Knots; - - EggNurbsSurface *eggNurbs = new EggNurbsSurface( name ); - - // create nurbs representation of surface - SAA_nurbsSurfaceGetDegree( &scene, node_desc->get_model(), &uDegree, &vDegree ); - softegg_cat.spam() << "nurbs degree: " << uDegree << " u, " << vDegree << " v\n"; - - SAA_nurbsSurfaceGetNbKnots( &scene, node_desc->get_model(), &uKnots, &vKnots ); - softegg_cat.spam() << "nurbs knots: " << uKnots << " u, " << vKnots << " v\n"; - - SAA_Boolean uClosed = FALSE; - SAA_Boolean vClosed = FALSE; - - SAA_nurbsSurfaceGetClosed( &scene, node_desc->get_model(), &uClosed, &vClosed); - - uExtra = vExtra = 2; - if ( uClosed ) { - softegg_cat.spam() << "nurbs is closed in u...\n"; - uExtra += 4; - } - if ( vClosed ) { - softegg_cat.spam() << "nurbs is closed in v...\n"; - vExtra += 4; - } - eggNurbs->setup(uDegree+1, vDegree+1, - uKnots + uExtra, vKnots + vExtra); - - softegg_cat.spam() << "from eggNurbs: num u knots " << eggNurbs->get_num_u_knots() << endl; - softegg_cat.spam() << "from eggNurbs: num v knots " << eggNurbs->get_num_v_knots() << endl; - softegg_cat.spam() << "from eggNurbs: num u cvs " << eggNurbs->get_num_u_cvs() << endl; - softegg_cat.spam() << "from eggNurbs: num v cvs " << eggNurbs->get_num_v_cvs() << endl; - - SAA_nurbsSurfaceGetNbVertices( &scene, node_desc->get_model(), &uRows, &vRows ); - softegg_cat.spam() << "nurbs vertices: " << uRows << " u, " << vRows << " v\n"; - - SAA_nurbsSurfaceGetNbCurves( &scene, node_desc->get_model(), &uCurves, &vCurves ); - softegg_cat.spam() << "nurbs curves: " << uCurves << " u, " << vCurves << " v\n"; - - if ( shift_textures ) { - if ( uClosed ) - // shift starting point on NURBS surface for correct textures - SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), -2, 0 ); - - if ( vClosed ) - // shift starting point on NURBS surface for correct textures - SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), 0, -2 ); - } - - SAA_nurbsSurfaceSetStep( &scene, node_desc->get_model(), nurbs_step, nurbs_step ); - - // Is this a double sided polygon? meaning check for back face flag - char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() ); - if ( modelNoteStr != nullptr ) { - if ( strstr( modelNoteStr, "bface" ) != nullptr ) { - eggNurbs->set_bface_flag(TRUE); - softegg_cat.spam() << "Set backface flag\n"; - } - } - - double *uKnotArray = new double[uKnots]; - double *vKnotArray = new double[vKnots]; - result = SAA_nurbsSurfaceGetKnots( &scene, node_desc->get_model(), node_desc->gtype, 0, - uKnots, vKnots, uKnotArray, vKnotArray ); - - if (result != SI_SUCCESS) { - softegg_cat.spam() << "Couldn't get knots\n"; - exit(1); - } - - // Lets prepare the softimage knots and then assign to eggKnots - add_knots( Knots, uKnotArray, uKnots, uClosed, uDegree ); - softegg_cat.spam() << "u knots: "; - for (i = 0; i < (int)Knots.size(); i++) { - softegg_cat.spam() << Knots[i] << " "; - eggNurbs->set_u_knot(i, Knots[i]); - } - softegg_cat.spam() << endl; - - Knots.resize(0); - add_knots( Knots, vKnotArray, vKnots, vClosed, vDegree ); - softegg_cat.spam() << "v knots: "; - for (i = 0; i < (int)Knots.size(); i++) { - softegg_cat.spam() << Knots[i] << " "; - eggNurbs->set_v_knot(i, Knots[i]); - } - softegg_cat.spam() << endl; - - // lets get the number of vertices from softimage - int numVert; - SAA_modelGetNbVertices( &scene, node_desc->get_model(), &numVert ); - - softegg_cat.spam() << numVert << " CV's\n"; - - // get the CV's - SAA_DVector *vertices = nullptr; - vertices = new SAA_DVector[numVert]; - - SAA_modelGetVertices( &scene, node_desc->get_model(), node_desc->gtype, 0, numVert, vertices ); - - LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv(); - - // create the buffer for EggVertices - EggVertex *verts = new EggVertex[numVert]; - - softegg_cat.spam() << endl << eggNurbs->get_num_cvs() << endl << endl; - - // for ( i = 0; iget_num_cvs(); i++ ) { - for ( k = 0; kget_u_index(i); - int vi = eggNurbs->get_v_index(i); - - int k = vRows * ui + vi; - - softegg_cat.spam() << i << ": ui " << ui << ", vi " << vi << ", k " << k << endl; - - softegg_cat.spam() << "original cv[" << k << "] = " - << vertices[k].x << " " << vertices[k].y << " " - << vertices[k].z << " " << vertices[k].w << endl; - */ - - // convert to global coords - _VCT_X_MAT( global, vertices[k], node_desc->matrix ); - - // preserve original weight - global.w = vertices[k].w; - - // normalize coords to weight - global.x *= global.w; - global.y *= global.w; - global.z *= global.w; - - /* - softegg_cat.spam() << "global cv[" << k << "] = " - << global.x << " " << global.y << " " - << global.x << " " << global.w << endl; - */ - - LPoint4d p4d(global.x, global.y, global.z, global.w); - p4d = p4d * vertex_frame_inv; - verts[k].set_pos(p4d); - - // check to see if material is present - if (node_desc->numNurbMats) { - PN_stdfloat r,g,b,a; - SAA_elementIsValid( &scene, &node_desc->materials[0], &valid ); - // material present - get the color - if ( valid ) { - SAA_materialGetDiffuse( &scene, &node_desc->materials[0], &r, &g, &b ); - SAA_materialGetTransparency( &scene, &node_desc->materials[0], &a ); - verts[k].set_color(LColor(r, g, b, 1.0f - a)); - // softegg_cat.spam() << "color r = " << r << " g = " << g << " b - // = " << b << " a = " << a << "\n"; - } - else { // no material - default to white - verts[k].set_color(LColor(1.0, 1.0, 1.0, 1.0)); - softegg_cat.spam() << "default color\n"; - } - } - vpool->add_vertex(verts+k, k); - eggNurbs->add_vertex(vpool->get_vertex(k)); - - if ( uClosed ) { - // add first uDegree verts to end of row - if ( (k % uRows) == ( uRows - 1) ) { - for ( i = 0; i < uDegree; i++ ) { - // add vref's to NURBS info - eggNurbs->add_vertex( vpool->get_vertex(i+((k/uRows)*uRows)) ); - } - } - } - } - - // check to see if the NURB is closed in v - if ( vClosed && !uClosed ) { - // add first vDegree rows of verts to end of list - for ( int i = 0; i < vDegree*uRows; i++ ) - eggNurbs->add_vertex( vpool->get_vertex(i) ); - } - // check to see if the NURB is closed in u and v - else if ( vClosed && uClosed ) { - // add the first (degree) v verts and a few extra - for good measure - for ( i = 0; i < vDegree; i++ ) { - // add first vDegree rows of verts to end of list - for ( j = 0; j < uRows; j++ ) - eggNurbs->add_vertex( vpool->get_vertex(j+(i*uRows)) ); - - // if u is closed to we have added uDegree verts onto the ends of - // the rows - add them here too - for ( k = 0; k < uDegree; k++ ) - eggNurbs->add_vertex( vpool->get_vertex(k+(i*uRows)+((k/uRows)*uRows)) ); - } - } - - // We add the NURBS to the group down here, after all of the vpools for - // the trim curves have been added. - egg_group->add_child(eggNurbs); - - // Now apply the shader. - if (node_desc->textures != nullptr) { - if (!strstr(node_desc->texNameArray[0], "noIcon")) - set_shader_attributes(node_desc, *eggNurbs, 0); - else - softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl; - } - - // if model has key shapes, generate vertex offsets - if ( numShapes > 0 && make_morph ) - node_desc->make_vertex_offsets( numShapes); - } -} - -/** - * Given a parametric surface, and its knots, create the appropriate egg - * structure by filling in Soft's implicit knots and assigning the rest to - * eggKnots. - */ -void SoftToEggConverter:: -add_knots( vector &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree ) { - - int k = 0; - double lastKnot = knots[0]; - double *newKnots; - - // add initial implicit knot(s) - if ( closed ) { - int i = 0; - newKnots = new double[degree]; - - // need to add (degree) number of knots - for ( k = numKnots - 1; k >= numKnots - degree; k-- ) { - // we have to know these in order to calculate next knot value so hold - // them in temp array - newKnots[i] = lastKnot - (knots[k] - knots[k-1]); - lastKnot = newKnots[i]; - i++; - } - for ( k = degree - 1; k >= 0; k-- ) { - eggKnots.push_back( newKnots[k] ); - softegg_cat.spam() << "knots[" << k << "] = " << newKnots[k] << endl; - } - } - else { - eggKnots.push_back( knots[k] ); - softegg_cat.spam() << "knots[" << k << "] = " << knots[k] << endl; - } - - // add the regular complement of knots - for (k = 0; k < numKnots; k++) { - eggKnots.push_back( knots[k] ); - softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k] << endl; - } - - lastKnot = knots[numKnots-1]; - - // add trailing implicit knots - if ( closed ) { - // need to add (degree) number of knots - for ( k = 1; k <= degree; k++ ) { - eggKnots.push_back( lastKnot + (knots[k] - knots[k-1]) ); - softegg_cat.spam() << "knots[" << k << "] = " << lastKnot + (knots[k] - knots[k-1]) << endl; - lastKnot = lastKnot + (knots[k] - knots[k-1]); - } - } - else { - eggKnots.push_back( knots[k-1] ); - softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k-1] << endl; - } -} - -/** - * Given an egg vertex pool, map each vertex therein to a vertex within an - * array of SAA model vertices of size numVert. Mapping is done by closest - * proximity. - */ -int *SoftToEggConverter:: -FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) { - int i,j; - int *vertMap = nullptr; - int vpoolSize = (int)vpool->size(); - PN_stdfloat closestDist; - PN_stdfloat thisDist; - int closest; - - vertMap = new int[vpoolSize]; - i = 0; - EggVertexPool::iterator vi; - for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++i) { - EggVertex *vert = (*vi); - softegg_cat.spam() << "vert external index = " << vert->get_external_index() << endl; - // softegg_cat.spam() << "found vert " << vert << endl; softegg_cat.spam() - // << "vert [" << i << "] " << vpool->get_vertex(i+1); - LPoint3d p3d = vert->get_pos3(); - - // find closest model vertex - for ( j = 0; j < numVert; j++ ) { - // calculate distance - thisDist = sqrtf( - powf( p3d[0] - vertices[j].x , 2 ) + - powf( p3d[1] - vertices[j].y , 2 ) + - powf( p3d[2] - vertices[j].z , 2 ) ); - - // remember this if its the closest so far - if ( !j || ( thisDist < closestDist ) ) { - closest = j; - closestDist = thisDist; - } - } - - vertMap[i] = closest; - softegg_cat.spam() << "mapping v " << i << " of " << vpoolSize-1 << ":( " - << p3d[0] << " " - << p3d[1] << " " - << p3d[2] << ")\n"; - - softegg_cat.spam() << " to cv " << closest << " of " << numVert-1 << ":( " - << vertices[closest].x << " " - << vertices[closest].y << " " - << vertices[closest].z << " )\tdelta = " << closestDist << endl; - } - return vertMap; -} - -/** - * make soft skin assignments to the mesh finally call cleanup_soft_skin to - * clean it up - */ -bool SoftToEggConverter:: -make_soft_skin() { - int num_nodes = _tree.get_num_nodes(); - SoftNodeDesc *node_desc; - SAA_Boolean isSkeleton; - - softegg_cat.spam() << endl << "----------------------------------------------------------------" << endl; - - for (int i = 0; i < num_nodes; i++) { - node_desc = _tree.get_node(i); - SAA_modelIsSkeleton( &scene, node_desc->get_model(), &isSkeleton ); - - softegg_cat.spam() << "??checking node " << node_desc->get_name() << " isSkel " << isSkeleton << " isJoint " << node_desc->is_joint() << endl; - if (isSkeleton && node_desc->is_joint()) { - - if (node_desc->is_partial(search_prefix)) - continue; - - // Now that we've added all the polygons (and created all the vertices), - // go back through the vertex pool and set up the appropriate joint - // membership for each of the vertices. - - // check for envelops - int numEnv; - SAA_ModelType type; - SAA_Elem *envelopes; - SAA_Elem *model = node_desc->get_model(); - EggGroup *joint = nullptr; - EggVertexPool *vpool; - - SAA_skeletonGetNbEnvelopes( &scene, model, &numEnv ); - if ( numEnv == 0 ) { - softegg_cat.spam() << "no soft skinning for joint " << node_desc->get_name() << endl; - continue; - } - - // it's got envelopes - must be soft skinned - softegg_cat.spam() << endl << "found skeleton part( " << node_desc->get_name() << ")!\n"; - softegg_cat.spam() << "numEnv = " << numEnv << endl; - // allocate envelope array - envelopes = new SAA_Elem[numEnv]; - if ( envelopes == nullptr ) { - softegg_cat.info() << "Out Of Memory" << endl; - exit(1); - } - int thisEnv; - SAA_EnvType envType; - bool hasEnvVertices = 0; - - SAA_skeletonGetEnvelopes( &scene, model, numEnv, envelopes ); - for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) { - softegg_cat.spam() << "env[" << thisEnv << "]: "; - SAA_envelopeGetType( &scene, &envelopes[thisEnv], &envType ); - - if ( envType == SAA_ENVTYPE_NONE ) { - softegg_cat.spam() << "envType = none\n"; - } - else if ( envType == SAA_ENVTYPE_FLXLCL ) { - softegg_cat.spam() << "envType = flexible, local\n"; - hasEnvVertices = 1; - } - else if ( envType == SAA_ENVTYPE_FLXGLB ) { - softegg_cat.spam() << "envType = flexible, global\n"; - hasEnvVertices = 1; - } - else if ( envType == SAA_ENVTYPE_RGDGLB ) { - softegg_cat.spam() << "envType = rigid, global\n"; - hasEnvVertices = 1; - } - else { - softegg_cat.spam() << "envType = unknown\n"; - } - - } - if ( !hasEnvVertices ) - continue; - - SAA_SubElem *envVertices = nullptr; - int *numEnvVertices; - int i,j,k; - - numEnvVertices = new int[numEnv]; - - if ( numEnvVertices != nullptr ) { - SAA_envelopeGetNbCtrlVertices( &scene, model, numEnv, envelopes, numEnvVertices ); - int totalEnvVertices = 0; - for( i = 0; i < numEnv; i++ ) { - totalEnvVertices += numEnvVertices[i]; - softegg_cat.spam() << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl; - } - softegg_cat.spam() << "total env verts = " << totalEnvVertices << endl; - if ( totalEnvVertices == 0 ) - continue; - - envVertices = new SAA_SubElem[totalEnvVertices]; - if ( envVertices != nullptr ) { - result = SAA_envelopeGetCtrlVertices( &scene, model, - numEnv, envelopes, numEnvVertices, envVertices); - if (result != SI_SUCCESS) { - softegg_cat.spam() << "error: GetCtrlVertices\n"; - exit(1); - } - // loop through for each envelope - for ( i = 0; i < numEnv; i++ ) { - PN_stdfloat *weights = nullptr; - int vertArrayOffset = 0; - softegg_cat.spam() << "envelope[" << i << "]: "; - weights = new PN_stdfloat[numEnvVertices[i]]; - if ( weights ) { - char *envName; - int *vpoolMap = nullptr; - for ( j = 0; j < i; j++ ) - vertArrayOffset += numEnvVertices[j]; - softegg_cat.spam() << "envVertArray offset = " << vertArrayOffset; - - /* - if (vertArrayOffset == totalEnvVertices) { - softegg_cat.spam() << endl; vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert ); - - break; - } - */ - - // get the weights of the envelope vertices - result = SAA_ctrlVertexGetEnvelopeWeights( &scene, model, &envelopes[i], - numEnvVertices[i], - &envVertices[vertArrayOffset], weights ); - - // Get the name of the envelope model - if ( use_prefix ) { - // Get the FULL name of the envelope - envName = _tree.GetFullName( &scene, &envelopes[i] ); - } - else { - // Get the name of the envelope - envName = _tree.GetName( &scene, &envelopes[i] ); - } - - softegg_cat.spam() << " envelop name is [" << envName << "]" << endl; - - if (result != SI_SUCCESS) { - softegg_cat.spam() << "warning: this envelop doesn't have any weights\n"; - continue; - } - - result = SAA_modelGetType( &scene, &envelopes[i], &type ); - if (result != SI_SUCCESS) { - softegg_cat.debug() << "choked on get type\n"; - exit(1); - } - - softegg_cat.spam() << "envelope model type "; - if ( type == SAA_MSMSH ) - softegg_cat.spam() << "MESH\n"; - else if ( type == SAA_MNSRF ) - softegg_cat.spam() << "NURBS\n"; - else - softegg_cat.spam() << "OTHER\n"; - - int *envVtxIndices = nullptr; - envVtxIndices = new int[numEnvVertices[i]]; - - // Get the envelope vertex indices - result = SAA_ctrlVertexGetIndices( &scene, &envelopes[i], numEnvVertices[i], - &envVertices[vertArrayOffset], envVtxIndices ); - - if (result != SI_SUCCESS) { - softegg_cat.debug() << "error: choked on get indices\n"; - exit(1); - } - - // find out how many vertices the model has - int modelNumVert; - - SAA_modelGetNbVertices( &scene, &envelopes[i], &modelNumVert ); - - SAA_DVector *modelVertices = nullptr; - modelVertices = new SAA_DVector[modelNumVert]; - - // get the model vertices - SAA_modelGetVertices( &scene, &envelopes[i], - SAA_GEOM_ORIGINAL, 0, modelNumVert, - modelVertices ); - - // create array of global model coords - SAA_DVector *globalModelVertices = nullptr; - globalModelVertices = new SAA_DVector[modelNumVert]; - PN_stdfloat matrix[4][4]; - - // tranform local model vert coords to global - - // first get the global matrix - SAA_modelGetMatrix( &scene, &envelopes[i], SAA_COORDSYS_GLOBAL, matrix ); - - // populate array of global model verts - for ( j = 0; j < modelNumVert; j++ ) { - _VCT_X_MAT( globalModelVertices[j], - modelVertices[j], matrix ); - } - - // Get the vpool - string s_name = envName; - SoftNodeDesc *mesh_node = find_node(s_name); - if (!mesh_node) { - softegg_cat.debug() << "error: node " << s_name << " not found in tree\n"; - exit(1); - } - string vpool_name = s_name + ".verts"; - EggNode *t = _tree.get_egg_root()->find_child(vpool_name); - if (t) - DCAST_INTO_R(vpool, t, nullptr); - - // find the mapping of the vertices that match this envelop - if (vpool) { - softegg_cat.spam() << "found vpool of size " << vpool->size() << endl; - if ( !make_nurbs || (type == SAA_MSMSH) ) { - vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert ); - } - } - else { - softegg_cat.debug() << "warning: vpool " << vpool_name << " not found\n"; - continue; // could be because of not visible - } - - joint = node_desc->get_egg_group(); - // for every envelope vertex - for (j = 0; j < numEnvVertices[i]; j++) { - double scaledWeight = weights[j]/ 100.0f; - - // make sure its in legal range - if (( envVtxIndices[j] < modelNumVert ) - && ( envVtxIndices[j] >= 0 )) { - if ( (type == SAA_MNSRF) && make_nurbs ) { - // assign all referenced control vertices - EggVertex *vert = vpool->get_vertex(envVtxIndices[j]); - if (!vert) { - softegg_cat.debug() << "possible error: index " << envVtxIndices[j] << ": vert is " << vert << endl; - continue; - } - joint->ref_vertex( vert, scaledWeight ); - softegg_cat.spam() << j << ": adding vref to cv " << envVtxIndices[j] - << " with weight " << scaledWeight << endl; - - /* - envPool->Vertex(envVtxIndices[j])->AddJoint( joint, scaledWeight ); - // set flag to show this vertex has been assigned - envPool->Vertex(envVtxIndices[j])->multipleJoints = 1; - */ - } - else { - // assign all the tri verts associated with this control - // vertex to joint - softegg_cat.spam() << j << "--trying to find " << envVtxIndices[j] << endl; - for ( k = 0; k < (int)vpool->size(); k++ ) { - if ( vpoolMap[k] == envVtxIndices[j] ) { - EggVertex *vert = vpool->get_vertex(k+1); - // EggVertex *vert = - // mesh_node->get_vpool()->get_vertex(vpoolMap[k]+1); - if (!vert) { - softegg_cat.debug() << "possible error: index " << k+1 << ": vert is " << vert << endl; - break; - } - - joint->ref_vertex(vert, scaledWeight); - softegg_cat.spam() << j << ": adding vref from cv " << envVtxIndices[j] - << " to vert " << k+1 << " with weight " << scaledWeight - << "(vpool)\n"; - /* - envPool->Vertex(k)->AddJoint( joint, scaledWeight ); - // set flag to show this vertex has been assigned - envPool->Vertex(k)->multipleJoints = 1; - */ - } - } - } - } - } - } - } - } - } - } - } - return true; -} -/** - * Given a model, make sure all its vertices have been soft assigned. If not - * hard assign to the last joint we saw. - */ -bool SoftToEggConverter:: -cleanup_soft_skin() -{ - int num_nodes = _tree.get_num_nodes(); - SoftNodeDesc *node_desc; - - softegg_cat.spam() << endl << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; - - for (int i = 0; i < num_nodes; i++) { - node_desc = _tree.get_node(i); - if (node_desc->is_partial(search_prefix)) - continue; - - SAA_Elem *model = node_desc->get_model(); - EggGroup *joint = nullptr; - EggVertexPool *vpool = nullptr; - SAA_ModelType type; - - // find out what type of node we're dealing with - - SAA_modelGetType( &scene, model, &type ); - - softegg_cat.debug() << "Cleaning up model------- " << node_desc->get_name() << endl; - - // this step is weird - I think I want it here but it seems to break some - // models. Files like props-props_wh_cookietime.3-0 in - // fulrndpubvrmlchipchips_adventurecharzone1roomswarehouse_final need to - // do the "if (skel)" bit. - - // find the vpool for this model - string vpool_name = node_desc->get_name() + ".verts"; - EggNode *t = _tree.get_egg_root()->find_child(vpool_name); - if (t) - DCAST_INTO_R(vpool, t, nullptr); - - if (!vpool) { - // softegg_cat.spam() << "couldn't find vpool " << vpool_name << endl; - continue; - } - - int numVerts = (int)vpool->size(); - softegg_cat.spam() << "found vpool " << vpool_name << " w/ " << numVerts << " verts\n"; - - // if this node is a joint, then these vertices belong to this joint - if (node_desc->is_joint()) - joint = node_desc->get_egg_group(); - else { - // find the closest _parentJoint - SoftNodeDesc *parentJ = node_desc; - while( parentJ && !parentJ->_parentJoint) { - if ( parentJ->_parent) { - SAA_Boolean isSkeleton; - // softegg_cat.spam() << " checking parent " << - // parentJ->_parent->get_name() << endl; - if (parentJ->_parent->has_model()) - SAA_modelIsSkeleton( &scene, parentJ->_parent->get_model(), &isSkeleton ); - - if (isSkeleton) { - joint = parentJ->_parent->get_egg_group(); - softegg_cat.spam() << "parent to " << parentJ->_parent->get_name() << endl; - break; - } - - parentJ = parentJ->_parent; - } - else - break; - } - if (!joint && (!parentJ || !parentJ->_parentJoint)) { - softegg_cat.spam() << node_desc->get_name() << " has no _parentJoint?!" << endl; - continue; - } - - if (!joint) { - softegg_cat.spam() << "parent joint to " << parentJ->_parentJoint->get_name() << endl; - joint = parentJ->_parentJoint->get_egg_group(); - } - } - EggVertexPool::iterator vi; - double membership = 1.0f; - for ( vi = vpool->begin(); vi != vpool->end(); ++vi) { - EggVertex *vert = (*vi); - - // if this vertex has not been soft assigned, then hard assign it to the - // parentJoint - if ( vert->gref_size() == 0 ) { - - softegg_cat.spam() << "vert " << vert->get_external_index() << " not assigned!\n"; - - // hard skin this vertex - joint->ref_vertex( vert, 1.0f ); - } - } - } - return true; -} - -/** - * Applies the known shader attributes to the indicated egg primitive. - */ -void SoftToEggConverter:: -set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, int idx) { - char *texName = node_desc->texNameArray[idx]; - EggTexture tex(texName, ""); - - Filename filename = Filename::from_os_specific(texName); - Filename fullpath = _path_replace->match_path(filename, get_model_path()); - tex.set_filename(_path_replace->store_path(fullpath)); - tex.set_fullpath(fullpath); - // tex.set_format(EggTexture::F_rgb); - apply_texture_properties(tex, node_desc->uRepeat[idx], node_desc->vRepeat[idx]); - - EggTexture *new_tex = _textures.create_unique_texture(tex, ~EggTexture::E_tref_name); - primitive.set_texture(new_tex); -} - -/** - * Applies all the appropriate texture properties to the EggTexture object, - * including wrap modes and texture matrix. - */ -void SoftToEggConverter:: -apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat) { - // Let's mipmap all textures by default. - tex.set_minfilter(EggTexture::FT_linear_mipmap_linear); - tex.set_magfilter(EggTexture::FT_linear); - - EggTexture::WrapMode wrap_u = uRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp; - EggTexture::WrapMode wrap_v = vRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp; - - tex.set_wrap_u(wrap_u); - tex.set_wrap_v(wrap_v); - /* - LMatrix3d mat = color_def.compute_texture_matrix(); - if (!mat.almost_equal(LMatrix3d::ident_mat())) { - tex.set_transform(mat); - } - */ -} -#if 0 -/** - * Compares the texture properties already on the texture (presumably set by a - * previous call to apply_texture_properties()) and returns false if they - * differ from that specified by the indicated color_def object, or true if - * they match. - */ -bool SoftToEggConverter:: -compare_texture_properties(EggTexture &tex, - const SoftShaderColorDef &color_def) { - bool okflag = true; - - EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp; - EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp; - - if (wrap_u != tex.determine_wrap_u()) { - // Choose the more general of the two. - if (wrap_u == EggTexture::WM_repeat) { - tex.set_wrap_u(wrap_u); - } - okflag = false; - } - if (wrap_v != tex.determine_wrap_v()) { - if (wrap_v == EggTexture::WM_repeat) { - tex.set_wrap_v(wrap_v); - } - okflag = false; - } - - LMatrix3d mat = color_def.compute_texture_matrix(); - if (!mat.almost_equal(tex.get_transform())) { - okflag = false; - } - - return okflag; -} -#endif -/** - * Recursively walks the egg hierarchy, reparenting "decal" type nodes below - * their corresponding "decalbase" type nodes, and setting the flags. - * - * Returns true on success, false if some nodes were incorrect. - */ -bool SoftToEggConverter:: -reparent_decals(EggGroupNode *egg_parent) { - bool okflag = true; - - // First, walk through all children of this node, looking for the one decal - // base, if any. - EggGroup *decal_base = nullptr; - pvector decal_children; - - EggGroupNode::iterator ci; - for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) { - EggNode *child = (*ci); - if (child->is_of_type(EggGroup::get_class_type())) { - EggGroup *child_group = DCAST(EggGroup, child); - if (child_group->has_object_type("decalbase")) { - if (decal_base != nullptr) { - softegg_cat.error() - << "Two children of " << egg_parent->get_name() - << " both have decalbase set: " << decal_base->get_name() - << " and " << child_group->get_name() << "\n"; - okflag = false; - } - child_group->remove_object_type("decalbase"); - decal_base = child_group; - - } else if (child_group->has_object_type("decal")) { - child_group->remove_object_type("decal"); - decal_children.push_back(child_group); - } - } - } - - if (decal_base == nullptr) { - if (!decal_children.empty()) { - softegg_cat.warning() - << decal_children.front()->get_name() - << " has decal, but no sibling node has decalbase.\n"; - } - - } else { - if (decal_children.empty()) { - softegg_cat.warning() - << decal_base->get_name() - << " has decalbase, but no sibling nodes have decal.\n"; - - } else { - // All the decal children get moved to be a child of decal base. This - // usually will not affect the vertex positions, but it could if the - // decal base has a transform and the decal child is an instance node. - // So don't do that. - pvector::iterator di; - for (di = decal_children.begin(); di != decal_children.end(); ++di) { - EggGroup *child_group = (*di); - decal_base->add_child(child_group); - } - - // Also set the decal state on the base. - decal_base->set_decal_flag(true); - } - } - - // Now recurse on each of the child nodes. - for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) { - EggNode *child = (*ci); - if (child->is_of_type(EggGroupNode::get_class_type())) { - EggGroupNode *child_group = DCAST(EggGroupNode, child); - if (!reparent_decals(child_group)) { - okflag = false; - } - } - } - - return okflag; -} - -/** - * Returns the TransformType value corresponding to the indicated string, or - * TT_invalid. - */ -SoftToEggConverter::TransformType SoftToEggConverter:: -string_transform_type(const string &arg) { - if (cmp_nocase(arg, "all") == 0) { - return TT_all; - } else if (cmp_nocase(arg, "model") == 0) { - return TT_model; - } else if (cmp_nocase(arg, "dcs") == 0) { - return TT_dcs; - } else if (cmp_nocase(arg, "none") == 0) { - return TT_none; - } else { - return TT_invalid; - } -} - -/** - * Invokes the softToEggConverter class - */ -extern "C" int init_soft2egg(int argc, char **argv) { - stec._commandName = argv[0]; - stec.rsrc_path = "c:\\Softimage\\SOFT3D_3.9.2\\3D\\rsrc"; - - if (stec.DoGetopts(argc, argv)) { - // Create a Filename object and convert the file - Filename softFile(argv[1]); - stec.convert_file(softFile); - } - - return 0; -} diff --git a/pandatool/src/softegg/softToEggConverter.h b/pandatool/src/softegg/softToEggConverter.h deleted file mode 100644 index 05c26fa60f..0000000000 --- a/pandatool/src/softegg/softToEggConverter.h +++ /dev/null @@ -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 -#include - -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 &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 MorphTable; - MorphTable _morph_table; - - EggTable *morph_node; - EggSAnimData *find_morph_table(char *name); -}; - -extern const int TEX_PER_MAT; - -#endif diff --git a/pandatool/src/softprogs/softCVS.cxx b/pandatool/src/softprogs/softCVS.cxx deleted file mode 100644 index 478aa682d2..0000000000 --- a/pandatool/src/softprogs/softCVS.cxx +++ /dev/null @@ -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 - -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 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 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 &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 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; -} diff --git a/pandatool/src/softprogs/softCVS.h b/pandatool/src/softprogs/softCVS.h deleted file mode 100644 index adbd89efa6..0000000000 --- a/pandatool/src/softprogs/softCVS.h +++ /dev/null @@ -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 SceneFiles; - typedef pmultiset 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 &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 diff --git a/pandatool/src/softprogs/softFilename.cxx b/pandatool/src/softprogs/softFilename.cxx deleted file mode 100644 index 4c099c56be..0000000000 --- a/pandatool/src/softprogs/softFilename.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/softprogs/softFilename.h b/pandatool/src/softprogs/softFilename.h deleted file mode 100644 index 0565eabf89..0000000000 --- a/pandatool/src/softprogs/softFilename.h +++ /dev/null @@ -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 From 6b00fe79878d2eeb443890b17908810a863c4062 Mon Sep 17 00:00:00 2001 From: Younguk Kim Date: Sun, 28 Oct 2018 00:29:32 +0900 Subject: [PATCH 05/15] makepanda: fix link error of assimp tool Closes #432 --- makepanda/makepanda.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index caa5a164a9..89aec0e0f6 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -680,6 +680,9 @@ if (COMPILER == "MSVC"): IncDirectory("FCOLLADA", GetThirdpartyDir() + "fcollada/include/FCollada") if (PkgSkip("ASSIMP")==0): LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/assimp.lib") + path = GetThirdpartyDir() + "assimp/lib/IrrXML.lib" + if os.path.isfile(path): + LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/IrrXML.lib") IncDirectory("ASSIMP", GetThirdpartyDir() + "assimp/include/assimp") if (PkgSkip("SQUISH")==0): if GetOptimize() <= 2: From bb71cd68e1b3879122669d5cd1be93467a689bea Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:40:28 +0100 Subject: [PATCH 06/15] makepanda: use /BIGOBJ flag when compiling p3gobj_composite2.cxx --- makepanda/makepanda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 89aec0e0f6..1087ce1aff 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3818,7 +3818,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"]) From fb52a8e15efd0d358f4b2ba29237b8cc25ddeb54 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:41:05 +0100 Subject: [PATCH 07/15] text: fix deadlock in TextNode::write Fixes #431 --- panda/src/text/textNode.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 5a0c0c7f7f..4a77acd6d3 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -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"; From 35d095c2cf69faf7ed2a068a092915ec4b5bc46c Mon Sep 17 00:00:00 2001 From: TLOPOOperations Date: Mon, 22 Oct 2018 16:16:17 -0700 Subject: [PATCH 08/15] GSG: Fix symbol name conflict --- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 10 +++++----- panda/src/wgldisplay/wglGraphicsStateGuardian.cxx | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 904f47afc3..b7b0f7d3e7 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -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)) { diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index 735f7fc409..c98f12cf48 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -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)) { From e5c3ce19958dedd5d8100875daaae5829097d9da Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:44:24 +0100 Subject: [PATCH 09/15] pipeline: fix missing symbols for CycleDataLockedReader --- panda/src/pipeline/cycleDataLockedReader.I | 38 ++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/panda/src/pipeline/cycleDataLockedReader.I b/panda/src/pipeline/cycleDataLockedReader.I index a622b9a2c0..882d8f600e 100644 --- a/panda/src/pipeline/cycleDataLockedReader.I +++ b/panda/src/pipeline/cycleDataLockedReader.I @@ -45,6 +45,19 @@ CycleDataLockedReader(const CycleDataLockedReader ©) : _cycler->increment_read(_pointer); } +/** + * + */ +template +INLINE CycleDataLockedReader:: +CycleDataLockedReader(CycleDataLockedReader &&from) noexcept : + _cycler(from._cycler), + _current_thread(from._current_thread), + _pointer(from._pointer) +{ + from._pointer = nullptr; +} + /** * */ @@ -61,19 +74,6 @@ operator = (const CycleDataLockedReader ©) { _cycler->increment_read(_pointer); } -/** - * - */ -template -INLINE CycleDataLockedReader:: -CycleDataLockedReader(CycleDataLockedReader &&from) noexcept : - _cycler(from._cycler), - _current_thread(from._current_thread), - _pointer(from._pointer) -{ - from._pointer = nullptr; -} - /** * */ @@ -177,6 +177,18 @@ operator = (const CycleDataLockedReader ©) { _pointer = copy._pointer; } +/** + * + */ +template +INLINE void CycleDataLockedReader:: +operator = (CycleDataLockedReader &&from) noexcept { + nassertv(_pointer == nullptr); + + _pointer = from._pointer; + from._pointer = nullptr; +} + /** * */ From da820877357e5242850487b90bc96f7caf214048 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:45:14 +0100 Subject: [PATCH 10/15] tests: add unit test for TextNode::write, see #431 --- tests/text/test_textnode.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/text/test_textnode.py b/tests/text/test_textnode.py index e96c9e5371..bedc91b0da 100644 --- a/tests/text/test_textnode.py +++ b/tests/text/test_textnode.py @@ -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" From afc994b2fb6ed6258be8529e8e9ecd43d11948f7 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:47:16 +0100 Subject: [PATCH 11/15] display: fix crash when removing DisplayRegion in pipelined render Maybe not a perfect solution; we should consider keeping the DisplayRegions around until they have gone through the entire pipeline. Fixes #427 --- panda/src/display/graphicsEngine.cxx | 10 +++++----- panda/src/display/graphicsOutput.cxx | 26 +++++++++++++------------- panda/src/display/graphicsOutput.h | 1 + 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 57a592f05d..496a05e273 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -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); } diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 7c6cef51cb..c8237059b8 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -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; } diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index acd41e8289..f426b41bee 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -394,6 +394,7 @@ protected: typedef CycleDataLockedReader CDLockedReader; typedef CycleDataReader CDReader; typedef CycleDataWriter CDWriter; + typedef CycleDataStageWriter CDStageWriter; protected: int _creation_flags; From 99aa598de00e7c1d748fa6f20dc85d031ea1622c Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:51:25 +0100 Subject: [PATCH 12/15] makepanda: don't try to link static libs into static library --- makepanda/makepanda.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 1087ce1aff..7573e89606 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1598,6 +1598,8 @@ def CompileLib(lib, obj, opts): else: cmd = GetAR() + ' cru ' + BracketNameWithQuotes(lib) for x in obj: + if GetLinkAllStatic() and x.endswith('.a'): + continue cmd += ' ' + BracketNameWithQuotes(x) oscmd(cmd) From e92777619cf33895b3faa56352d4d245b131eb58 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:53:55 +0100 Subject: [PATCH 13/15] doc: remove two outdated documents --- doc/INSTALLING-PLUGINS.TXT | 20 ---- doc/InstallerNotes | 183 ------------------------------------- 2 files changed, 203 deletions(-) delete mode 100644 doc/INSTALLING-PLUGINS.TXT delete mode 100644 doc/InstallerNotes diff --git a/doc/INSTALLING-PLUGINS.TXT b/doc/INSTALLING-PLUGINS.TXT deleted file mode 100644 index 994e164936..0000000000 --- a/doc/INSTALLING-PLUGINS.TXT +++ /dev/null @@ -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) - - diff --git a/doc/InstallerNotes b/doc/InstallerNotes deleted file mode 100644 index cf57b15cc1..0000000000 --- a/doc/InstallerNotes +++ /dev/null @@ -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 /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. - - From 733c7f2352ba269f712e211fc770e5789c3ca4bb Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:59:18 +0100 Subject: [PATCH 14/15] makepanda: remove mention of removed softprogs/softcvs --- makepanda/makepanda.py | 16 ---------------- makepanda/makepanda.vcproj | 20 -------------------- 2 files changed, 36 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 7573e89606..7f82da5b80 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3299,7 +3299,6 @@ if (PkgSkip("PANDATOOL")==0): CopyAllHeaders('pandatool/src/ptloader') CopyAllHeaders('pandatool/src/miscprogs') CopyAllHeaders('pandatool/src/pstatserver') - CopyAllHeaders('pandatool/src/softprogs') CopyAllHeaders('pandatool/src/text-stats') CopyAllHeaders('pandatool/src/vrmlprogs') CopyAllHeaders('pandatool/src/win-stats') @@ -6352,21 +6351,6 @@ if (PkgSkip("PANDATOOL")==0): TargetAdd('p3pstatserver_composite1.obj', opts=OPTS, input='p3pstatserver_composite1.cxx') TargetAdd('libp3pstatserver.lib', input='p3pstatserver_composite1.obj') -# -# DIRECTORY: pandatool/src/softprogs/ -# - -if (PkgSkip("PANDATOOL")==0): - OPTS=['DIR:pandatool/src/softprogs', 'OPENSSL'] - TargetAdd('softcvs_softCVS.obj', opts=OPTS, input='softCVS.cxx') - TargetAdd('softcvs_softFilename.obj', opts=OPTS, input='softFilename.cxx') - TargetAdd('softcvs.exe', input='softcvs_softCVS.obj') - TargetAdd('softcvs.exe', input='softcvs_softFilename.obj') - TargetAdd('softcvs.exe', input='libp3progbase.lib') - TargetAdd('softcvs.exe', input='libp3pandatoolbase.lib') - TargetAdd('softcvs.exe', input=COMMON_PANDA_LIBS) - TargetAdd('softcvs.exe', opts=['ADVAPI']) - # # DIRECTORY: pandatool/src/text-stats/ # diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj index 6be22d7d1a..c4c34db4e3 100644 --- a/makepanda/makepanda.vcproj +++ b/makepanda/makepanda.vcproj @@ -4770,12 +4770,6 @@ - - - - - - @@ -5305,20 +5299,6 @@ - - - - - - - - - - - - - - From ed96a5270333c5344c9757393939c1a02a4dd1cc Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 20:40:55 +0100 Subject: [PATCH 15/15] cocoa: cautiously enable sRGB framebuffers on macOS [skip ci] --- panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm index 26d4dbdf71..b584d02a2c 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm @@ -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); + } } /**