2014-12-07 13:01:05 +00:00
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
# define EXPORT_GET_ALLOCATOR
# include <assert.h>
# ifdef _STLPORT_VERSION
namespace std
{
float fabsf ( float f ) ;
double fabsl ( double f ) ;
}
# endif
// Various MAX and MXS includes
# include <maxversion.h>
# if MAX_VERSION_MAJOR >= 14
# include <maxscript / maxscript.h>
# include <maxscript / foundation / 3dmath.h>
# include <maxscript / foundation / numbers.h>
# include <maxscript / maxwrapper / maxclasses.h>
# include <maxscript / foundation / streams.h>
# include <maxscript / foundation / mxstime.h>
# include <maxscript / maxwrapper / mxsobjects.h>
# include <maxscript / compiler / parser.h>
# include <maxscript / macros / define_instantiation_functions.h>
# else
# include <MaxScrpt / MAXScrpt.h>
# include <MaxScrpt / 3dmath.h>
# include <MaxScrpt / Numbers.h>
# include <MaxScrpt / MAXclses.h>
# include <MaxScrpt / Streams.h>
# include <MaxScrpt / MSTime.h>
# include <MaxScrpt / MAXObj.h>
# include <MaxScrpt / Parser.h>
# include <MaxScrpt / definsfn.h>
# endif
# include <max.h>
# include <stdmat.h>
// Visual
# include <direct.h>
# ifdef min
# undef min
# endif
# ifdef max
# undef max
# endif
// From nel patch lib
# include "../../plugin_max/nel_patch_lib/rpo.h"
# include "../../plugin_max/nel_mesh_lib/export_nel.h"
// From nel 3d
# include "nel/3d/zone.h"
# include "nel/3d/zone_symmetrisation.h"
# include "nel/3d/nelu.h"
# include "nel/3d/landscape_model.h"
// From nel misc
# include "nel/misc/file.h"
# include "nel/misc/o_xml.h"
# include "nel/misc/i_xml.h"
# include "nel/misc/config_file.h"
// From ligo library
# include "nel/../../src/ligo/zone_template.h"
# include "nel/ligo/ligo_config.h"
# include "nel/../../src/ligo/ligo_error.h"
# include "nel/../../src/ligo/ligo_material.h"
# include "nel/../../src/ligo/transition.h"
# include "nel/ligo/zone_bank.h"
# include "max_to_ligo.h"
using namespace std ;
using namespace NLMISC ;
using namespace NLLIGO ;
using namespace NL3D ;
// APP DATA
# define NEL3D_APPDATA_LIGO_USE_BOUNDINGBOX ((uint32)1342141818)
// ***************************************************************************
/// Definition of new MAXScript functions
def_visible_primitive ( export_material , " NeLLigoExportMaterial " ) ;
def_visible_primitive ( export_transition , " NeLLigoExportTransition " ) ;
def_visible_primitive ( export_zone , " NeLLigoExportZone " ) ;
//def_visible_primitive( export_transition_zone, "NeLLigoExportTransitionZone");
def_visible_primitive ( get_error_zone_template , " NeLLigoGetErrorZoneTemplate " ) ;
def_visible_primitive ( get_snap , " NeLLigoGetSnap " ) ;
def_visible_primitive ( get_cell_size , " NeLLigoGetCellSize " ) ;
def_visible_primitive ( check_zone_with_material , " NeLLigoCheckZoneWithMaterial " ) ;
def_visible_primitive ( check_zone_with_transition , " NeLLigoCheckZoneWithTransition " ) ;
def_visible_primitive ( get_error_string , " NeLLigoGetErrorString " ) ;
def_visible_primitive ( set_directory , " NeLLigoSetDirectory " ) ;
def_visible_primitive ( get_zone_mask , " NeLLigoGetZoneMask " ) ;
def_visible_primitive ( make_snapshot , " NeLLigoMakeSnapShot " ) ;
def_visible_primitive ( get_zone_size , " NeLLigoGetZoneSize " ) ;
// ***************************************************************************
/// Zone template
CLigoError ScriptErrors [ 10 ] ;
// ***************************************************************************
bool MakeSnapShot ( NLMISC : : CBitmap & snapshot , const NL3D : : CTileBank & tileBank , const NL3D : : CTileFarBank & tileFarBank ,
sint xmin , sint xmax , sint ymin , sint ymax , const CLigoConfig & config , bool errorInDialog ) ;
bool MakeSnapShot ( NLMISC : : CBitmap & snapshot , const NL3D : : CTileBank & tileBank , const NL3D : : CTileFarBank & tileFarBank ,
sint xmax , sint ymax , const CLigoConfig & config , bool errorInDialog ) ;
// ***************************************************************************
/// Export a material
Value * export_material_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (4)
check_arg_count ( export_material , 4 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoExportMaterial [Object] [Filename] [CheckOnly] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , Boolean , message ) ;
type_check ( arg_list [ 3 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second arg
const char * fileName = arg_list [ 1 ] - > to_string ( ) ;
// The third arg
bool checkOnly = ( arg_list [ 2 ] - > to_bool ( ) ! = FALSE ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 3 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export material " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// The zone template
CZoneTemplate zoneTemplate ;
// Build the zone template
bool res = CMaxToLigo : : buildZoneTemplate ( node , tri - > patch , zoneTemplate , config , ScriptErrors [ 0 ] , ip - > GetTime ( ) ) ;
// Success ?
if ( res )
{
// Build a zone
NL3D : : CZone zone ;
CZoneSymmetrisation zoneSymmetry ;
if ( tri - > rpatch - > exportZone ( node , & tri - > patch , zone , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Build a material
NLLIGO : : CMaterial material ;
// No error ?
if ( res = material . build ( zoneTemplate , config , ScriptErrors [ 0 ] ) )
{
// Save it ?
if ( ! checkOnly )
{
// Make a name for the zone
char drive [ 512 ] ;
char dir [ 512 ] ;
char name [ 512 ] ;
char path [ 512 ] ;
_splitpath ( fileName , drive , dir , name , NULL ) ;
_makepath ( path , drive , dir , name , " .zone " ) ;
// Ok ?
bool ok = true ;
// Catch exception
try
{
// Open a stream file
COFile outputfile ;
if ( outputfile . open ( fileName ) )
{
// Create an xml stream
COXml outputXml ;
nlverify ( outputXml . init ( & outputfile ) ) ;
// Serial the class
material . serial ( outputXml ) ;
// Another the stream
COFile outputfile2 ;
// Open another file
if ( outputfile2 . open ( path ) )
{
// Serial the zone
zone . serial ( outputfile2 ) ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the file %s for writing. " , path ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export material " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the file %s for writing. " , fileName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export material " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while save the file %s : %s " , fileName , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export material " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
// Remove the files
if ( ! ok )
{
remove ( fileName ) ;
remove ( path ) ;
}
}
}
}
else
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export material " ,
* MAXScript_interface , errorInDialog ) ;
}
}
// Return the result
return res ? & true_value : & false_value ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo export material " , * MAXScript_interface , errorInDialog ) ;
}
}
// Return false
return & false_value ;
}
// ***************************************************************************
/// Export a transition
Value * export_transition_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (6)
check_arg_count ( export_transition , 6 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoExportTransition [Object array (count=9)] [Output filename] [First material filename] [Second material filename] [CheckOnly] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , Array , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , String , message ) ;
type_check ( arg_list [ 3 ] , String , message ) ;
type_check ( arg_list [ 4 ] , Boolean , message ) ;
type_check ( arg_list [ 5 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
Array * nodes = ( Array * ) arg_list [ 0 ] ;
nlassert ( is_array ( nodes ) ) ;
// The second arg
const char * fileName = arg_list [ 1 ] - > to_string ( ) ;
// The second arg
string matFilename [ 2 ] ;
matFilename [ 0 ] = arg_list [ 2 ] - > to_string ( ) ;
matFilename [ 1 ] = arg_list [ 3 ] - > to_string ( ) ;
// The third arg
bool checkOnly = ( arg_list [ 4 ] - > to_bool ( ) ! = FALSE ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 5 ] - > to_bool ( ) ! = FALSE ) ;
// Ok ?
bool ok = true ;
// All zone are present ?
bool allPresent = true ;
// Clear error message
for ( uint error = 0 ; error < 10 ; error + + )
ScriptErrors [ error ] . clear ( ) ;
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export transition " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// CTransition::TransitionZoneCount elements in the array ?
if ( nodes - > size = = CTransition : : TransitionZoneCount )
{
// Build a node array
std : : vector < CZoneTemplate > arrayTemplate ( CTransition : : TransitionZoneCount ) ;
std : : vector < const CZoneTemplate * > arrayTemplatePtr ( CTransition : : TransitionZoneCount , NULL ) ;
std : : vector < RPO * > arrayTri ( CTransition : : TransitionZoneCount , NULL ) ;
std : : vector < INode * > arrayNode ( CTransition : : TransitionZoneCount , NULL ) ;
for ( uint i = 0 ; i < ( uint ) nodes - > size ; i + + )
{
// Get a node zone
if ( nodes - > get ( i + 1 ) ! = & undefined )
{
arrayNode [ i ] = nodes - > get ( i + 1 ) - > to_node ( ) ;
// Node builded ?
bool builded = false ;
// Get a Object pointer
ObjectState os = arrayNode [ i ] - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
arrayTri [ i ] = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( arrayTri [ i ] )
{
// Build a zone template
CZoneTemplate zoneTemplate ;
// Build the zone template
if ( CMaxToLigo : : buildZoneTemplate ( arrayNode [ i ] , arrayTri [ i ] - > patch , arrayTemplate [ i ] , config , ScriptErrors [ i ] , ip - > GetTime ( ) ) )
{
// Success, put the pointer
arrayTemplatePtr [ i ] = & arrayTemplate [ i ] ;
builded = true ;
}
}
}
// Ok ?
if ( ! builded )
ok = false ;
}
else
allPresent = false ;
}
// Ok, continue
if ( ok )
{
// Load the materials
NLLIGO : : CMaterial materials [ 2 ] ;
// For each material
for ( uint mat = 0 ; mat < 2 ; mat + + )
{
// Inputfile 0
CIFile input ;
if ( input . open ( matFilename [ mat ] ) )
{
// Catch some errors
try
{
// XML stream
CIXml inputXml ;
nlverify ( inputXml . init ( input ) ) ;
// Serial
materials [ mat ] . serial ( inputXml ) ;
}
catch ( Exception & e )
{
// Error message
char tmp [ 2048 ] ;
smprintf ( tmp , 2048 , " Error while loading material file %s : %s " , matFilename [ mat ] , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the file %s for reading. " , matFilename [ mat ] ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
// Ok ?
if ( ok )
{
// Build the transition
CTransition transition ;
if ( ok = transition . build ( materials [ 0 ] , materials [ 1 ] , arrayTemplatePtr , config , ScriptErrors , ScriptErrors [ CTransition : : TransitionZoneCount ] ) )
{
// Export ?
if ( ! checkOnly )
{
// All transitions are ok ?
if ( allPresent )
{
// Build the zones
NL3D : : CZone zones [ CTransition : : TransitionZoneCount ] ;
uint zone ;
for ( zone = 0 ; zone < CTransition : : TransitionZoneCount ; zone + + )
{
// Build the zone
CZoneSymmetrisation zoneSymmetry ;
if ( ! arrayTri [ zone ] - > rpatch - > exportZone ( arrayNode [ zone ] , & arrayTri [ zone ] - > patch , zones [ zone ] , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export material " ,
* MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
// Catch exceptions
if ( ok )
{
// File names
vector < string > createdfiles ;
try
{
// Open a stream file
COFile outputfile ;
if ( outputfile . open ( fileName ) )
{
// Add the filename
createdfiles . push_back ( fileName ) ;
// Create an xml stream
COXml outputXml ;
nlverify ( outputXml . init ( & outputfile ) ) ;
// Serial the class
transition . serial ( outputXml ) ;
// Make a name for the zone
char drive [ 512 ] ;
char dir [ 512 ] ;
char name [ 512 ] ;
// Export each zones
for ( zone = 0 ; zone < CTransition : : TransitionZoneCount ; zone + + )
{
// Final path
char path [ 512 ] ;
_splitpath ( fileName , drive , dir , path , NULL ) ;
sprintf ( name , " %s-%d " , path , zone ) ;
_makepath ( path , drive , dir , name , " .zone " ) ;
// Another the stream
COFile outputfile2 ;
// Open another file
if ( outputfile2 . open ( path ) )
{
// Add the filename
createdfiles . push_back ( path ) ;
// Serial the zone
zones [ zone ] . serial ( outputfile2 ) ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the file %s for writing. " , path ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the file %s for writing. " , fileName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while save the file %s : %s " , fileName , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
// Not ok ?
if ( ! ok )
{
// Erase the files
for ( uint file = 0 ; file < createdfiles . size ( ) ; file + + )
{
// Removing files
remove ( createdfiles [ file ] . c_str ( ) ) ;
}
}
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " All transition are not present. Can't export.. " ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export transition " , * MAXScript_interface , errorInDialog ) ;
ok = false ;
}
}
}
}
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: must have 9 cell in the node array " , " NeL Ligo export transition " ,
* MAXScript_interface , errorInDialog ) ;
}
}
// Ok ?
return ok ? & true_value : & false_value ;
}
// ***************************************************************************
Value * get_error_zone_template_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (4)
check_arg_count ( get_error_zone_template , 4 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoGetErrorZoneTemplate [Array error codes] [Array vertex id] [Array messages] [Error index] " ;
type_check ( arg_list [ 0 ] , Array , message ) ;
type_check ( arg_list [ 1 ] , Array , message ) ;
type_check ( arg_list [ 2 ] , Array , message ) ;
type_check ( arg_list [ 3 ] , Integer , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
Array * errorCodes = ( Array * ) arg_list [ 0 ] ;
nlassert ( is_array ( errorCodes ) ) ;
// The second arg
Array * vertexId = ( Array * ) arg_list [ 1 ] ;
nlassert ( is_array ( vertexId ) ) ;
// The third arg
Array * messages = ( Array * ) arg_list [ 2 ] ;
nlassert ( is_array ( messages ) ) ;
// The third arg
int errorIndex = arg_list [ 3 ] - > to_int ( ) - 1 ;
clamp ( errorIndex , 0 , 8 ) ;
// Num error
uint numError = ScriptErrors [ errorIndex ] . numVertexError ( ) ;
// For each error
for ( uint i = 0 ; i < numError ; i + + )
{
// Id and edge
uint id , edge ;
uint error = ( uint ) ScriptErrors [ errorIndex ] . getVertexError ( i , id , edge ) ;
// Append error code
errorCodes - > append ( Integer : : intern ( error + 1 ) ) ;
// Append vertex id
vertexId - > append ( Integer : : intern ( id + 1 ) ) ;
// Append messages
messages - > append ( new String ( " [LIGO DEBUG] Opened edge " ) ) ;
}
// Return the main error message
return Integer : : intern ( ( int ) ScriptErrors [ errorIndex ] . MainError + 1 ) ;
}
// ***************************************************************************
Value * get_snap_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (0)
check_arg_count ( get_snap , 0 , count ) ;
// Load the ligofile
CLigoConfig config ;
if ( CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , false ) )
{
return Float : : intern ( ( float ) config . Snap ) ;
}
else
return & undefined ;
}
// ***************************************************************************
Value * get_cell_size_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (0)
check_arg_count ( get_cell_size , 0 , count ) ;
// Load the ligofile
CLigoConfig config ;
if ( CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , false ) )
{
return Float : : intern ( ( float ) config . CellSize ) ;
}
else
return & undefined ;
}
// ***************************************************************************
/// Check a ligo zone with a ligo material
Value * check_zone_with_material_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (3)
check_arg_count ( check_zone_with_template , 3 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoCheckZoneWithMaterial [Object] [Material filename] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second arg
string fileName = arg_list [ 1 ] - > to_string ( ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 2 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo check zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// The zone template
CZoneTemplate zoneTemplate ;
// Build the zone template
bool res = CMaxToLigo : : buildZoneTemplate ( node , tri - > patch , zoneTemplate , config , ScriptErrors [ 0 ] , ip - > GetTime ( ) ) ;
// Success ?
if ( res )
{
// Material to check ?
if ( fileName ! = " " )
{
// The material
NLLIGO : : CMaterial material ;
// Read the template
CIFile inputfile ;
// Catch exception
try
{
// Open the selected template file
if ( inputfile . open ( fileName ) )
{
// Create an xml stream
CIXml inputXml ;
inputXml . init ( inputfile ) ;
// Serial the class
material . serial ( inputXml ) ;
// Get the zone edges
const std : : vector < CZoneEdge > & zoneEdges = zoneTemplate . getEdges ( ) ;
// All edge ok
res = true ;
// For each zone edge
for ( uint edge = 0 ; edge < zoneEdges . size ( ) ; edge + + )
{
// Check it
if ( ! material . getEdge ( ) . isTheSame ( zoneEdges [ edge ] , config , ScriptErrors [ 0 ] ) )
res = false ;
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the zone template file %s for reading. " , fileName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while loading the file %s : %s " , fileName , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
// Return the result
return res ? & true_value : & false_value ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return false
return & false_value ;
}
// ***************************************************************************
/// Check a ligo zone with a ligo material
Value * check_zone_with_transition_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (4)
check_arg_count ( check_zone_with_template , 4 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoCheckZoneWithTransition [Object] [Transition filename] [Transition number: 0~8] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , Integer , message ) ;
type_check ( arg_list [ 3 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second arg
string fileName = arg_list [ 1 ] - > to_string ( ) ;
// The second arg
int transitionNumber = arg_list [ 2 ] - > to_int ( ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 3 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo check zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// The zone template
CZoneTemplate zoneTemplate ;
// Build the zone template
bool res = CMaxToLigo : : buildZoneTemplate ( node , tri - > patch , zoneTemplate , config , ScriptErrors [ 0 ] , ip - > GetTime ( ) ) ;
// Success ?
if ( res )
{
// The material
NLLIGO : : CTransition transition ;
// Read the template
CIFile inputfile ;
// Catch exception
try
{
// Open the selected template file
if ( inputfile . open ( fileName ) )
{
// Create an xml stream
CIXml inputXml ;
inputXml . init ( inputfile ) ;
// Serial the class
transition . serial ( inputXml ) ;
// Check it
res = transition . check ( zoneTemplate , transitionNumber , config , ScriptErrors [ 0 ] ) ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the transition template file %s for reading. " , fileName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while loading the file %s : %s " , fileName , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
// Return the result
return res ? & true_value : & false_value ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return false
return & false_value ;
}
// ***************************************************************************
// Get the zone mask
void getSquareMask ( CZone & zone , std : : vector < bool > & mask , uint & width , uint & height , float cellSize )
{
CZoneInfo zoneInfo ;
zone . retrieve ( zoneInfo ) ;
// Look for bounding box of the zone, min size 1x1
sint maxX = 1 ;
sint maxY = 1 ;
// For each patches
uint i ;
for ( i = 0 ; i < zoneInfo . Patchs . size ( ) ; i + + )
{
CPatchInfo & patch = zoneInfo . Patchs [ i ] ;
// For each vertex
uint v ;
for ( v = 0 ; v < 4 ; v + + )
{
// Get the cel position
sint positionX = ( uint ) ( ( patch . Patch . Vertices [ v ] . x + cellSize / 2 ) / cellSize ) ;
sint positionY = ( uint ) ( ( patch . Patch . Vertices [ v ] . y + cellSize / 2 ) / cellSize ) ;
// PosX
if ( positionX > maxX )
maxX = positionX ;
// PosY
if ( positionY > maxY )
maxY = positionY ;
}
}
// Set the size
width = ( uint ) maxX ;
height = ( uint ) maxY ;
// Set the mask
uint size = width * height ;
mask . resize ( 0 ) ;
mask . resize ( size , true ) ;
}
// ***************************************************************************
/// Export a ligo zone
Value * export_zone_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (5)
check_arg_count ( check_zone_with_template , 5 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoExportZone [Object] [Ligozone filename] [Category Array] [Error in dialog] [Snapshot] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , Array , message ) ;
type_check ( arg_list [ 3 ] , Boolean , message ) ;
type_check ( arg_list [ 4 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second arg
string fileName = arg_list [ 1 ] - > to_string ( ) ;
// The thrid arg
Array * array = ( Array * ) arg_list [ 2 ] ;
// Build an array of category
vector < pair < string , string > > categories ;
categories . resize ( array - > size ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 3 ] - > to_bool ( ) ! = FALSE ) ;
// The fifth arg
bool weWantToMakeASnapshot = ( arg_list [ 4 ] - > to_bool ( ) ! = FALSE ) ;
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo check zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// For each array elements
uint i ;
for ( i = 0 ; i < ( uint ) array - > size ; i + + )
{
// Check that we have an array
type_check ( array - > get ( i + 1 ) , Array , message ) ;
// Check we have 2 strings
Array * cell = ( Array * ) array - > get ( i + 1 ) ;
if ( cell - > size ! = 2 )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: category arguments are not 2 strings " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
return & false_value ;
}
type_check ( cell - > get ( 1 ) , String , message ) ;
type_check ( cell - > get ( 2 ) , String , message ) ;
// Get the strings
categories [ i ] . first = cell - > get ( 1 ) - > to_string ( ) ;
categories [ i ] . second = cell - > get ( 2 ) - > to_string ( ) ;
}
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Build a filename
char drive [ 512 ] ;
char path [ 512 ] ;
char finalpath [ 512 ] ;
char name [ 512 ] ;
char ext [ 512 ] ;
_splitpath ( fileName . c_str ( ) , drive , path , name , ext ) ;
// Build the zone filename
char outputFilenameZone [ 512 ] ;
strcpy ( finalpath , path ) ;
strcat ( finalpath , " zones \\ " ) ;
_makepath ( outputFilenameZone , drive , finalpath , name , " .zone " ) ;
// Build the snap shot filename
char outputFilenameSnapShot [ 512 ] ;
strcpy ( finalpath , path ) ;
strcat ( finalpath , " zoneBitmaps \\ " ) ;
_makepath ( outputFilenameSnapShot , drive , finalpath , name , " .tga " ) ;
// Build the ligozone filename
char outputFilenameLigozone [ 512 ] ;
strcpy ( finalpath , path ) ;
strcat ( finalpath , " zoneLigos \\ " ) ;
_makepath ( outputFilenameLigozone , drive , finalpath , name , " .ligozone " ) ;
// Build the zone
CZone zone ;
CZoneSymmetrisation zoneSymmetry ;
if ( ! tri - > rpatch - > exportZone ( node , & tri - > patch , zone , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// The zone mask
std : : vector < bool > mask ;
uint width ;
uint height ;
// Calc zone mask or force bounding mask ?
bool useBoundingBox = CExportNel : : getScriptAppData ( node , NEL3D_APPDATA_LIGO_USE_BOUNDINGBOX , 0 ) ! = 0 ;
bool maskOk = false ;
if ( useBoundingBox )
{
// Get the square zone
getSquareMask ( zone , mask , width , height , config . CellSize ) ;
maskOk = true ;
}
else
{
// The zone template
CZoneTemplate zoneTemplate ;
// Build the zone template
bool res = CMaxToLigo : : buildZoneTemplate ( node , tri - > patch , zoneTemplate , config , ScriptErrors [ 0 ] , ip - > GetTime ( ) ) ;
// Success ?
if ( res )
{
// Build the zone mask
zoneTemplate . getMask ( mask , width , height ) ;
maskOk = true ;
}
}
// Continue ?
if ( maskOk )
{
// The bank
static CTileBank * tileBank = NULL ;
static CTileFarBank * tileFarBank = NULL ;
// Catch exception
try
{
// Load the bank
if ( tileBank = = NULL )
{
CIFile fileBank ;
if ( fileBank . open ( GetBankPathName ( ) ) )
{
// Create an xml stream
CTileBank * tileBankSerial = new CTileBank ;
tileBankSerial - > serial ( fileBank ) ;
tileBank = tileBankSerial ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the bank file %s for reading. " , GetBankPathName ( ) . c_str ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
if ( tileBank ! = NULL )
{
// Continue ?
bool cont = true ;
// The .TGA
if ( weWantToMakeASnapshot )
{
CIFile fileFarBank ;
char drive [ 512 ] ;
char path [ 512 ] ;
char name [ 512 ] ;
char farBankPathName [ 512 ] ;
_splitpath ( GetBankPathName ( ) . c_str ( ) , drive , path , name , NULL ) ;
_makepath ( farBankPathName , drive , path , name , " farbank " ) ;
if ( fileFarBank . open ( farBankPathName ) )
{
// Create an xml stream
CTileFarBank * tileFarBankSerial = new CTileFarBank ;
tileFarBankSerial - > serial ( fileFarBank ) ;
tileFarBank = tileFarBankSerial ;
CBitmap snapshot ;
if ( MakeSnapShot ( snapshot , * tileBank , * tileFarBank , width , height , config , errorInDialog ) )
{
// Output the snap shot
COFile outputSnapShot ;
if ( outputSnapShot . open ( outputFilenameSnapShot ) )
{
// Write the tga file
snapshot . writeTGA ( outputSnapShot , 32 ) ;
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the tga file %s for writing. " , outputFilenameSnapShot ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
cont = false ;
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the farbank file %s for reading. " , farBankPathName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
cont = false ;
}
}
// The .ZONE
if ( cont )
{
{
COFile outputZone ;
if ( outputZone . open ( outputFilenameZone ) )
{
// Serial the NeL zone
zone . serial ( outputZone ) ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the NeL zone file %s for writing. " , outputFilenameZone ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
// The .LIGOZONE
{
// Is filled ?
uint j ;
for ( j = 0 ; j < mask . size ( ) ; j + + )
if ( ! mask [ j ] ) break ;
// Add filled zone
if ( j > = mask . size ( ) )
{
categories . push_back ( pair < string , string > ( " filled " , " yes " ) ) ;
}
else
{
categories . push_back ( pair < string , string > ( " filled " , " no " ) ) ;
}
// Add the zone categorie
if ( width = = height )
{
categories . push_back ( pair < string , string > ( " square " , " yes " ) ) ;
}
else
{
categories . push_back ( pair < string , string > ( " square " , " no " ) ) ;
}
// Add the size category
char size [ 30 ] ;
smprintf ( size , 30 , " %dx%d " , width , height ) ;
categories . push_back ( pair < string , string > ( " size " , size ) ) ;
// Create the zone bank element
CZoneBankElement bankElm ;
bankElm . setMask ( mask , width , height ) ;
// Add the category
for ( j = 0 ; j < categories . size ( ) ; j + + )
{
bankElm . addCategory ( strlwr ( categories [ j ] . first ) , strlwr ( categories [ j ] . second ) ) ;
}
// Write the zone
COFile outputLigoZone ;
// Catch exception
try
{
// Open the selected zone file
if ( outputLigoZone . open ( outputFilenameLigozone ) )
{
// Create an xml stream
COXml outputXml ;
outputXml . init ( & outputLigoZone ) ;
// Serial the class
bankElm . serial ( outputXml ) ;
// Return true
return & true_value ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the ligozone file %s for writing. " , outputFilenameLigozone ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while writing the file %s : %s " , outputFilenameLigozone , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while loading the file bank %s : %s " , GetBankPathName ( ) . c_str ( ) , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
// Return false
return & false_value ;
}
// ***************************************************************************
Value * get_error_string_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (1)
check_arg_count ( get_error_string , 1 , count ) ;
// Checks arg
char * message = " NeLLigoGetErrorString [error code] " ;
type_check ( arg_list [ 0 ] , Integer , message ) ;
// The first arg
int errorCode = arg_list [ 0 ] - > to_int ( ) - 1 ;
// Error code
return new String ( ( char * ) CLigoError : : getStringError ( ( CLigoError : : TError ) errorCode ) ) ;
}
// ***************************************************************************
Value * set_directory_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (1)
check_arg_count ( set_directory , 1 , count ) ;
// Checks arg
char * message = " NeLLigoDirectory [path] " ;
type_check ( arg_list [ 0 ] , String , message ) ;
// The first arg
const char * dir = arg_list [ 0 ] - > to_string ( ) ;
// Set the directory
return ( chdir ( dir ) = = 0 ) ? & true_value : & false_value ;
}
// ***************************************************************************
Value * get_zone_mask_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (5)
check_arg_count ( check_zone_with_template , 5 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoGetZoneMask [Object] [Mask Array] [Width Array] [Height Array] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , Array , message ) ;
type_check ( arg_list [ 2 ] , Array , message ) ;
type_check ( arg_list [ 3 ] , Array , message ) ;
type_check ( arg_list [ 4 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The first array
Array * maskArray = ( Array * ) arg_list [ 1 ] ;
// The second array
Array * widthArray = ( Array * ) arg_list [ 2 ] ;
// The second array
Array * heightArray = ( Array * ) arg_list [ 3 ] ;
// The fourth arg
bool errorInDialog = ( arg_list [ 4 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Build the zone
CZone zone ;
CZoneSymmetrisation zoneSymmetry ;
if ( ! tri - > rpatch - > exportZone ( node , & tri - > patch , zone , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Get the object matrix
Matrix3 nodeTM ;
nodeTM = node - > GetObjectTM ( ip - > GetTime ( ) ) ;
// max x and y
int maxx = 0x80000000 ;
int maxy = 0x80000000 ;
// For each vertex
for ( uint vert = 0 ; vert < ( uint ) tri - > patch . numVerts ; vert + + )
{
// Transform in the world
Point3 worldPt = tri - > patch . verts [ vert ] . p * nodeTM ;
// Get cell coordinates
int x = ( int ) ( worldPt . x / config . CellSize ) + 1 ;
int y = ( int ) ( worldPt . y / config . CellSize ) + 1 ;
// Max ?
if ( x > maxx )
maxx = x ;
if ( y > maxy )
maxy = y ;
}
// The second array
maxx + + ;
maxy + + ;
widthArray - > append ( Float : : intern ( ( float ) maxx ) ) ;
heightArray - > append ( Float : : intern ( ( float ) maxy ) ) ;
// Cells
vector < bool > cells ( maxx * maxy , false ) ;
// For each patch
for ( uint patch = 0 ; patch < ( uint ) tri - > patch . numPatches ; patch + + )
{
// Average of the patch
Point3 average ( 0 , 0 , 0 ) ;
// For each vertex
for ( uint vert = 0 ; vert < 4 ; vert + + )
{
// Index of the vertex
int vertId = tri - > patch . patches [ patch ] . v [ vert ] ;
// Sum
average + = tri - > patch . verts [ vertId ] . p * nodeTM ;
}
// Average
average / = 4 ;
// Coordinates
int x = ( int ) ( average . x / config . CellSize ) + 1 ;
int y = ( int ) ( average . y / config . CellSize ) + 1 ;
// Clip
if ( ( x > = 0 ) & & ( y > = 0 ) & & ( x < maxx ) & & ( y < maxy ) )
{
// Set this ok
cells [ x + y * maxx ] = true ;
}
}
// For each cell
for ( uint k = 0 ; k < cells . size ( ) ; k + + )
{
// Build the result mask
maskArray - > append ( cells [ k ] ? & true_value : & false_value ) ;
}
// ok
return & true_value ;
}
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return false
return & false_value ;
}
// ***************************************************************************
Value * get_zone_size_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (6)
check_arg_count ( check_zone_with_template , 6 , count ) ;
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoGetZoneMask [Object] [minx Array] [maxy Array] [miny Array] [maxy Array] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , Array , message ) ;
type_check ( arg_list [ 2 ] , Array , message ) ;
type_check ( arg_list [ 3 ] , Array , message ) ;
type_check ( arg_list [ 4 ] , Array , message ) ;
type_check ( arg_list [ 5 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second array
Array * minXArray = ( Array * ) arg_list [ 1 ] ;
// The second array
Array * maxXArray = ( Array * ) arg_list [ 2 ] ;
// The second array
Array * minYArray = ( Array * ) arg_list [ 3 ] ;
// The second array
Array * maxYArray = ( Array * ) arg_list [ 4 ] ;
// The fourth arg
bool errorInDialog = ( arg_list [ 5 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Build the zone
CZone zone ;
CZoneSymmetrisation zoneSymmetry ;
if ( ! tri - > rpatch - > exportZone ( node , & tri - > patch , zone , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Get the object matrix
Matrix3 nodeTM ;
nodeTM = node - > GetObjectTM ( ip - > GetTime ( ) ) ;
// max x and y
int minx = 0x7fffffff ;
int miny = 0x7fffffff ;
int maxx = 0x80000000 ;
int maxy = 0x80000000 ;
// For each patch
for ( uint patch = 0 ; patch < ( uint ) tri - > patch . numPatches ; patch + + )
{
// Average of the patch
Point3 average ( 0 , 0 , 0 ) ;
// For each vertex
for ( uint vert = 0 ; vert < 4 ; vert + + )
{
// Index of the vertex
int vertId = tri - > patch . patches [ patch ] . v [ vert ] ;
// Sum
average + = tri - > patch . verts [ vertId ] . p * nodeTM ;
}
// Average
average / = 4 ;
// Coordinates
int x = ( int ) ( average . x / config . CellSize ) ;
int y = ( int ) ( average . y / config . CellSize ) ;
if ( x < minx )
minx = x ;
if ( x > maxx )
maxx = x ;
if ( y < miny )
miny = y ;
if ( y > maxy )
maxy = y ;
}
maxx + + ;
maxy + + ;
// The second array
minXArray - > append ( Float : : intern ( ( float ) minx ) ) ;
maxXArray - > append ( Float : : intern ( ( float ) maxx ) ) ;
minYArray - > append ( Float : : intern ( ( float ) miny ) ) ;
maxYArray - > append ( Float : : intern ( ( float ) maxy ) ) ;
// ok
return & true_value ;
}
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return false
return & false_value ;
}
// Make a snap shot of a zone
bool MakeSnapShot ( NLMISC : : CBitmap & snapshot , const NL3D : : CTileBank & tileBank , const NL3D : : CTileFarBank & tileFarBank ,
sint xmax , sint ymax , const CLigoConfig & config , bool errorInDialog )
{
return MakeSnapShot ( snapshot , tileBank , tileFarBank , 0 , xmax , 0 , ymax , config , errorInDialog ) ;
}
bool MakeSnapShot ( NLMISC : : CBitmap & snapshot , const NL3D : : CTileBank & tileBank , const NL3D : : CTileFarBank & tileFarBank ,
sint xmin , sint xmax , sint ymin , sint ymax , const CLigoConfig & config , bool errorInDialog )
{
// Result
bool result = false ;
try
{
// Resolution
sint widthPixel = config . ZoneSnapShotRes * ( xmax - xmin ) ;
sint heightPixel = config . ZoneSnapShotRes * ( ymax - ymin ) ;
sint oversampledWidth = widthPixel * 4 ;
sint oversampledHeight = heightPixel * 4 ;
// Oversampled size should be < 2048
if ( oversampledWidth > 2048 )
oversampledWidth = 2048 ;
if ( oversampledHeight > 2048 )
oversampledHeight = 2048 ;
// Oversampled size should be < sreen size
DEVMODE devMode ;
devMode . dmSize = sizeof ( DEVMODE ) ;
devMode . dmDriverExtra = 0 ;
EnumDisplaySettings ( NULL , ENUM_CURRENT_SETTINGS , & devMode ) ;
if ( oversampledWidth > ( sint ) devMode . dmPelsWidth )
oversampledWidth = devMode . dmPelsWidth ;
if ( oversampledHeight > ( sint ) devMode . dmPelsHeight )
oversampledHeight = devMode . dmPelsHeight ;
// Region
float width = config . CellSize * ( float ) ( xmax - xmin ) ;
float height = config . CellSize * ( float ) ( ymax - ymin ) ;
float posX = config . CellSize * ( float ) xmin ;
float posY = config . CellSize * ( float ) ymin ;
// Use NELU
2014-12-09 22:10:27 +00:00
if ( CNELU : : init ( oversampledWidth , oversampledHeight , CViewport ( ) , 32 , true , NULL , false , true ) ) // FIXME: OpenGL not working correctly, offscreen not available in Direct3D
2014-12-07 13:01:05 +00:00
{
// Setup the camera
CNELU : : Camera - > setTransformMode ( ITransformable : : DirectMatrix ) ;
CMatrix view ;
view . setPos ( CVector ( width / 2 + posX , height / 2 + posY , width ) ) ;
view . setRot ( CVector : : I , - CVector : : K , CVector : : J ) ;
2014-12-09 22:10:27 +00:00
CNELU : : Camera - > setFrustum ( width , height , 0.1f , 10000.f , false ) ;
2014-12-07 13:01:05 +00:00
CNELU : : Camera - > setMatrix ( view ) ;
// Create a Landscape.
CLandscapeModel * theLand = ( CLandscapeModel * ) CNELU : : Scene - > createModel ( LandscapeModelId ) ;
// Build the scene
CExportNelOptions options ;
CExportNel export_ ( errorInDialog , false , true , MAXScript_interface , " Snapshot ligozone " , & options ) ;
export_ . buildScene ( * CNELU : : Scene , * CNELU : : ShapeBank , * CNELU : : Driver , 0 , & theLand - > Landscape , NULL , false , false , false ) ;
theLand - > Landscape . setTileNear ( 50.f ) ;
theLand - > Landscape . TileBank = tileBank ;
theLand - > Landscape . TileFarBank = tileFarBank ;
theLand - > Landscape . initTileBanks ( ) ;
// Enable additive tiles
theLand - > enableAdditive ( true ) ;
theLand - > Landscape . setRefineMode ( true ) ;
2014-12-09 22:10:27 +00:00
// theLand->Landscape.setupStaticLight(CRGBA(255, 255, 255), CRGBA(0, 0, 0), 1.0f);
// theLand->Landscape.setThreshold(0.0005);
2014-12-07 13:01:05 +00:00
// Enbable automatique lighting
# ifndef NL_DEBUG
2014-12-09 22:10:27 +00:00
// theLand->Landscape.enableAutomaticLighting (true);
// theLand->Landscape.setupAutomaticLightDir (CVector (0, 0, -1));
2014-12-07 13:01:05 +00:00
# endif // NL_DEBUG
2014-12-09 22:10:27 +00:00
// theLand->Landscape.updateLightingAll();
2014-12-07 13:01:05 +00:00
// Clear the backbuffer and the alpha
CNELU : : clearBuffers ( CRGBA ( 255 , 0 , 255 , 0 ) ) ;
// Render the scene
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
CNELU : : Scene - > render ( ) ;
// Snapshot
CNELU : : Driver - > getBuffer ( snapshot ) ;
// Release the driver
CNELU : : Driver - > release ( ) ;
// Release NELU
CNELU : : release ( ) ;
// Resample the bitmap
snapshot . resample ( widthPixel , heightPixel ) ;
// Ok
result = true ;
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Can't initialise opengl offscreen renderer " , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
}
catch ( Exception & e )
{
// Error
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error during the snapshot: %s " , e . what ( ) ) ;
// Output an error
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return result
return result ;
}
// ***************************************************************************
/// Export a ligo zone
Value * make_snapshot_cf ( Value * * arg_list , int count )
{
// Make sure we have the correct number of arguments (7)
2014-12-09 22:10:27 +00:00
check_arg_count ( NeLLigoMakeSnapShot , 7 , count ) ;
2014-12-07 13:01:05 +00:00
// Check to see if the arguments match up to what we expect
char * message = " NeLLigoMakeSnapShot [Object] [Snapshot filename] [xMin] [xMax] [yMin] [yMax] [Error in dialog] " ;
type_check ( arg_list [ 0 ] , MAXNode , message ) ;
type_check ( arg_list [ 1 ] , String , message ) ;
type_check ( arg_list [ 2 ] , Integer , message ) ;
type_check ( arg_list [ 3 ] , Integer , message ) ;
type_check ( arg_list [ 4 ] , Integer , message ) ;
type_check ( arg_list [ 5 ] , Integer , message ) ;
type_check ( arg_list [ 6 ] , Boolean , message ) ;
// Get a good interface pointer
Interface * ip = MAXScript_interface ;
// The first arg
INode * node = arg_list [ 0 ] - > to_node ( ) ;
nlassert ( node ) ;
// The second arg
string fileName = arg_list [ 1 ] - > to_string ( ) ;
// The thrid arg
int xMin = arg_list [ 2 ] - > to_int ( ) ;
int xMax = arg_list [ 3 ] - > to_int ( ) ;
int yMin = arg_list [ 4 ] - > to_int ( ) ;
int yMax = arg_list [ 5 ] - > to_int ( ) ;
// The fourth arg
bool errorInDialog = ( arg_list [ 6 ] - > to_bool ( ) ! = FALSE ) ;
// Get a Object pointer
ObjectState os = node - > EvalWorldState ( ip - > GetTime ( ) ) ;
// Ok ?
if ( os . obj )
{
// Convert in 3ds NeL patch mesh
RPO * tri = ( RPO * ) os . obj - > ConvertToType ( ip - > GetTime ( ) , RYKOLPATCHOBJ_CLASS_ID ) ;
if ( tri )
{
// Load the ligofile
CLigoConfig config ;
if ( ! CMaxToLigo : : loadLigoConfigFile ( config , * MAXScript_interface , errorInDialog ) )
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't load the config file ligoscape.cfg " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// Build a filename
2014-12-09 22:10:27 +00:00
char drivetga [ 512 ] ;
char pathtga [ 512 ] ;
char nametga [ 512 ] ;
char exttga [ 512 ] ;
_splitpath ( fileName . c_str ( ) , drivetga , pathtga , nametga , exttga ) ;
2014-12-07 13:01:05 +00:00
// Build the zone
CZone zone ;
CZoneSymmetrisation zoneSymmetry ;
if ( ! tri - > rpatch - > exportZone ( node , & tri - > patch , zone , zoneSymmetry , 0 , config . CellSize , config . Snap , false ) )
{
// Error, zone can't be exported
CMaxToLigo : : errorMessage ( " Error: can't export the Nel zone, check bind errors. " , " NeL Ligo export zone " ,
* MAXScript_interface , errorInDialog ) ;
}
else
{
// The bank
static CTileBank * tileBank = NULL ;
static CTileFarBank * tileFarBank = NULL ;
// Catch exception
try
{
if ( tileBank = = NULL )
{
// Load the bank
CIFile fileBank ;
if ( fileBank . open ( GetBankPathName ( ) ) )
{
// Create an xml stream
CTileBank * bankSerial = new CTileBank ;
bankSerial - > serial ( fileBank ) ;
tileBank = bankSerial ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the bank file %s for writing. " , GetBankPathName ( ) . c_str ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
if ( tileBank ! = NULL )
{
CIFile fileFarBank ;
char drive [ 512 ] ;
char path [ 512 ] ;
char name [ 512 ] ;
char farBankPathName [ 512 ] ;
_splitpath ( GetBankPathName ( ) . c_str ( ) , drive , path , name , NULL ) ;
_makepath ( farBankPathName , drive , path , name , " farbank " ) ;
if ( fileFarBank . open ( farBankPathName ) )
{
// Create an xml stream
CTileFarBank * tileFarBankSerial = new CTileFarBank ;
tileFarBankSerial - > serial ( fileFarBank ) ;
tileFarBank = tileFarBankSerial ;
// Build a screenshot of the zone
CBitmap snapshot ;
if ( MakeSnapShot ( snapshot , * tileBank , * tileFarBank , xMin , xMax , yMin , yMax , config , errorInDialog ) )
{
// Build the snap shot filename
char outputFilenameSnapShot [ 512 ] ;
2014-12-09 22:10:27 +00:00
_makepath ( outputFilenameSnapShot , drivetga , pathtga , nametga , " .tga " ) ;
2014-12-07 13:01:05 +00:00
// Output the snap shot
COFile outputSnapShot ;
if ( outputSnapShot . open ( outputFilenameSnapShot ) )
{
// Write the tga file
snapshot . writeTGA ( outputSnapShot , 32 ) ;
// Some categories
vector < pair < string , string > > categories ;
// Add filled zone
categories . push_back ( pair < string , string > ( " filled " , " yes " ) ) ;
// Add the zone categorie
categories . push_back ( pair < string , string > ( " square " , " yes " ) ) ;
// Add the size category
categories . push_back ( pair < string , string > ( " size " , " 1x1 " ) ) ;
// Add the material category
categories . push_back ( pair < string , string > ( " material " , " fyros " ) ) ;
// Add the material category
categories . push_back ( pair < string , string > ( " zone " , name ) ) ;
// Create the zone bank element
CZoneBankElement bankElm ;
std : : vector < bool > mask ;
mask . push_back ( true ) ;
bankElm . setMask ( mask , 1 , 1 ) ;
// Add the category
for ( uint j = 0 ; j < categories . size ( ) ; j + + )
{
bankElm . addCategory ( strlwr ( categories [ j ] . first ) , strlwr ( categories [ j ] . second ) ) ;
}
// Write the zone
COFile outputLigoZone ;
2014-12-09 22:10:27 +00:00
_makepath ( outputFilenameSnapShot , drivetga , pathtga , nametga , " .ligozone " ) ;
2014-12-07 13:01:05 +00:00
// Catch exception
2014-12-09 22:10:27 +00:00
/*try
2014-12-07 13:01:05 +00:00
{
// Open the selected zone file
if ( outputLigoZone . open ( outputFilenameSnapShot ) )
{
// Create an xml stream
COXml outputXml ;
outputXml . init ( & outputLigoZone ) ;
// Serial the class
bankElm . serial ( outputXml ) ;
// Return true
return & true_value ;
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the ligozone file %s for writing. " , fileName . c_str ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while loading the file %s : %s " , fileName , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
2014-12-09 22:10:27 +00:00
} */
2014-12-07 13:01:05 +00:00
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the NeL snapshot file %s for writing. " , outputFilenameSnapShot ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
else
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Can't open the farbank file %s for reading. " , farBankPathName ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
catch ( Exception & e )
{
// Error message
char tmp [ 512 ] ;
smprintf ( tmp , 512 , " Error while loading the file bank %s : %s " , GetBankPathName ( ) . c_str ( ) , e . what ( ) ) ;
CMaxToLigo : : errorMessage ( tmp , " NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo export zone " , * MAXScript_interface , errorInDialog ) ;
}
}
else
{
// Output an error
CMaxToLigo : : errorMessage ( " Error: can't convert the object in 3ds NeL patch mesh object " ,
" NeL Ligo check zone " , * MAXScript_interface , errorInDialog ) ;
}
// Return false
return & false_value ;
}
// ***************************************************************************
/// MAXScript Plugin Initialization
// ***************************************************************************
__declspec ( dllexport ) void LibInit ( ) { }
// ***************************************************************************