/*
    MO       RF          ITMO          RFITMOR         FITMORFI      TM     ORFITMORFI    
    TM       OR         FI  TM         OR    FI        TM            OR         FI        
    TMO     RFI        TM    OR        FI     TM       OR            FI         TM        
    ORF     ITM        OR    FI        TM     OR       FI            TM         OR        
    FITM   ORFI       TM      OR       FI     TM       OR            FI         TM        
    ORFI   TMOR       FI      TM       OR    FI        TMORFIT       MO         RF        
    IT MO RF IT       MO      RF       ITMORFI         TM            OR         FI        
    TM OR FI TM       OR      FI       TM    OR        FI            TM         OR        
    FI  TMO  RF        IT    MO        RF     IT       MO            RF         IT        
    MO  RFI  TM        OR    FI        TM     OR       FI            TM         OR        
    FI   T   MO         RF  IT         MO     RF       IT            MO         RF        
    IT   M   OR          FITM          OR      FI      TM            OR         FI        


	mrft_api.h

	Morfit 3D engine API

	
	NOTE: There are many functions in this API. You will probably need
              only few of them. You can write a great game, program that uses
              3D graphics or an 3D web site using only about 20
              functions from this API. We suggest that you first look at some
              sample code and only when you feel comfortable, take a deeper
              look at this API.


              
	The main idea
	-------------
	With one command you load a three dimensional world model
	into the engine. With one command you create a camera
	for taking pictures from inside the world. 
	Now all you have to do is call this function
	Morfit_engine_render(HWND hwnd, DWORD camera)
	and voila !!! you have the picture taken using the camera
	pasted on the given window !!!!
	now if you modify the camera location or direction
	and call the rendering function again you get movement !!!

		
	Naming convention.
	1- All the functions of this API start with Morfit_
		example: Morfit_camera_create(char *camera_name);

	2- The second word is the name of the group of function.
		examples:
			Morfit_camera_set_location(x,y,x);
			Morfit_engine_increase_atmospheric_effect();


	There are several groups off API commands
	1- the engine API
		all function starting with Morfit_engine_
		controls things like picture quality, atmospheric effect etc ...

	2- the camera API
		all function starting with Morfit_camera_
		controls properties of the camera like
		zoom location direction etc...

	3- The object API
		all function starting with Morfit_object_
		In your world you can define objects like an airplane,
		a boy, a runner, a bird etc ...
		this api allows you to control their behavior.

	The Other APIs are:
	The Polygon API, the Point API, the group API,
	the Track API, the Bitmap API, the Math API, the Utilities API,
	the Animation API, the profiler API, the background API.
	You can find more information at the beginning of each API.


	Speed and performances
	-----------------------
	Once you are more familiar with the Morfit API you might want to 
	increase your application performances. Here are some tips:
	
	1) Do some of the following calls
		Morfit_engine_set_perspective_correction_accuracy(0);
		Morfit_engine_use_zbuffer(NO);
		Morfit_engine_set_automatic_quality_control();
		
		Each of the above functions has its advantages and disadvantages
		but they will all make your application run faster, read their 'help'
		in the tutorial for more details.




*/

#ifndef MRFT_API_H
#define MRFT_API_H


#include <windows.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
#if defined(__BORLANDC__)
	#define MORFIT_WINAPI WINAPI
#else
	#define MORFIT_WINAPI 
#endif
*/
#define MORFIT_WINAPI WINAPI

#define OK              0
#define VR_ERROR -1

#define YES 1
#define NO 0



#define WORLD_SPACE	0

#define OBJECT_SPACE (WORLD_SPACE+1)

#ifndef CAMERA_SPACE
#define CAMERA_SPACE (WORLD_SPACE+2)
#endif

#define PLAYER_CONTROL		1
#define COMPUTER_CONTROL	2
	
// used for Morfit_camera_save()
#define CAMERA_DESCRIPTOR_SIZE 53  //Number of DWORDs (212 bytes)

//#define FORBID_DIRECTX	

#define EDGE_NOT_SEEN		1
#define EDGE_FULLY_SEEN		2
#define EDGE_PARTIALLY_SEEN	3	
	
// Automatic movement constants == "Chasing"
// --------------------------
// In the wld file we have the following lines that are relevant
// to the Automatic movement.
// TRACK: track_name track_offset //chase name could be NO_TRACK if ...
// SPEED: track_speed    // track speed is also used in CHASE_PRECISE and CHASE_FLEXIBLE
						 // in those cases it is the distance behind the chased object
// CHASE: dynamic_object_to_chase  chase_offset
// CHASE_TYPE: chase_type tracking_softness  //tracking_softness is a number between 0 and 1.

// Below are the values that could appear in chase_type.
// relevant fields: none
// The NO_CHASE Const Must be 0.
#define	NO_CHASE							0 // doesn't move at all. Control is through software

// relevant fields: dynamic_object_to_chase, chase_offset
#define	CHASE_LOCATION						2 // trace only location. Only the line "CHASE: object_to_chase x y z " is relevant
											  // The three numbers are the offset from the object being chased
// relevant fields: dynamic_object_to_chase, chase_offset, chase_distance
#define	CHASE_PRECISE    					3 //  trace location and cord system. The track is ignored

	// relevant fields: dynamic_object_to_chase, chase_offset, chase_distance, tracking_softness
#define	CHASE_FLEXIBLE   					4 // trace location and direction with a delay

// not available yet
#define	CHASE_ON_TRACK   					(5+CHASE_TRACK_FAMILY) // chase the object to be chased but doesn't go out of the track line

// not available yet
#define	CHASE_INSIDE_TRACK_BOUNDING_BOX		6 // chase the object to be chased but doesn't go out from the track bounding box

// relevant fields: track_name, track_offset, speed, tracking_softness
#define	CHASE_TRACK   						(7+CHASE_TRACK_FAMILY) // just advance on the track according to the speed with out chasing anyone

// relevant fields: track_name, track_offset, speed, tracking_softness
#define	CHASE_TRACK_AIRPLANE				(8+CHASE_TRACK_FAMILY) // like CHASE_TRACK just with an airplane movements

//Not a chase type but a chase family
//Makes it possible to do things like if(chase_type & CHASE_TRACK_FAMILY) ...
#define CHASE_TRACK_FAMILY				128

#define CHASE_PHYSICS						9	//Moves the object according to the physics params (that is
												// speed,friction, elasticity, max_speed)
	
// Orientation values
#define ORIENTATION_UNKNOWN 0
#define ORIENTATION_TOP		1
#define ORIENTATION_BOTTOM	2
#define ORIENTATION_FRONT	4
#define ORIENTATION_BACK	8

#define NO_TRACK			0


#ifdef MORFIT_EXPORTS
#define MORFIT_IMPORT __declspec(dllexport)
#else
#define MORFIT_IMPORT __declspec(dllimport)
#endif



	
//--------------------------------------------------------//
//=========== T H E    E N G I N E   A P I ===============//
//--------------------------------------------------------//
	
// This API controls things like picture quality, atmospheric effect etc ...
	
// world_mode options (for function Morfit_engine_load_world() )
#define USER_DEFINED_BEHAVIOR 0
#define AUTO_BEHAVIOR01	1   //JAPPLIC_ID
#define AUTO_BEHAVIOR02	2	//CORE_APPLIC // NOTE AUTO_BEHAVIOR02 is obsolete
#define EDITOR_MODE	4
#define DONT_USE_ZBUFFER 8	//This option doesn't  works together with  EDITOR_MODE. When zbuffer is off
							// rendering will be faster but less accurate (things that are supposed to be hidden will sometime appear
							// depending on the structure of the used world). If zbuffer is on the rendering will
							// be accurate though slower. We suggest that you try both possibilities and choose what's best
							// The default is zbuffer ON.

////The resample flags cause every bitmap that is loaded to be automatically resampled to a power of two dimensions
//Note that since version 3.0 all the bitmaps that are not in the power of two are automatically resampled (with RESAMPLE_CLOSEST).
#define RESAMPLE_UP			16 //The new width and height will always be bigger than or equal than the original dimension of the bitmap
#define RESAMPLE_CLOSEST	32 //The new dimensions will be the closest power of two numbers to the original dimensions
#define RESAMPLE_DOWN		64 //The new width and height will always be smaller than or equal than the original dimension of the bitmap

#define	MIPMAP_DISABLE		0	//The default
#define	MIPMAP_STABLE		128	//Bitmaps will look more stable (The pixels wont "swim")
								//though the resolution will be a little bit lower
#define	MIPMAP_RESOLUTION	512	//This option prefers better resolution upon stable bitmaps
#define	MIPMAP_NORMAL		1024//An average between MIPMAP_STABLE and MIPMAP_RESOLUTION    

#define ENABLE_BRIGHT_LIGHT 2048 //Relevant only when 3D card is used.
#define ENABLE_VERY_BRIGHT_LIGHT 4096
#define CREATE_BSP_FOR_DYNAMIC_OBJECTS 8192
#define NO_BSP_FOR_STATIC_WORLD 16384

// For checking if a handle is legal (for example a camera handle) you can do one of the two:
// 1- call the function Morfit_camera_is_camera(handle, "my_test");
// 2- Use the macro IS_CAMERA. The advantage of the macro is that you can 
// replace it with an empty macro on your release program.
// See more details next to the declaration of function Morfit_camera_is_camera()
#define         IS_CAMERA(camera_handle,function_name)			Morfit_camera_is_camera(camera_handle,function_name)
#define         IS_OBJECT(object_handle,function_name)			Morfit_object_is_object(object_handle,function_name)			
#define         IS_GROUP(group_handle,function_name)			Morfit_group_is_group(group_handle,function_name)
#define         IS_TRACK(track_handle,function_name)			Morfit_track_is_track(track_handle,function_name)
#define         IS_POLYGON(polygon_handle,function_name)		Morfit_polygon_is_polygon(polygon_handle,function_name)
#define         IS_LIGHT(light_handle,function_name)			Morfit_light_is_light(light_handle,function_name)
#define         IS_POINT(point_handle,function_name)			Morfit_point_is_point(point_handle,function_name)
#define         IS_BITMAP(bitmap_handle,function_name)			Morfit_bitmap_is_bitmap(bitmap_handle,function_name)
#define         IS_ANIMATION(animation_handle,function_name)	Morfit_animation_is_animation(animation_handle,function_name)
#define         IS_BACKGROUND(background_handle,function_name)	Morfit_background_is_background(background_handle,function_name)
#define         IS_3D_ANIMATION(animation3d_handle,function_name)	Morfit_3D_animation_is_3D_animation(animation3d_handle,function_name)
#define         IS_3D_SEQUENCE(sequence3d_handle,function_name)	Morfit_3D_sequence_is_3D_sequence(sequence3d_handle,function_name)

// This function puts the image seen from the camera on the given window
// The rendering operation is not automatic after every API function
// This way we can save lots of CPU time by calling a group of API function
// followed by only one call to Morfit_engine_render(). (This function takes lots of
// CPU time while all the other are very fast to execute)
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_render(HWND hwnd, DWORD camera);

//exactly like Morfit_engine_render() only easier to use
// if you are working with MFC
//MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_render_on_cwnd(void *pointer_to_CWnd_object, void *camera);

// returns (OK / VR_ERROR)
// It is important to check the return value
// Arguments:
// world_file_name: the name of the file to be loaded 
//					examples: "my_world.wld" , "my_world.raw" , "C:\\worlds\\my_world.x"
// world_directory_path: relevant only if  INCLUDE_FILE is used
//						 (INCLUDE_FILE is used in the world file if our world consist of several files)
//						  using a different world_directory_path we can load the same
//						world with different models library
//						or we can use one models library for several worlds
//						examples: "", "C:\\models\\chaires\\plastic", "C:\\models\\chaires\\plastic"
// bitmaps_directory_path:
//						using a different bitmaps_directory_path we can load the same
//						world with different bitmaps library
//						or we can use one bitmap library for several worlds
//						examples: "", "C:\\bitmaps1", "C:\\bitmaps2", "bitmaps"
// world_mode options: 
//		USER_DEFINED_BEHAVIOR 
//		AUTO_BEHAVIOR01			Automatically moves the camera or an object according the arrows key
//		AUTO_BEHAVIOR02			Obsolete
//		EDITOR_MODE				Dont move objects automatically. make it possible to use all the group API
//
//		DONT_USE_ZBUFFER 
//						This option doesn't  work together with  EDITOR_MODE. When zbuffer is off, the
//						rendering will be faster but could be less accurate (things that are supposed to be hidden will sometime appear
//						depending on the structure of the used world). If zbuffer is on, the rendering will sometime
//						more accurate though slower. We suggest that you try both possibilities and choose what's best
//						The default is zbuffer ON. The changes in speed are not so relevant when using a 3D card (harware rendering)
//
//		The resample flags cause every bitmap that is loaded to be automatically resampled to a power of two dimensions
//		RESAMPLE_UP			 The new width and height will always be bigger than or equal than the original dimension of the bitmap
//		RESAMPLE_CLOSEST	 The new dimensions will be the closest power of two numbers to the original dimensions
//		RESAMPLE_DOWN		 The new width and height will always be smaller than or equal than the original dimension of the bitmap
//
//		ENABLE_BRIGHT_LIGHT				Relevant only when 3D card is used. Makes it possible to create brighter lighting on textures
//		ENABLE_VERY_BRIGHT_LIGHT 
//		CREATE_BSP_FOR_DYNAMIC_OBJECTS	This used to be the default. The default was changed since a BSP tree might add polygons to the world
//		NO_BSP_FOR_STATIC_WORLD 16384   The world might have less polygons but collision detection will be slower. Usually it is not recommended to use this flag.
//
// For editor mode do an OR operation for example USER_DEFINED_BEHAVIOR | EDITOR_MODE
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_load_world(char *world_file_name, char *world_directory_path, char *bitmaps_directory_path, int world_mode);

// The loaded world will be add to the existing world
// the given position indicates where the origin of the added world will be located
// returns a handle to the group that encapsulates the added world
// if an error occurred it will return NULL
// It is important to check the return value
// Note that usually you will call Morfit_group_set_location(added_world_grp, position);
// after calling Morfit_engine_add_world() to move the center of the added world
// to this position. Not calling Morfit_group_set_location() will put the origin
// of the added world in the given position. Note that this is different from  moving the center of the world to 
// the given position
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_add_world(char *world_file_name, char *world_directory_path, char *bitmaps_directory_path, double position[3]);


// returns YES if no world is loaded into the engine
// otherwise returns NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_is_engine_empty(void);

/*

// This function is not in use anymore instead 
// When doing Morfit_engine_load_world() for editor mode do an OR operation for example USER_DEFINED_BEHAVIOR | EDITOR_MODE
//return OK or VR_ERROR
//The editor mode is slower but it enables you to
// edit the world in real-time
// It will only effect the next world that will be loaded
// 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_editor_mode(void);


// This function is not in use anymore instead 
// Viewer mode is the default mode. Each time 
// we do Morfit_engine_load_world() and we dont use the EDITOT_MODE flag it 
// will load the world in viewer mode.
//
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_viewer_mode(void);
 */

MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_is_editor_mode(void);

// change the resolution of the screen.
// bits_per_pixel is 8 or 16 or 24
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_resolution(int width, int height, int bits_per_pixel);

// returns the resolution of the screen in the three arguments.
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_resolution(int *width, int *height, int *bits_per_pixel);


// change the screen graphics mode.
// the dimensions are not change only the color depth
// bits_per_pixel is 8 or 16 or 24
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_color_depth(int bits_per_pixel);


MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_log_window_visible(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_hide_log_window(void);
MORFIT_IMPORT int   MORFIT_WINAPI Morfit_engine_is_log_window_visible(void);

// On the log window there are two fields that has to do with the progress bar
// one field represent the current progress and the other the target number
// that the progress should reach.
MORFIT_IMPORT int   MORFIT_WINAPI Morfit_engine_get_log_window_progress(void);
MORFIT_IMPORT int   MORFIT_WINAPI Morfit_engine_get_log_window_target(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_log_window_progress(int value);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_log_window_target(int value);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_log_window_minimize(void);

//Add text to the log window
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_log_window_output(char *text);

//Delete the old text and put the new text instead.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_log_window_set_text(char *new_text);

//Set the title of the log window
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_log_window_set_title(char *new_caption);

MORFIT_IMPORT HWND  MORFIT_WINAPI Morfit_engine_log_window_get_hwnd(void);

//delete all the text in morfits log files
//there are two log files. morfit.log and error.log.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_clear_morfit_log_files(void);

// (x,y) is a point in the rendering window
// usually we get this point from the events like OnLButtonDown()
// returns OK if a polygon was marked
// returns VR_ERROR if there is no polygon in that spot
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_mark_polygon_at_point(int x, int y);

// gets a two dimensional point=> (x,y) is a point in the rendered window
// usually we get this point from the events like OnLButtonDown()
// and retrieves the corresponding three dimensional point
// in the virtual space. Return OK on success. returns VR_ERROR if
// failed. note that if we give a point where there is no 
// polygon rendered there will get VR_ERROR because the point
// in 3D is in infinity ... in that case the 3d point retrieved (result[] )
// will hold (0,0,0)
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_2D_point_to_3D(int x, int y, double result[3], DWORD *selected_object_handle, DWORD *selected_polygon_handle);

// gets a two dimensional point=> (x,y) is a point in the rendered window
// usually we get this point from events like OnLButtonDown()
// and retrieves the corresponding three dimensional point that is on the given plane
// in the virtual space. Return OK on success. returns VR_ERROR if
// failed.
// The difference between this function on Morfit_engine_2D_point_to_3D() is that
// here we get the 3D point as if the polygon is end-less and in Morfit_engine_2D_point_to_3D()
// once we give a 2d point that is outside the polygon we will get what's behind
// this polygon (or in front). Another way to think of that is like that
// This function is equal to Morfit_engine_2D_point_to_3D() if we have only one polygon in
// the world and this polygon is end-less.
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_2D_point_to_3D_point_on_plane(int x, int y, double polygons_plane[4],double p3d[3]);


// gets a point in the world and returns the 
// matching point on the screen.
// On call p2D[2] has no meaning
// on exit it will contain the 2D point.
// on call p3D[3] should be the 3D point in the world.
// return value:
// returns -1 if an error occurred. p2D contains 0,0
// returns 0 if every thing is OK. p2D contains a valid result
// returns 1 if the point is out of the window. p2D contains a valid result.
// returns 2 if the point is behind the camera. p2D contains a valid result though  not accurate
// returns 3 if both: behind the camera and out of the window. p2D contains a valid result though  not accurate
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_3D_point_to_2D(double p3D[3], int p2D[2]);

// Note that picture quality that is set by the following
// functions is related to the current camera only (the camera that was
// last used by Morfit_engine_render(). 
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_picture_quality(int quality);
MORFIT_IMPORT int   MORFIT_WINAPI Morfit_engine_get_picture_quality(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_increase_picture_quality(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_decrease_picture_quality(void);

// This function deals with fine tuning the engine performances
// This function checks if it is possible to increase the quality without
// slowing down rendering time. The return value is YES or NO.
// Returns NO if couldn't increase quality without hurting performances.
// Returns YES if succeeded to do so.
// Usually this function will return NO. If it return YES
// then it is better if we dont change the graphics quality our selves by calling Morfit_engine_set_picture_quality() 
// Note that this function is very slow (about one third of a second !)
// Usually you would like to call it before the first render
// for calibration-optimization. Call this function with the same parameters you
// call Morfit_engine_render();
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_automatic_quality_control(HWND hwnd, DWORD camera_handle);



MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_normal_rendering_mode(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_color_fill_rendering_mode(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_wire_frame_rendering_mode(void);


MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_toggle_rendering_mode(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_toggle_wire_frame_flag(void);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_default_brightness(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_increase_brightness(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_decrease_brightness(void);
// Zero means according to what is set in the input world file.
// a positive number means make brighter. a negative number means darker
// values should be in the range -64 till +64
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_brightness(int value);
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_get_brightness(void);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_increase_atmospheric_effect_intensity(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_decrease_atmospheric_effect_intensity(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_default_atmospheric_effect_intensity(void);
// 1 means according to what is set in the input world file.
// 2 means the atmospheric effect intensity is doubled.
// 0.5 means atmospheric effect intensity is half.
// 0 means that atmospheric effect is off.
MORFIT_IMPORT double  MORFIT_WINAPI Morfit_engine_get_atmospheric_effect_intensity(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_atmospheric_effect_intensity(double value);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_toggle_atmospheric_effect(void);

// set the background color automatically to the atmosphere color
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_atmospheric_effect(int red, int green, int blue);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_get_atmospheric_effect(int *red, int *green, int *blue);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_background_color(int red, int green, int blue);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_get_background_color(int *red, int *green, int *blue);

// toggle between automatic perspective correction and
// no perspective correction(fastest).
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_toggle_automatic_perspective_correction(void);
// cancels automatic mode and toggle between several accuracy modes.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_toggle_perspective_correction_accuracy(void);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_increase_far_objects_color_accuracy(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_decrease_far_objects_color_accuracy(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_default_far_objects_color_accuracy(void);
// When the polygons nearest point needs a bigger or equal palette to
// this value it will be painted with fill color instead of bitmap fill.
// The value must be in the range [0, NUMBER_OF_PALETTES-1]
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_get_far_objects_color_accuracy(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_far_objects_color_accuracy(int value);

MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_increase_culling_depth(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_decrease_culling_depth(void);
// The given value should be in the range [0 - Infinity ]
// A reasonable value is around NUMBER_OF_PALETTES.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_default_culling_depth(void);
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_get_culling_depth(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_set_culling_depth(int value);

// if movement possible returns YES else returns NO
// If movement is not possible it returns the blocking polygon 
// and the intersection point.
// Note that the normal of the blocking surface is N=( plane[0], plane[1], plane[2])
// If the return value is NO and blocking_object==NULL
// it means that what blocks us is the static part of the world
// Note that the function will be faster if the distance between the start_location and the end_location is smaller
// Important NOTE:
// Polygons have only one side. 
// So there is a question what to do when we want to
// go through a polygon that is not visible to the camera
// (the camera sees its back only)
// The solution that we chose is that:
// In Viewer (Morfit_load_world() without EDITOR_MODE) mode we dont care if you see the polygon or not
// you can never go through it !
// In Editor mode we apply the following.
	// If the current camera sees the polygon then it is like
	// a solid wall (nothing can go through the wall and nothing can come from the wall)
	// If the current camera doesn't see the polygon then it is as if
	// the polygon doesn't exist at all.
	// If you didnt get it, we will try again.
	// say A is a point in space in the front of the poly and B is a point on the back side 
	// of the polygon (The front is the side of the normal where you see the vertex in counterclockwise order)
	// then if the location of the camera is in the side of A then
	// one cant move not from A to B nor form B to A.
	// if the current camera is in the side of B
	// then it is possible to move both from A to B and from
	// B to A.
	// Note that the result is insensitive to the direction
	// of movement ( start_point to end_point or the other way around)
	// IMPORTANT:
	// If you want to move the camera from A to B. Lets say there is a one sided polygon
	// on the way that doesn't allow the movement. Now watch this one, there is a big
	// difference between the following options
	// I- moving the camera to B and then asking Morfit_engine_is_movement_possible()
	// II- asking Morfit_engine_is_movement_possible() while we are in A
	// In the first case we would get YES (error)
	// In the second case we would get the correct answer - NO
	// The reason for that is that if the camera is at point B then from point
	// B the polygon is not seen (we see only its back side which is invisible)
	// and if the obstacle is not seen then the movement is allowed !
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_is_movement_possible(double start_location[3], double end_location[3], DWORD *intersected_polygon, double intersection[3], DWORD *blocking_object);

// if movement possible returns YES else returns NO
// If movement is not possible it returns the plane equation Ax+By+Cz+D=0
// and the intersection point.
// Note that the normal of the blocking surface is N=( plane[0], plane[1], plane[2])
// If the return value is NO and blocking_object==NULL
// it means that what blocks us is the static part of the world
// see also remarks on Morfit_engine_is_movement_possible()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_is_movement_possible_camera_space(double start_location[3], double end_location[3], DWORD *intersected_polygon, double intersection[3], DWORD *blocking_object);

//Counts how many polygons we will cross going from point1 to point2
//in addition it calculates the average normal of all the polygons between the two points
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_number_of_collisions(double point1[3], double point2[3], double combined_normal[3]);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_object_at_point_2D(int x,int y);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_polygon_at_point_2D(int x,int y);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_default_rendering_window_size(int left_x, int top_y, int width, int height);

//The default rendering window is the window on which the engine render
//when we call Morfit_engine_render() with a NULL window
//(example: Morfit_engine_render(NULL,camera))
//If the return value is NULL it means that the function failed
//One can use this handle with many of the win32 api function
//that deals with windows
MORFIT_IMPORT HWND MORFIT_WINAPI Morfit_engine_get_default_rendering_window_hwnd(void);

//The default rendering window is the window on which the engine render
//when we call Morfit_engine_render() with a NULL window
//(example: Morfit_engine_render(NULL,camera))
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_maximize_default_rendering_window(void);

//The default rendering window is the window on which the engine render
//when we call Morfit_engine_render() with a NULL window
//(example: Morfit_engine_render(NULL,camera))
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_minimize_default_rendering_window(void);

//The default rendering window is the window on which the engine render
//when we call Morfit_engine_render() with a NULL window
//(example: Morfit_engine_render(NULL,camera))
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_default_rendering_window_title(char *text);

//The default rendering window is the window on which the engine render
//when we call Morfit_engine_render() with a NULL window
//(example: Morfit_engine_render(NULL,camera))
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_default_rendering_window_size(int left_x, int top_y, int width, int height);


// accuracy is used when we try to check whether two polygons
// have the same plane (so we can unite them to one polygon). 
// If this number for example is 0.1 and 
// the X component if the normals are planeA[0]=1 and planeB[0]=0.9
// then the join operation will take place.
// can be done only in editor mode.
// returns the number of polygons that were reduced.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_reduce_polygons_count(double accuracy);

// returns OK or VR_ERROR.
// Add a polygon to the world. A polygon can be created and manipulate
// but it is not drawn until we call this function.
// the function check the validity of the polygon 
// If the operation succeed it returns OK, else VR_ERROR.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_add_polygon(DWORD polygon_handle);


// the file name should have the extension .wld or
// should be without an extension at all (.wld will be add automatically)
// if a relative path is provided it will be relative to
// the directory of the executable.
// if group_to_save==NULL the whole world will be saved
// return OK or VR_ERROR
// possible flags: (note that we can do an OR operation between them)
#define SAVE_DEFAULT			0
#define SAVE_ONLY_WHATS_NEEDED	1 //does NOT save extra resources that are not needed to the saved group. it will save only animations that are needed for the polygons in the models. Cameras backgrounds and tracks will NOT be saved
									// see also SAVE_MODELS_ONLY
#define SAVE_FLAT_BITMAP_PATH	2 //for every polygon the name of its bitmap wont include the path just the name. the same for animations. this is very convenient if we want to keep all the bitmap in one directory.
								// If we also save bitmaps then the save will be done with flat bitmap path no matter the value of this flag.
// The following options will save the world as a complete projects including the bitmaps file
// The function will make a directory called bitmap bellow the given path, and there it will put all the bitmaps
// The idea here that the world becomes a "stand alone" it can be send through e-mail, put on a diskette etc ...
// Note that when you try to load the world
// after it was saved the engine would first look for jbm files
// then for bmp and then for jpg, so if a bitmap was changed and saved as bmp
// but the jbm file wasnt deleted then the engine will load the old bitmap in the jbm format.
// using one of the bitmaps flag will cause the save to be done with flat bitmap path no matter the value of this flag.
// using different kind of bitmaps type is allowed. it will create all of them on the disk.
#define SAVE_BITMAP_AS_JPG		4  //The bitmaps are saved in a JPG format. This should be done when optimizing for space. The down side is that it would take more time to load the world. and
									// the quality of some bitmaps might suffer. If transparent bitmap have spots or that some parts are missing one can modify by hand
									// The *.flt file for that bitmap.
								    //for more information about the flt files see at the bottom of this file
								    // in the help appendixes

#define SAVE_BITMAP_AS_BMP		8  //The bitmaps are saved in a BMP format. This should be done when we want the ability to modify the bitmaps
									// using bitmaps editors like PhtoPaint, Photoshop, Paintbrush etc ... Remember to delete the jbm file each time you modify the bitmap.
#define SAVE_BITMAP_AS_JBM		16 //The bitmaps are saved in a JBM format. This is the engine internal format. This should be done when we want the loading time of the world to be as short as possible.

//see also the flag SAVE_BITMAP_OPTIMIZE below

#define SAVE_IN_MULTIPLE_FILES	32 // Instead of putting all the models in one file, it saves each model
									// in a separate file. This way is easier to change the world
									// by hand. In this method it is also very easy to replace components (now each one is
									// separate file

#define	SAVE_ONLY_MODELS 64 //Save the model and its bitmaps and only the animations that are currently used by
							// the model. This is the same as to call with SAVE_ONLY_WHATS_NEEDED when all the save flags are set to NO
							// ( see Morfit_camera_set_save_flag() , Morfit_animation_set_save_flag(0 etc ...)

#define SAVE_RELEASE 128 //1-	All the polygons will be put inside module main
						 //		this makes a faster save and a faster load afterwards
						 //		When we load a world that was save using SAVE_RELEASE we
						 //		will lose all group affiliations.
						 //2-	polygons that have their release_save flag set to NO wont be saved
						 //		for example some models have polygons that are used only as a bottom
						 //		(applications like Morfit World Builder need a bottom polygon so when
						 //		we drop an objects on a floor it will know how to put it, in some models
						 //		a bottom polygon is part of the model and in others (like trees) it is just an extra polygon)
						 //		the release_save_flag can be set by Morfit_polygon_set_release_save_flag() or
						 //		by specifying NO\YES in the RELEASE_SAVE field in the world text file

#define SAVE_BITMAP_OPTIMIZED 512 //This option overrides the following flags SAVE_BITMAP_AS_JPG, SAVE_BITMAP_AS_BMP, and SAVE_BITMAP_AS_JBM
								  //with this option all the bitmaps will be saved in jpg format
								  //except those that are being used with a transparency, those will be saved
								  //in BMP format. This flag is used when we want to save in jpg format
								  //but we dont want the jpg format to ruin the transparency bitmaps.
								  //The problem is that jpg images are not identical to the original and
								  //this makes a big problem with the transparent color because instead of one background color
								  //for example 255,255,255 we get several like 254,255,255 and 255,254,254 etc ...
								  //the engine will only eliminate one transparent color leaving all the other nuances
								  //If you didnt understand, just try to save a world using the flag SAVE_BITMAP_AS_JPG
								  //and then load the saved world and look at polygons that use a transparent bitmap.
								  //another way to deal with this problem is using the flt file that is saved together with each jpg bitmap
								  //for more information about the flt files see at the bottom of this file
								  // in the help appendixes

MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_save(char *file_name, DWORD group_to_save, int save_flags);

//Use Morfit_engine_save() with a .x extension ...
//MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_save_in_directx_format(char *file_name);



// Redraw on the window the last rendered image
// Usually used together with Morfit_engine_render_on_dc()
// Note that this function also releases the dc the was obtained
// when calling Morfit_engine_render_on_dc() this means that
// all the function that use the returned dc (from dc=Morfit_engine_render_on_dc() )
// must be called before calling Morfit_engine_copy_image_from_dc_to_screen().
// 
//See Morfit_engine_render_on_dc() for more information.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_copy_image_from_dc_to_screen(void);

//obsolete. Completely identical (Physically the same) to Morfit_engine_copy_image_from_dc_to_screen()
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_engine_bitblt(void);

//like Morfit_engine_render() only that the created image is not
// blted on the window. This function is good for the occasion
// that we would like to paint things on top of the rendered image.
// the return value on success is the bitmap with picture taken
// with the given camera.
// on failure returns NULL.
// after finishing painting on top of the rendered image 
// one can use Morfit_engine_copy_image_from_dc_to_screen() to draw the finished image on the
// window
MORFIT_IMPORT HBITMAP  MORFIT_WINAPI Morfit_engine_render_on_bitmap(HWND hwnd, DWORD camera_handle);



//This function is very important. It allows painting and writing over the rendered image
//The function is exactly like Morfit_engine_render() only that it doesnt write the
//rendered image into the screen, instead the image is left on the device context ( dc )
//If you dont know what is a Device Context then dont bother about it
//just think of it as a handle that many WIN32 graphic functions get.
//The beauty of this technique that one can use all the many Windows function
// (GDI functions). Please be aware that Windows graphics function are
// some time quite slow.
// After finishing painting on top of the rendered image 
// use Morfit_engine_copy_image_from_dc_to_screen() to draw the finished image on the
// window
//
//Here is a sample how to use Morfit_engine_render_on_dc()
//
//		HDC dc=Morfit_engine_render_on_dc(NULL,camera);	
//
//	    //paints a circle on the device context. 
//		//Note that ELlipse() is a Windows function (WIN32 API)
//		//Look in you compiler help for information about that function.
//		//There are many other function that you can use for writing tect changing
//      //colors, changing the fill pattern etc ...
//		Ellipse(dc, 100,100,200,200);
//		//paint another circle
//		Ellipse(dc, 220,220,320,320);
//		
//		//Get the picture on the screen. Without calling this function you
//      //wont see anything.
//		Morfit_engine_copy_image_from_dc_to_screen();
//		
//		//Note that Morfit_engine_copy_image_from_dc_to_screen()
//		//releases dc (the device context) so
//		//after calling it one cant use dc any more.
//		//a new valid dc will be obtain when we repeat it in a loop
//		// dc=Morfit_engine_render_on_dc();	
//
// For drawing a wire frame lines around polygons note the function Morfit_engine_3D_edge_to_2D()
//
MORFIT_IMPORT HDC MORFIT_WINAPI Morfit_engine_render_on_dc(HWND hwnd, DWORD camera_handle);

//obsolete. Completely identical (Physically the same) to Morfit_engine_render_on_dc()
MORFIT_IMPORT HDC MORFIT_WINAPI Morfit_engine_render_on_memCDC(HWND hwnd, DWORD camera_handle);

// returns one of the four
// EDGE_NOT_SEEN if the edge is outside the rendering window
//					in this case p1_2D and p2_2D are not valid
// EDGE_FULLY_SEEN if the edge is fully inside the rendering window
//					in this case p1_2D and p2_2D are the desired result

// EDGE_PARTIALLY_SEEN if some of the edge is inside the window
//					in this case p1_2D and p2_2D are the portion that inside the rendering area

// VR_ERROR an error occurred 
//					in this case p1_2D and p2_2D are not valid
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_3D_edge_to_2D(double p1[3], double p2[3], int p1_2D[2], int p2_2D[2]);


// returns one of the four
// EDGE_NOT_SEEN if the edge is outside the rendering window
//					in this case p1,p2 == clipped_p1,clipped_p2

// EDGE_FULLY_SEEN if the edge is fully inside the rendering window
//					in this case p1,p2 == clipped_p1,clipped_p2

// EDGE_PARTIALLY_SEEN if some of the edge is inside the window
//					in this case clipped_p1,clipped_p2 is the seen part

// VR_ERROR an error occurred 
//					in this case clipped_p1,clipped_p2 are not valid

MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_clip_edge(double p1[3], double p2[3], double clipped_p1[3], double clipped_p2[3]);


//polygons not included in this group wont be rendered
// if it is NULL all the polygons will be rendered
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_group_to_render(DWORD grp_to_render_handle);


// -- bitmaps stuff
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_number_of_loaded_bitmaps(void);

// return the number of bitmaps that were unloaded
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_unload_unused_bitmaps(void);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_unload_all_bitmaps(void);

//Obsolete. Please use Morfit_engine_translate_movement_on_screen_to_world()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_translate_movement_on_screen_to_movement_in_world(double p3D[3], double result_p3D[3], int delta_x, int delta_y);

// p3D is a point in the world.
// delta_x, delta_y is the desired change in the location on
// the screen of the projection of p3D.
// result_p3D is a location that if p3D will move to this location
// its projection on the render image will move delta_x pixels right
// and delta_y pixels down (negative gives an opposite direction)
// returns OK or VR_ERROR.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_translate_movement_on_screen_to_world(double p3D[3], double result_p3D[3], int delta_x, int delta_y);


// The function returns the color depth (of the graphic mode) that was before
// Morfit.dll was loaded. 
//When the dll is being loaded it changes the color depth of the desktop to 16 bit (if not 16 bit already).
// Possible return values are:
//  0  When DirectX is not installed it will always return 0
//		this means that the color depth wasnt changed by the Morfit dll.
//	4 (for 16 color mode)
//  8 (for 256 color mode)
//  16 (16bit color mode == 65536 colors)
//  24 ( RGB 8-8-8 mode )
//  32 (32bit color mode )
//
// Note also that the dll will change the color to 16bit rgb automatically only if DirectX was installed on the computer
// or if the OS is Windows98 or above
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_original_color_depth(void);

// gets YES or NO. YES will move the objects automatically each
// time we do Morfit_engine_render(). The movement is according
// to the instructions in the wld file (CHASE ... ) or as was set in real-time.
// The default is YES.
// See also Morfit_camera_advance_all()
// and Morfit_object_advance_all()
// Note works only in viewer mode (viewer mode is the default mode)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_advance_objects_automatically(int yes_no_flag);

// gets YES or NO. YES will move the cameras automatically each
// time we do Morfit_engine_render(). The movement is according
// to the instructions in the wld file (CHASE ... ) or as was set in real-time.
// The default is YES.
// See also Morfit_camera_advance_all()
// and Morfit_object_advance_all()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_advance_cameras_automatically(int yes_no_flag);



//This function doesn't  work in editor mode. When zbuffer is off
// get YES or NO. zbuffer is the name of the algorithm that is often used to solve
// the hidden surface removal problem. If NO is given the engine will use
// BSP algorithms (binary space partitions) the BSP algorithms are faster
// and more accurate most of the time. There are some cases where BSP algorithms will
// be less accurate. Try testing both methods and see which is better for your world.
// Note that using this function is equivalent to calling Morfit_engine_load_world()
// with (or without) the DONT_USE_ZBUFFER flag. Using this function makes it possible to change
// methods at run-time.
//The return value is OK or VR_ERROR (error if we try to do it in editor_mode)
// The default is zbuffer ON.
// example: Morfit_engine_use_zbuffer(YES);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_use_zbuffer(int yes_no_flag);


// returns YES or NO. YES if the zbuffer algorithm is used.
// see Morfit_engine_use_zbuffer() for more details.
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_engine_is_zbuffer(void);



// Returns an array of all the extensions supported by the engine.
// returns also in number_of_supported_formats the number of extensions supported.
// these are the extensions that can be used with Morfit_engine_load_world()
// and with Morfit_engine_save()
// Example of usage:
//		int num;
//		table=Morfit_engine_get_supported_extensions_array(&num);
//		for(int i=0; i<num; i++) MessageBox(table[i]);
//
// The strings that we will get are "wld", "mft", "raw", "x" and more depending  on the
// version of Morfit dll.
MORFIT_IMPORT char ** MORFIT_WINAPI Morfit_engine_get_supported_formats_extensions_array(int *number_of_supported_formats);

// Usage is exactly like Morfit_engine_get_supported_formats_extensions_array()
// The string that we will get is similar  to "Morfit's 3D worlds file format" for example.
MORFIT_IMPORT char ** MORFIT_WINAPI Morfit_engine_get_supported_formats_names_array(int *number_of_supported_formats);

// a value of 0 will make rendering as fast as possible but 
// perspective correction will be at its lowest level (try it out and see if the lake of accuracy influence your world)
// a value of one is the default. values less than one will make rendering faster (but less accurate)
// values bigger than one will make rendering slower but more accurate.
// normally you wouldnt find values bigger than 3 useful.
// the value 1000 has a special meaning it will make perspective correction
// 100% correct. This of course will make rendering very very slow,
// use this value for pause mode or for screen capturing or when ever speed
// is not important at all.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_perspective_correction_accuracy(double value);

// see Morfit_engine_set_perspective_correction_accuracy() for more details
MORFIT_IMPORT double MORFIT_WINAPI Morfit_engine_get_perspective_correction_accuracy(void);


// === Performances Querying  ====== //

// Measure the time between two consecutive calls to render.
//returns the time in milliseconds.
// Morfit_engine_render() must be called at least twice before this
// function can be used (if not it will return 0) 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_average_program_cycle_time(void);


// Measure the time between two consecutive calls to render.
//returns the time in milliseconds.
// Morfit_engine_render() must be called at least twice before this
// function can be use (if not it will return 0) 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_last_program_cycle_time(void);

// Returns the execution time (in milliseconds) of the last call to Morfit_engine_render().
// Through this number one can calculate the current fps (frames per second)
// t=Morfit_engine_get_last_render_execution_time()
// if (t==0) return(0); //Morfit_engine_render() wasnt called even once. protect against division by zero
// fps=1000/t;
// see also Morfit_engine_get_average_render_execution_time()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_last_render_execution_time(void);

// Returns the average execution time (in milliseconds) of Morfit_engine_render().
// Through this number one can calculate the average fps (frames per second)
// t=Morfit_engine_get_average_render_execution_time()
// if (t==0) return(0); //Morfit_engine_render() wasnt called even once. protect against division by zero
// fps=1000/t;
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_get_average_render_execution_time(void);

// Obsolete. Use the 3D_card API instead (Morfit_3D_card....)
// return YES or NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_check_3d_hardware_support(void);

// Obsolete. Use the 3D_card API instead (Morfit_3D_card....)
// Get YES or NO. Returns OK or VR_ERROR
// If gets YES, the function will look for a 3D card installed on the computer
// if it wont find, the function will return VR_ERROR.
// It is a good practice to call Morfit_engine_use_3D_accelerator_card(NO);
//before you exit your application.
// The default is NO.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_use_3D_accelerator_card(int YES_or_NO);

// Obsolete. Use the 3D_card API instead (Morfit_3D_card....)
//example:
//	if(Morfit_engine_set_3D_accelerator_resolution(800, 600)==VR_ERROR) return(VR_ERROR);
//	if(Morfit_engine_use_3D_accelerator_card(YES)==VR_ERROR) return(VR_ERROR);
//
//	The default is 640x480
//	Note that if the card doesnt support this resolution, it will set the closest
//  resolution to the given one. You can call Morfit_engine_get_3D_accelerator_resolution()
//	to check what was actually set.
//	Returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_set_3D_accelerator_resolution(int width, int height);

// Obsolete. Use the 3D_card API instead (Morfit_3D_card....)
//Returns the current setting for the 3D accelerator card.
//example:
// int res_x, res_y;
// Morfit_engine_get_3D_accelerator_resolution(&res_x,&res_y);
// output_message("The current resolution setting for 3D hardware is %d X %d \n",res_x,res_y);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_get_3D_accelerator_resolution(int *width, int *height);

// Obsolete. Use the 3D_card API instead (Morfit_3D_card....)
//Returns YES if a 3D accelerator card is in use.
//Returns NO if software rendering is used.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_is_3D_accelerator_card_used(void);

// Using this function one can build an application that
// scan a map from the atlas and build a 3D world from it
// the 3D world can be 100% accurate (but never more accurate than
// the map itself ...)
// The function takes a regular window bitmap (in 256 color format or 24bit per pixel RGB format)
// painted with gray scales and convert it into a 3d model. The 3d model is built according
// to the colors of the bitmap the more white it is the higher it is.
// (the peaks of the mountains will be much brighter than the valleys in the bitmap)
//Input params:
// bitmap_file_name:
//		The name of the bitmap that according to its colors the model is built
//		The bitmap must be in 24 bit rgb format or 8 bit per pixel format (256 colors).
//		The colors of the bitmap should be in gray scale (not a must) since
//		the function calculates height according to their brightness (sqrt (red^2 + green^2 + blue^2)  Never mind if you dont understand the calculation)
//		The bitmap could be in any size.
//		examples: "my_bitmap.bmp" ; "c:\\gs_maps\\France.bmp" ; "..\\rgb24maps\\Jerusalem.map" etc ...
//
// level_of_optimization:
//		This number is responsible to the polygon reduction level.
//		A number in the range [0 - 3000]
//		The bigger the number is the stronger the optimization
//		0 means that there is no optimization so the number of polygon in the output file
//		will be as set by the argument max_number_of_polygons
//		3000 will make such a strong optimization that the model
//		will be simplified to one flat polygon no matter what source bitmap we had !
//		common numbers that you might try are
//		0.1 , 1, 10 ,100 ,200 ,400
//		Use a big numbers if it is important to reduce as many as possible polygons
//		Use small number if the terrain model must be very detailed.
//
//  max_number_of_polygons:
//		A big number makes a very detailed object
//		a small number makes a model with less polygons
//		so it can be rendered fast in real-time
//		Try 2000 to begin with and if you need more details increase this number
//		if on the other hand you need more speed when rendering, use a smaller number
//
//  bitmap_to_wrap_over_handle:
//		This is a handle to the bitmap that will be used to paint the created model
//		for example this bitmap could be a texture of rocks, sand snow , grass etc ...
//		If a NULL is given, then the model will be painted according to the given legend.
//		You get the handle for the bitmap using Morfit_bitmap_load()
//		Note that if you want the bitmap to repeat more than once on the model (tile mode)
//		then the dimensions of the bitmap must be in the power of two (for example 32,64,128,256,512,1024,2048 etc ... 
//		all these numbers are powers of two).
//		see also Morfit_group_wrap_a_bitmap()
//
//  tile_x, tile_y:
//		The numbers of time that the tile of the bitmap is to repeat itself
//		These numbers are only relevant if bitmap_to_wrap_over_handle
//		is not NULL.
//		examples: 1,1 (no tile) ; 4,4 (bitmap will repeat 16 times) ; 7,3 ; 712,1095 etc ...
//
//	legend, number_of_colors_in_legend:
//		If bitmap_to_wrap_over_handle is NULL, then
//		The created model is painted according to the given legend.
//		legend is an array of RGB colors. If for example we give
//		three colors then the first color will be the color of the bottom
//		third of the model. The second color will be the middle color.
//		the last color will be the color of the top third.
//		If NULL is given (instead of the legend array) then the
//		model is colored according to the default legend.
//		number_of_colors_in_legend is of course the number of colors that
//		the given legend array contains.
//		example: 
//			BYTE my_legend[2][3]={0,255,0,  255,255,255};
//			Here we define two colors. 0,255,0 is green.
//			255,255,255 is white. This would cause the bottom half
//			to be painted with green colors and the top half with white hues
//
//	dimensions:
//		The created model is built so its center is in the origin ( point 0,0,0 )
//		and its width is dimension[0], its length is dimension[1] and its height is dimension[2]
//		Note that if for example dimension[2]==100 (the height of the model)
//		then the model will be built from -50 to +50 (remember that the center is in the origin ...)
//		Chose the number according to the source map.
//		If for example it was a map of Israel then you should give the following dimensions
//		dimension[0]=60 (The width of Israel is 60 Km) (quit small isn't it ?)
//		dimension[1]=300 (The length of Israel is 300 Km)
//		dimension[2]=2 (The difference between the tallest mountain to the lowest place is 2 Km)
//
//	number_of_polygons_in_group:
//		This value is set by the function so it doesn't have to be initialized.
//		When the function returns it contains the number of polygons in the created model
//		This parameter is updated during the time that the function runs and can be
//		accessed by a different process to get an idea on the the function progress
//		This parameter can be used to estimate how much time the function would take
//		If it is not one of your concerns just give NULL.
//		This function can take a lot of time (if we have a huge max_number_of_polygons for example 100000)
//		so you might like to run it in a different process ,while showing
//		a progress bar. Send a pointer to a global variable
//		so that you can read its value outside the process.
//		Though it is not known in advance how much time it takes, this number give some ideas
//		at first this number will be equal to max_number_of_polygons and it will go down by one when ever
//		a polygon is reduced. Till what number it gets to depends on level_of_optimization and
//		the source bitmap itself (If the map is flatter it will be possible to reduce more polygons and vice versa)
//
// Return Value:
//		On failure returns NULL
//		On success returns a handle to the created group
//
//	Example: 
//		double dimensions[3]={20000,20000,6000};
//		DWORD terrain_group=Morfit_engine_create_terrain_from_bitmap("map.bmp", 100, 3200, NULL,1,1,NULL, 0,dimensions,NULL);
//		double step[3]={0,0,-3500};
//		Morfit_group_move(terrain_group, step, WORLD_SPACE);
//		Morfit_camera_set_location(Morfit_camera_get_default_camera(),0,0,0);
//		Morfit_camera_set_direction(Morfit_camera_get_default_camera(),-1,0,0);
//
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_engine_create_terrain_from_bitmap(char *bitmap_file_name, double level_of_optimization, int max_number_of_polygons, DWORD bitmap_to_wrap_over_handle, int tile_x, int tile_y, BYTE legend [][3], int number_of_colors_in_legend,double dimensions[3], int *number_of_polygons_in_group);

//If one of Morfit's functions fails, then one can use this
//function to retrieve a string describing the error
//This is the same string that appears in the Morfit.log file
MORFIT_IMPORT char *MORFIT_WINAPI Morfit_engine_get_last_error(void);

//If we want that the speed of a certain operation will be equal on all computers
//then we can use this function.
//For example say we want to move an object by 100 units each render
//Then we should write something like that:
//  factor=Morfit_engine_computer_speed_factor();
//  corrected_number= 100*factor;
//  move_my_object(corrected_number);
//
// Note:
// 1- The return value of this function is constantly changing to reflect
//	  changes in the CPU load. This means you have to call the function each
//	  time before you use it (dont call it once and then use the same value over and over ...). 
//  
// 2- If your object is moved automatically on a track then
//	  you dont have to worry at all because the engine takes care of it. 
//
// See also: Morfit_object_get_speed_units() ,Morfit_object_set_speed_units()
MORFIT_IMPORT double MORFIT_WINAPI Morfit_engine_get_computer_speed_factor(void);

//When the engine detect an error he makes a beep using the PC loudspeaker
//and writes some words about it to the morfit.log file (also to error.log)
//Usually you should take care of all the errors and the warnings if
//you didnt, you can use this function to shut down the noise from the speaker.
//Note that the error messages will still be outputted to the morfit.log and error.lof files
//The default value is YES
//Example: Morfit_engine_set_speaker_mode(NO);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_speaker_mode(int yes_no_flag);

// This function is everything you'll need to create lighs and shadows
// The function creates and adds new polygons which are the shadow of "entity_creating_shadow"
// on "entity_receiving_shadow" according to the given light source location. 
// Those new added polygons are called patches. 
// entity_receiving_shadow and entity_creating_shadow could be handles to any one of the following
// types POLYGON, OBJECT or GROUP. If a NULL is given the function would treat it as a handle to group
// a(note that a NULL group means the whole world)
// Note that the new added polygons get the same properties
// of the "entity_creating_shadow" (i.e. the same bitmap, the same translucent etc ...)
// Usually you would like to change those properties. For example:
// 
//		double light[3]={0,0,200}
//		Morfit_engine_create_shadow(room_group, chair_group, light, 255);
//		//setting the color of the shadows. Note that by changing the color
//		//you can simulate changes in light intensity
//		Morfit_group_set_patches_color(room_group, 70,70,70, ALL_PATCHES); 
//
// If we dont call Morfit_group_set_patches_color() we wont get a dark shadow on the room floor
// instead we will get the shape of the shadow but with the colors and bitmaps of the chair.
// Note that the last argument in the call to Morfit_engine_create_shadow() is called serial_number
// serial_number is a number in the range [10 - 255]
// The number is relevant only if we will call 
// Morfit_group_set_patches_color(..., serial_number)
// and the function Morfit_group_set_patches_bitmap(..., serial_number)
// This will allow us to have a room with several shadows and to change only one of them.
// 
// Use Morfit_polygon_delete_patches() to remove the shadow
// For example: Morfit_polygon_delete_patches(room_handle, ALL_PATCHES) will
// delete all the shadows in the room while Morfit_polygon_delete_patches(room_handle, 255) will
// delete just the shadows that were created with serial number 255.
//
// Performance note:
//		If you create the shadow in real time and you want it to be fast
//		then call this function with polygon handles. for example
//		Morfit_engine_create_shadow(polygon_to_get_shadow, polygon_obscaring_light, light, 255);
//
// Note that function like Morfit_polygon_add_patch_easy() are also creating patches though for
// different purposes.
//
// Examples:
// A)
//		double light[3]={100,200,300}
//		Morfit_engine_create_shadow(wall_polygon, blocking_polygon, light, 255);
// 
//
// Example B:
// while(user did not press ESC) {
//		Morfit_polygon_delete_patches(wall_polygon, ALL_PATCHES);
//		light[0]+=10; //move the light source
//		Morfit_engine_create_shadow(wall_polygon, blocking_polygon, light, 255);		
//		Morfit_polygon_set_bitmap_fill(shadow_polygon_handle, flare_bitmap);
//		Morfit_polygon_set_translucent(shadow_polygon_handle, NORMAL_GLASS);
// }
//
// See also: Morfit_engine_create_dynamic_shadow(),
// Morfit_polygon_delete_patches(), 
// Morfit_polygon_delete_patches(),
// Morfit_group_delete_patches(), Morfit_group_set_patches_translucent(), 
// Morfit_group_set_color(), Morfit_group_set_patches_bitmap()
// Morfit_polygon_add_patch_easy().
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_create_shadow(DWORD entity_receiving_shadow, DWORD entity_creating_shadow, double light_src[3], BYTE serial_number);

// Exactly like Morfit_engine_create_shadow() only that it is faster
// The disadvantage is that dynamic shadows can only be deleted with
// Morfit_engine_delete_dynamic_shadows() which delete all the existing dynamic shadow.
// (Morfit_group_delete_patches() wont work here)
// We suggest that you use this function to create shadows that can be changed from
// one render to another. For example in our world we might have several source
// of lights some of them will be moving and some are fixed. We could also have some moving objects
// in our world (so their shadow is moving too). The shadow that is created
// from the fixed light sources and by the fixed object can be created only once at the beginning of
// the program. To create the fixed shadows use Morfit_engine_create_shadow()
// The shadows that are created by the moving light sources or from the moving objects will have to be
// deleted and recreated for each render cycle. Use Morfit_engine_create_dynamic_shadow()
// to create them. To delete them use Morfit_engine_delete_dynamic_shadows().
// Here is an example:
// 
//		//creating the static shadow. Create the shadow that the trees project on the ground 
//		double sun[3]={10000, 10000, 30000};
//		Morfit_engine_create_shadow(ground, trees, sun, 255);
//		while(Escape key is not pressed) {
//			Morfit_engine_delete_dynamic_shadows();
//			move_our_ball(ball);
//			Morfit_engine_create_dynamic_shadow(ground, ball, light_source);
//			Morfit_engine_render(NULL, camera);
//		}
//		
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_create_dynamic_shadow(DWORD entity_receiving_shadow, DWORD entity_creating_shadow, double light_src[3], BYTE serial_number);

// Deletes all the existing dynamic shadow. Dynamic shadow is created using
// the function Morfit_engine_create_dynamic_shadow()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_delete_dynamic_shadows(void);


//When rendering takes more than the specified time then the rendering function will exit automatically
//This is very useful when rendering indoor worlds. The engine renders front to back
// so it is usually enough to stop rendering after finishing with the current room.
// Try playing with different values and see the result.
//The default is 1000000 (which is about 17 minutes which is similar to "take all the time in the world to finish every rendering")
//Typical values would be 200,100,50
// Note that this function is only relevant in Viewer Mode (Viewer Mode is the the default mode)
//Example: Morfit_engine_set_maximum_rendering_time(100); //Set minimum frames per seconds to 10
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_maximum_rendering_time(int max_duration_in_mili_seconds);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_maximum_rendering_time(void);

//Sets a minimum time for each render. If Morfit_engine_render() take less time
//than the specified time then the engine will wait (Doing Sleep() ) till it reaches the given
// duration.
// Why should you use this function ? Sometimes when you get to the end of your world
// The engine has only few polygons to render in this case it can get to 1000 frames per seconds and more !!!
// If you are moving a car by X units every render then your car is going to become
// a rocket when you reach the end of the world ...
// The default is 2. This permits a maximum of 500 frames per seconds
// Note also the function Morfit_engine_get_computer_speed_factor()
//Example: Morfit_engine_set_minimum_rendering_time(0);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_minimum_rendering_time(int min_duration_in_mili_seconds);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_engine_get_minimum_rendering_time(void);


//Controls the amount of CPU time that the rendering process gets.
//Usually you would like to have the fastest graphics possible
//though sometime when a few application are working in conjunction
//there is need to release some CPU time for the benefit of the others.
// parameters:
//		thread_priority: (For more details please see the win32 function SetThreadPriority() )
//
//			THREAD_PRIORITY_ABOVE_NORMAL 
//				Indicates 1 point above normal priority for the priority class. 
//			THREAD_PRIORITY_BELOW_NORMAL Indicates 
//				1 point below normal priority for the priority class. 
//			THREAD_PRIORITY_HIGHEST 
//				Indicates 2 points above normal priority for the priority class. 
//			THREAD_PRIORITY_IDLE 
//				Indicates a base priority level of 1 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 16 for REALTIME_PRIORITY_CLASS processes. 
//			THREAD_PRIORITY_LOWEST 
//				Indicates 2 points below normal priority for the priority class. 
//			THREAD_PRIORITY_NORMAL 
//				Indicates normal priority for the priority class. 
//			THREAD_PRIORITY_TIME_CRITICAL 
//				Indicates a base priority level of 15 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 31 for REALTIME_PRIORITY_CLASS processes. 
//
//		Class priorities: ( For more details please see the win32 function SetPriorityClass() )
//
//			HIGH_PRIORITY_CLASS 
//				Specify this class for a process that performs time-critical tasks that must be executed immediately. The threads of the process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class application can use nearly all available CPU time. 
//			IDLE_PRIORITY_CLASS 
//				Specify this class for a process whose threads run only when the system is idle. The threads of the process are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle-priority class is inherited by child processes. 
//			NORMAL_PRIORITY_CLASS 
//				Specify this class for a process with no special scheduling needs. 
//			REALTIME_PRIORITY_CLASS 
//				Specify this class for a process that has the highest possible priority. The threads of the process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive. 
//Examples:
// A)
//		Setting High priority (The default)
//		Morfit_engine_set_thread_priority(THREAD_PRIORITY_HIGHEST, HIGH_PRIORITY_CLASS);
//
// B)
//		Setting the fastest rendering possible
//		Morfit_engine_set_thread_priority(THREAD_PRIORITY_TIME_CRITICAL, REALTIME_PRIORITY_CLASS);
//
// For more details please see the win32 functions SetPriorityClass() and SetThreadPriority()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_set_thread_priority(int thread_priority, DWORD class_priority);

//This function must be called when before your program exits.
//Not calling this function at the end of your program might 
//cause your program not to exit cleanly (Crashing at the end)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_engine_close(void);


//Returns Morfit's logo
MORFIT_IMPORT HBITMAP MORFIT_WINAPI Morfit_engine_get_logo(void);


//--------------------------------------------------------//
//=========== T H E    C A M E R A   A P I ===============//
//--------------------------------------------------------//

// This API	controls properties of the camera like
// zoom location direction etc...


MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_is_camera(DWORD camera_handle, char *function_asking);

// returns a handle to a camera.
// Used in conjunction with Morfit_camera_get_next_camera()
// to traverse all the existing cameras
// example:
//	for(handle=Morfit_camera_get_first_camera() ; handle!=NULL ; handle=Morfit_camera_get_next_camera(handle) )
//	{
//		... 
//
//	}
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_first_camera(void);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_next_camera(DWORD camera_handle);

// Checks if this is a handle to a camera
// Warn with a message box in the following cases:
// 1- The handle is a handle to a different type
// 2- The handle is NULL
// 3- The handle points to an Illegal memory address (the handle is garbage ...)
// returns YES or NO.
// function_name is a text that will appear in the message box title,
// The best is to give the function name so if you get the error you know
// what function should be fixed.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_is_camera(DWORD camera_handle, char *function_name);

// insensitive to upper / lower case  (it doesn't make a difference if it is a or A)
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_using_name(char *camera_name);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_camera_get_name(DWORD camera_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_name(DWORD camera_handle, char *name);

// the bigger this number is the more accurate will be 
// the rendering of the objects. In editor mode a bigger number
// will improve the accuracy of the whole rendering
// On the other hand a number too big will hide objects that are near
// the camera. Typical values are 1, 4, 10, 20 when distance in
// the world is measured  with centimeters.
// Try to make this number as big as you can. stop increasing this number
// when near objects or not drawn.
// return OK or VR_ERROR
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_distance_from_eye(DWORD camera_handle, double distance);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_distance_from_eye(DWORD camera_handle);


// Creates a camera and returns a handle to that camera
// Note that the values for the camera setting (location, direction , field view etc ...)
// are given default values. In probably all cases you
// would like to set those values yourself before you
// You use the camera specially the location and the direction
// given parameters
//----------------- 
//	camera_name: a string that identifies the camera. Usually this
//		string wont be in use since it is more efficient to
//		retrieve a camera using the handle (the return value of this
//		function).
// see also Morfit_camera_recreate() Morfit_camera_save()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_create(char *camera_name);

// returns the last camera that was used with Morfit_engine_render();
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_current(void);

// If you render only on one window at one time, you dont need this function,
// If however you render on more than one window in every rendering cycle
// you might need this function.
// Many operations like Morfit_engine_3D_point_to_2D() dont take
// a camera_handle as one of their parameters instead they do
// Morfit_camera_get_current() which returns the last camera that was
// rendered with. So if we wont to do one of those operations
// with a camera that is different from the last one used by Morfit_engine_render()
// we should call this function. This function is very quick so it is
// much much better to call it than to call Morfit_engine_render()
// hwnd is the window that we are using the camera with
// If you are using MFC do CWnd->m_hWnd
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_camera_set_current(DWORD camera_handle, HWND hwnd);

//MORFIT_IMPORT int  MORFIT_WINAPI Morfit_camera_set_current(DWORD camera_handle);


// Returns a handle to the first camera that was created.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_default_camera(void);


//save the current status of the given camera to the given buffer
// later a camera with the same status (location, direction, field_of_view etc ...)
// can be created using the given buffer.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_camera_save(DWORD camera_handle, DWORD save_buffer[CAMERA_DESCRIPTOR_SIZE]);

// creates a new camera and returns the handle to that camera
// The new camera status (location, direction, field_of_view etc ...) is
// set according to the data in restore_buffer.
// this buffer should be filled before calling this function
// using Morfit_camera_save(). This mechanism could be used to
// duplicate cameras. Another usage could be to send the buffer across
// the internet so that the same camera could be created on
// the far computer. see also Morfit_camera_create()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_recreate(char *camera_name, DWORD restore_buffer[CAMERA_DESCRIPTOR_SIZE]);

// The new camera status (location, direction, field_of_view etc ...) is
// set according to the data in "values_data" buffer.
// this buffer should be filled before calling this function
// using Morfit_camera_save().
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_values(DWORD camera_handle, DWORD values_data[CAMERA_DESCRIPTOR_SIZE]);

// return the width of the core image created on the camera film
// this value multiplied by the value return from Morfit_camera_get_height()
// indicates the quality of the picture that will be created
// you can modify the picture quality by using the following functions
// 1- Morfit_engine_set_picture_quality(int quality);
// 2- Morfit_engine_increase_picture_quality(void);
// 3- Morfit_engine_decrease_picture_quality(void);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_width(DWORD camera_handle);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_height(DWORD camera_handle);

// returns the new location in x,y,z
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_get_direction(DWORD camera_handle, double *x, double *y, double *z);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_direction(DWORD camera_handle, double x, double y, double z);

//gets a point\location in the world and make the camera point to this location
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_point_at(DWORD camera_handle, double x, double y, double z);

// gets a two dimensional point=> (x,y) is a point in the rendered window
// usually we get this point from the events like OnLButtonDown()
// the function calculates the corresponding three dimensional point
// in the world and sets the camera to point towards this point.
// If there is no corresponding 3D point then returns VR_ERROR
// (happens when we point to an empty place in the rendered image.
// see also Morfit_camera_point_at() and Morfit_engine_2D_point_to_3D();
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_point_at_2D(DWORD camera_handle, int x, int y);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_location(DWORD camera_handle, double x, double y, double z);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_get_location(DWORD camera_handle, double *x, double *y, double *z);

MORFIT_IMPORT int MORFIT_WINAPI  Morfit_camera_set_axis_system(DWORD camera_handle, double X[3], double Y[3], double Z[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_get_axis_system(DWORD camera_handle, double X[3], double Y[3], double Z[3]);



// Returns the new tilt angle
// examples:
// tilt 0 mean looking straight.
// tilt 90 looking up
// tilt -90 means looking down
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_set_tilt(DWORD camera_handle, double angle);

// Returns the new tilt angle
// examples:
// tilt 0 mean looking straight.
// tilt 90 looking up
// tilt -90 means looking down
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_tilt(DWORD camera_handle);


// Returns the new tilt angle
// examples:
// 90 means rotate camera 90 degrees up
// -90 means rotate camera 90 degrees down
// The rotation is done in world cords (rather then in object cords)
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_modify_tilt(DWORD camera_handle, double change);


// space_flag could be WORLD_SPACE or CAMERA_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_move(DWORD camera_handle, int space_flag, double x, double y, double z);


// Returns the new focus distance
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_set_focus(DWORD camera_handle, double focus_distance);


// Returns the new focus distance
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_modify_focus(DWORD camera_handle, double change_in_focus_distance);


// Returns the new field of view angle
// the field of view could be anything between 1 to 179 degrees
// field of view == 1 means a very strong zoom in 
// field of view == 179 means a very strong zoom out
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_set_zoom(DWORD camera_handle, double field_of_view_angle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_zoom(DWORD camera_handle);

// Returns the new field of view angle
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_modify_zoom(DWORD camera_handle, double field_of_view_change);



// Sets the new head angle (also the return value)
// examples:
// 0 means look forward into the screen
// 90 means look left
// -90 or 270 means look right
// 180 means camera looking from the screen out
// if we add or subtract 360*n to the angle it
// will be the same
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_set_head_angle(DWORD camera_handle, double head_angle);

// returns the new head angle
// examples:
// 0 means look forward into the screen
// 90 means look left
// -90 or 270 means look right
// 180 means camera looking from the screen out
// if we add or subtract 360*n to the angle it
// will be the same
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_head_angle(DWORD camera_handle);


// Returns the new head angle
// examples:
// 0 do nothing (can be use as get_current_head_angle() ...)
// 90 means turn 90 degrees counterclockwise
// 90 means turn 90 degrees clockwise.
// 180 means camera turns half a circle
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_modify_head_angle(DWORD camera_handle, double head_angle);


// Returns the new bank angle
// the angle is given in degrees from the horizon
// examples:
// 0 means looking straight.
// 90 means turned 90 degrees clockwise
// -90 means turned 90 degrees clockwise
// giving alfa +360*k (k= ... -5,-4 , .... 0, 1 ,2 ...)
// is the same as giving alfa
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_set_bank(DWORD camera_handle, double angle);

// Returns the new bank angle
// the angle is given in degrees from the horizon
// examples:
// 0 means looking straight.
// 90 means turned 90 degrees clockwise
// -90 means turned 90 degrees clockwise
// The return value is in the range -90 - 270
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_bank(DWORD camera_handle);

// Returns the new bank angle
// the angle is given in degrees from the horizon
// examples:
// 0 means looking straight.
// 90 means turned 90 degrees clockwise
// -90 means turned 90 degrees clockwise
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_modify_bank(DWORD camera_handle, double change);



// space flag can be OBJECT_SPACE or  WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_x(DWORD camera_handle, double degrees, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_y(DWORD camera_handle, double degrees, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_z(DWORD camera_handle, double degrees, int space_flag);

// The same just with radians.
// space flag can be OBJECT_SPACE or  WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_x_radians(DWORD camera_handle, double radians, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_y_radians(DWORD camera_handle, double radians, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_rotate_z_radians(DWORD camera_handle, double radians, int space_flag);

// returns OK or VR_ERROR if failed
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_convert_point_to_world_space(DWORD camera_handle, double camera_space_point[3], double result[3]);
// returns OK or VR_ERROR if failed
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_convert_point_to_camera_space(DWORD camera_handle, double world_space_point[3], double result[3]);

// deletes a camera.
// remember not to use any handle after the instance was deleted
// doing:
//	Morfit_camera_delete(my_camera);
//	my_camera=NULL;
// is good practice.
// returns OK or VR_ERROR 
// VR_ERROR could be receive if there is no more camera with this handle
// (if we already deleted the camera before)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_delete(DWORD camera_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_delete_all(void);


// *************************

MORFIT_IMPORT char * MORFIT_WINAPI  Morfit_camera_get_track_name(DWORD camera_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_track_handle(DWORD camera_handle);

// returns VR_ERROR, OK
// if track_handle ==NULL it doesn't cancel the chase type so
// for canceling chasing use Morfit_camera_set_chase_type(NO_CHASE);
// Automatically set the closest point on the track (closest to the object)
// as the next point to go towards (to override this setting use Morfit_camera_set_next_point_on_track() )
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_set_track(DWORD camera_handle, DWORD track_handle);


// return OK or VR_ERROR
// the offset is return through argument "offset"
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_track_offset(DWORD camera_handle, double offset[3]);

// return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_set_track_offset(DWORD camera_handle, double offset[3]);


// returns an index to a point on the track. This point is the point that the camera is moving towards
// The exact cords of the point can be retrieved through Morfit_track_get_point()
// 0 is the first point and number_of_points-1 is the last index (use Morfit_track_get_number_of_points() to get this number
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_next_point_on_track(DWORD camera_handle);

// returns the point on the track that the camera is moving towards
// 0 is the first point and number_of_points-1 is the last index (use Morfit_track_get_number_of_points() to get this number
// if point_index<0 then it set it to 0
// if point_index is bigger than the maximum index then it is set to the maximum allowed. In those cases it returns VR_ERROR 
// to notify the change from the given value.
// If there is no track associated with the camera it returns VR_ERROR without setting the value
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_set_next_point_on_track(DWORD camera_handle, int point_index);

// Set the object to chase after
// the given arguments should NOT be NULL
// Note that if the camera was previously chasing a camera or a group
// , those chasing operation are canceled. (The camera can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_object_to_chase(DWORD camera_handle, DWORD object_to_chase_handle);

// If the return value is NULL it means no object is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_chased_object(DWORD camera_handle);


// Set the camera to chase after
// the given argument should NOT be NULL
// Note that if the camera was previously chasing an object or a group
// , those chasing operation are canceled. (The camera can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_camera_to_chase(DWORD camera_handle, DWORD camera_to_chase_handle);

// If the return value is NULL it means no camera is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_chased_camera(DWORD camera_handle);

// Set the group to chase after
// the given argument should NOT be NULL
// Note that if the camera was previously chasing a camera or an object
// , those chasing operation are canceled. (The camera can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_group_to_chase(DWORD camera_handle, DWORD group_to_chase_handle);

// If the return value is NULL it means no group is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_camera_get_chased_group(DWORD camera_handle);

// return OK or VR_ERROR
// the offset is return through argument "offset"
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_chase_offset(DWORD camera_handle, double offset[3]);

// return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_set_chase_offset(DWORD camera_handle, double offset[3]);

// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_chase_softness(DWORD camera_handle);

// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
// it the given number is bigger than one it is set as one
// if it is smaller than 0 than it set as 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_chase_softness(DWORD camera_handle, double softness);

// look in the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_chase_type(DWORD camera_handle);

// look in the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_chase_type(DWORD camera_handle, int chase_type);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_chase_distance(DWORD camera_handle, double chase_distance);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_chase_distance(DWORD camera_handle);

// ************************

// Advance the object on the track according to its
// track, track_speed, track_offset, chase_offset, target_point_on_track and chasing softness
// Use Morfit_camera_advance() instead (set the right chase type before calling ...)
// XXXX MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_advance_on_track(DWORD camera_handle);

// Advance the camera according to its chase_type
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_advance(DWORD camera_handle);


// Function for PHYSICS
//PHYSICS: SPEED: 0 0 0 FORCE: 0 0 0 MAX_SPEED: 0 FRICTION: 0 ELASTICITY: 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_get_speed(DWORD camera_handle, double speed[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_speed(DWORD camera_handle, double speed[3]);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_absolute_speed(DWORD camera_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_absolute_speed(DWORD camera_handle, double speed);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_get_force(DWORD camera_handle, double force[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_force(DWORD camera_handle, double force[3]);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_max_speed(DWORD camera_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_friction(DWORD camera_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_camera_get_elasticity(DWORD camera_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_max_speed(DWORD camera_handle, double value);

//Friction is a value smaller or equal to 1
// if friction==0 it means no friction
// if friction==1 it means infinite friction nothing can move
// if friction is smaller than 0, it acts like pressing on the gas
// The exact calculation.
// Each render the absolute_speed is multiply with (1-friction).
//
// Note, a negative number can used for increasing the speed.
// a friction of -1 will double the speed.
// -2 will multiply the speed by three each rendering.
// so choose number carefully.
// typical numbers can be 0.03 or -0.03 etc ...
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_friction(DWORD camera_handle, double value);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_elasticity(DWORD camera_handle, double value);

// (left_x, top_y) and (right_x ,bottom_y) are points on the window that
// was used to render an image using the given camera.
// The function returns through new_location a location that if we would
// do Morfit_camera_set_location() the rectangle area will fill our screen
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_location_to_fit_rectangle(DWORD camera_handle, int left_x, int top_y, int right_x, int bottom_y, double new_location[3]);


// x,y are points on the window
// usually we get this point from events like OnLButtonDown()
// The function moves the camera towards the point (or far from the point depending 
// on the given value, factor).
// Note that the direction of the camera doesn't change. (Use Morfit_camera_point_at() to make the target point at the center)
// returns OK, VR_ERRORR.
// factor can be any number. Here are some examples:
// factor== -2 , the camera will triple its distance from the given point
// factor== -1 , the camera will double its distance from the given point
// factor==0 means, the camera wont move
// factor==0.5 the camera will move half way to the point
// factor==1 the camera will move to the given point x,y
// factor==2 the camera will pass the point (will be in the same distance but on the other side of the line that connects the point and the line).
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_move_toward_point_2D(DWORD camera_handle, int x, int y, double factor);

// advance all the cameras. If Morfit_engine_advance_cameras_automatically(YES) is called
// then this function will be called automatically each time we do render
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_advance_all();

MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_name_to_chase(DWORD camera_handle, char *name_to_chase);

MORFIT_IMPORT char * MORFIT_WINAPI Morfit_camera_get_name_to_chase(DWORD camera_handle);

// sending YES will write the given camera to file after call to Morfit_engine_save() with SAVE_ONLY_WHATS_NEEDED 
// Note that it if Morfit_engine_save() is called without SAVE_ONLY_WHATS_NEEDED, all the tracks will be saved
// sending NO will cause  Morfit_engine_save() not to save this camera (only if SAVE_ONLY_WHATS_NEEDED is used)
// The default value is NO
// see also Morfit_animation_set_save_flag()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_save_flag(DWORD camera_handle, int yes_no_flag); 

// returns YES or NO
// The default value is NO
// see Morfit_camera_set_save_flag() for more details
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_save_flag(DWORD camera_handle); 

//
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_perspective_projection(DWORD camera_handle); 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_camera_set_parallel_projection(DWORD camera_handle, int width, int heigh); 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_is_perspective_projection(DWORD camera_handle); 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_parallel_projection_width(DWORD camera_handle);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_camera_get_parallel_projection_height(DWORD camera_handle);



//-----------------------------------------------------//
//======== T H E    O B J E C T    A P I ==============//
//-----------------------------------------------------//

// This API is used in viewer_mode to manipulate moving objects
// See also the GROUP API for manipulating things in EDITOR mode.
// Note that some of group API are also working in viewer mode
// (those that do not move polygons or change them) but not the other way around.


// Returns YES or NO.
// YES , if the given handle is an object handle. NO if not.
// If it is not an object handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_OBJECT()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_object(DWORD object_handle, char *function_asking);


// if movement possible returns YES else returns NO
// If movement is not possible it returns the plane equation Ax+By+Cz+D=0
// and the intersection point.
// Note that the normal of the blocking surface is N=( plane[0], plane[1], plane[2])
// on return blocking_object is the object that make movement impossible
// if the return value is NO and blocking_object==NULL it means
// that what blocks us is the static part of the world.
// the difference between this function end Morfit_engine_is_movement_possible()
// is that here we also give the handle to the dynamic object that wants to move
// this handle is needed so that the function can eliminate the object itself
// from being  the obstacle that makes the movement impossible.
// see also remarks on Morfit_engine_is_movement_possible()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_movement_possible(DWORD object_handle ,double start_location[3], double end_location[3], DWORD *intersected_polygon, double intersection[3], DWORD *blocking_object);



// If no dynamic object has this name then it
// returns a NULL
// If there are several objects with the same name then 
// it returns the first one. 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_object_using_name(char *object_name);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_object_get_name(DWORD object_handle);
MORFIT_IMPORT int   MORFIT_WINAPI MorfitVB_object_get_name(DWORD object_handle, char *name);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_object_get_type_name(DWORD object_handle);

// returns OK if was successful else VR_ERROR;
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_name(DWORD object_handle, char *new_name);

// returns OK if was successful else VR_ERROR;
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_type_name(DWORD object_handle, char *new_name);


MORFIT_IMPORT int  MORFIT_WINAPI Morfit_object_get_object_type_number(DWORD object_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_object_type_number(DWORD object_handle, int object_type_number);

MORFIT_IMPORT int  MORFIT_WINAPI Morfit_object_get_control_type_number(DWORD object_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_control_type_number(DWORD object_handle, int control_type_number);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_object_get_track_name(DWORD object_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_track_handle(DWORD object_handle);


// returns a handle to an object.
// Used in conjunction with Morfit_object_get_next_object()
// to traverse all the existing objects
// example:
//	for(handle=Morfit_object_get_first_object() ; handle!=NULL ; handle=Morfit_object_get_next_object(handle) )
//	{
//		... 
//
//	}
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_first_object(void);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_next_object(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_location(DWORD object_handle, double x, double y, double z);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_location(DWORD object_handle, double *x, double *y, double *z);
// space_flag could be WORLD_SPACE or OBJECT_SPACE or CAMERA_SPACE
// Advance the object (move relative)
// space_flag determines if the step is according to the objects
// coordinate system or the world coordinate  system etc ...
// for example if space_flag==OBJECT_SPACE and step==(-1,0,0)
// This means that the object will advance forward (If it is a car than
// forward is the direction of the front window).
// Try both option and see what happens.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_move(DWORD object_handle, int space_flag, double x, double y, double z);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_direction(DWORD object_handle, double x, double y, double z);
// returns the new location in x,y,z
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_direction(DWORD object_handle, double *x, double *y, double *z);



// rotates the object so that the orientation of the object matches the given directions
// returns OK or VR_ERROR
// one of the direction can be 0,0,0 in this case it is calculated automatically.
// If the given axis are not orthogonal, the function 
// handle it by building an orthogonal system that is close as possible
// to the given axis.
// Here are some examples, note that
// all the examples give the same result.
// Example A:
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0; 
//	y_axis[0]=-1; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=1; 
//	Morfit_object_set_axis_system(x_axis, y_axis, z_axis);
//
// Example B:
//	//Example B would give exactly the same result as example A
//	x_axis[0]=0; x_axis[1]=111; x_axis[2]=0; 
//	y_axis[0]=-17; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=12; 
//	Morfit_object_set_axis_system(x_axis, y_axis, z_axis);
//
// Example C:
//	//Note that  z_axis=(0,0,0) and will be automatically 
//  // calculated by the function
//	//Example C would give exactly the same result as example A and B
//	x_axis[0]=0; x_axis[1]=111; x_axis[2]=0; 
//	y_axis[0]=-17; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=0; 
//	Morfit_object_set_axis_system(x_axis, y_axis, z_axis);
//
// Example D:
//  // Note that z_axis=(0,0,0) and that the x_axis and the y_axis are not orthogonal to each other.
//  //Note that we will get again the same result
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0;
//	y_axis[0]=-1; y_axis[1]=11; y_axis[2]=0;
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=0; 
//	Morfit_object_set_axis_system(x_axis, y_axis, z_axis);
//
// Example E:
//  // Note that z_axis=(-1,0,0) which doesn't give a right hand system
//	// in this case the z_axis will be ignored and calculated by doing cross between the x_axis and the y_axis
//  //Note that we will get again the same result
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0; 
//	y_axis[0]=-1; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=-1; 
//	Morfit_object_set_axis_system(x_axis, y_axis, z_axis);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_axis_system(DWORD object_handle, double x[3], double y[3], double z[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_axis_system(DWORD object_handle, double x[3], double y[3], double z[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_x_axis(DWORD object_handle, double x_axis[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_y_axis(DWORD object_handle, double y_axis[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_z_axis(DWORD object_handle, double z_axis[3]);



#ifndef WORLD_SPACE
#define WORLD_SPACE	0
#endif

#define OBJECT_SPACE (WORLD_SPACE+1)

// space flag can be OBJECT_SPACE or  WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_x(DWORD object_handle, double degrees, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_y(DWORD object_handle, double degrees, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_z(DWORD object_handle, double degrees, int space_flag);

// The same just with radians.
// space flag can be OBJECT_SPACE or  WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_x_radians(DWORD object_handle, double radians, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_y_radians(DWORD object_handle, double radians, int space_flag);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_z_radians(DWORD object_handle, double radians, int space_flag);

// The return value is in [-1  -   1] according to the
// angle between the object direction and the Z axis
// 1 means we are looking up . -1 means down.
MORFIT_IMPORT double	 MORFIT_WINAPI Morfit_object_get_cos_pitch(DWORD object_handle);

MORFIT_IMPORT double	 MORFIT_WINAPI Morfit_object_get_cos_bank(DWORD object_handle);
MORFIT_IMPORT double	 MORFIT_WINAPI Morfit_object_get_cos_head(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_total_move_mat(DWORD object_handle, double object_matrix[4][4]);



// returns a handle to the an animation that belongs to the object
// If the object has no animations or it has more then one the function
// returns NULL
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_animation(DWORD object_handle);

// names must be in capital letters
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_replace_animation_using_names(DWORD object_handle, char *old_animation_name ,char *new_animation_name);

// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_replace_animation(DWORD object_handle, DWORD old_animation_handle ,DWORD new_animation_handle);

// returns OK or VR_ERROR if failed
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_convert_point_to_world_space(DWORD object_handle, double object_space_point[3], double result[3]);
// returns OK or VR_ERROR if failed
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_convert_point_to_object_space(DWORD object_handle, double world_space_point[3], double result[3]);


// **************************

// returns VR_ERROR, OK

// if track_handle ==NULL it doesn't cancel the chase type so
// for canceling chasing use Morfit_object_set_chase_type(NO_CHASE);
// Automatically set the closest point on the track (closest to the object)
// as the next point to go towards
// (to override this setting use Morfit_object_set_next_point_on_track() )
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_track(DWORD object_handle, DWORD track_handle);

// return OK or VR_ERROR
// the offset is return through argument "offset"
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_track_offset(DWORD object_handle, double offset[3]);

// return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_track_offset(DWORD object_handle, double offset[3]);

// returns an index to a point on the track. This point is the point that the object is moving towards
// The exact cords of the point can be retrieved through Morfit_track_get_point()
// 0 is the first point and number_of_points-1 is the last index (use Morfit_track_get_number_of_points() to get this number
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_next_point_on_track(DWORD object_handle);

// returns the point on the track that the object is moving towards
// 0 is the first point and number_of_points-1 is the last index (use Morfit_track_get_number_of_points() to get this number
// if point_index<0 then it set it to 0
// if point_index is bigger than the maximum index then it is set to the maximum allowed. In those cases it returns VR_ERROR 
// to notify the change from the given value.
// If there is no track associated with the object it returns VR_ERROR without setting the value
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_next_point_on_track(DWORD object_handle, int point_index);

// Set the object to chase after
// the given argument should NOT be NULL
// Note that if the object was previously chasing a camera or a group
// , those chasing operation are canceled. (The object can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_object_to_chase(DWORD object_handle, DWORD object_to_chase_handle);

// If the return value is NULL it means no object is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_chased_object(DWORD object_handle);

// Set the camera to chase after
// the given argument should NOT be NULL
// Note that if the object was previously chasing another object or a group
// , those chasing operation are canceled. (The object can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_camera_to_chase(DWORD object_handle, DWORD camera_to_chase_handle);

// If the return value is NULL it means no camera is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_chased_camera(DWORD object_handle);

// Set the group to chase after
// the given argument should NOT be NULL
// Note that if the object was previously chasing a camera or an object
// , those chasing operation are canceled. (The object can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_group_to_chase(DWORD object_handle, DWORD group_to_chase_handle);

// If the return value is NULL it means no group is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_chased_group(DWORD object_handle);


// return OK or VR_ERROR
// the offset is return through argument "offset"
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_chase_offset(DWORD object_handle, double offset[3]);

// return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_chase_offset(DWORD object_handle, double offset[3]);

// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_chase_softness(DWORD object_handle);


// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
// it the given number is bigger than one it is set as one
// if it is smaller than 0 than it set as 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_chase_softness(DWORD object_handle, double softness);

// look in the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_chase_type(DWORD object_handle);

// look at the top of the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_chase_type(DWORD object_handle, int chase_type);


/*
	Function for automatic falling from a track.
	--------------------------------------------
	Example of usage:
	Say we have a track for a runner on a road, if the track is not 100 percent precise
	meaning that some time the runner will be in the air and some times inside the ground.
	With these functions we can solve that problem.
	We give an offset for the track in the Z axis 
	so the track will be above the road. Now if "falling"
	is ON, the object will fall down till it reaches the
	the track.
	Another example:
	If we want to move the object on a terrain model
        very close to the ground. It will be very difficult to 
	calculate the exact track. Now we can define a very simple
	track like a basic square and "falling" will do the rest.

	NOTE: to use it directly from the wld file, add _FALLxx to the
	chase_type. for example CHASE_TRACK_AIRPLANE would become CHASE_TRACK_AIRPLANE_FALL17
	17 here is the height above ground that we want to fall.
*/

// Calling this function will make the object fall down from
// its track till it reaches "height_above_ground" distance from the ground
// fall_through_dynamic_objects could be YES or NO. the idea here is that if for example we have a runner (human being)
// and the track is very high in the air then in might fall on the top of the airplanes so we would like it to fall through the planes on the ground
// if on the other hand there are cars on the ground we would like it to fall on the top of the cars and not to pass through.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_falling_from_track(DWORD object_handle, double	height_above_ground, int fall_through_dynamic_objects);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_unset_falling_from_track(DWORD object_handle);

// returns the current status in the three params: set_flag, height_above_ground, fall_through_dynamic_objects
// set_flag could be YES or NO 
// fall_through_dynamic_objects could be YES or NO . See Morfit_object_set_falling_from_track() for more details
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_falling_from_track_params(DWORD object_handle, int *set_flag, double	*height_above_ground, int *fall_through_dynamic_objects);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_location_on_track_before_falling(DWORD object_handle, double location[3]);

// Function for PHYSICS
//PHYSICS: SPEED: 0 0 0 FORCE: 0 0 0 MAX_SPEED: 0 FRICTION: 0 ELASTICITY: 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_speed(DWORD object_handle, double speed[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_speed(DWORD object_handle, double speed[3]);


MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_absolute_speed(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_absolute_speed(DWORD object_handle, double speed);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_force(DWORD object_handle, double force[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_force(DWORD object_handle, double force[3]);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_max_speed(DWORD object_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_friction(DWORD object_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_elasticity(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_max_speed(DWORD object_handle, double value);

//Friction is a value smaller or equal to 1
// if friction==0 it means no friction
// if friction==1 it means infinite friction nothing can move
// if friction is smaller than 0, it act like pressing
// The exact calculation.
// Each render the absolute_speed is multiply with (1-friction).
//
// Note, a negative number can use for increasing the speed.
// a friction of -1 will double the speed.
// -2 will multiply the speed by three each rendering.
// so choose number carefully.
// typical numbers can be 0.03 or -0.03 etc ...
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_friction(DWORD object_handle, double value);

//This number is used when the object hits a polygon.
//A value of one will make the new speed (after collision)
//equal to the old speed (effects only the absolute speed value and not the direction)
//a value of 0.5 will cut speed by half. 
//We can also give values greater than one.
//For example a value of 2 will make the new speed twice as big
//as before the collision.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_elasticity(DWORD object_handle, double value);

// advance all the objects. If Morfit_engine_advance_objects_automatically(YES) is called
// then this function will be called automatically each time we do render
// Note works only in viewer mode (viewer mode is the default mode)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_advance_all();

// Moves it according to the chase type.
// Note works only in viewer mode (viewer mode is the default mode)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_advance(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_reset_distance_counter(DWORD object_handle);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_distance_counter(DWORD object_handle);

// box[0][0] is the minimum X
// box[0][1] is the minimum Y
// box[0][2] is the minimum Z
// box[1][0] is the max X 
// box[1][1] is the max Y
// box[1][2] is the max Z
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_bounding_box(DWORD object_handle, double box[2][3]);

//Create a copy of a given object
//Returns a handle to the created object
//If an error occured it will return NULL
// duplicate_polygons_flag can be YES or NO.
// if NO is given then the source and the new copy will
// use the same polygons. That means that if we will change the bitmap or the color
// of a polygon it will effect all the copies too.
// If the object is big then duplicating all its polygons can be time consuming,
// That's why we might prefer to set duplicate_polygons_flag to NO.
// Note also that if the polygons are not really duplicated then many
// functions that receive a polygon will fail.
// For example if we call Morfit_polygon_get_location()
// and we send a polygon that belongs to a copy of an object. 
// then since we didnt duplicate the object's polygons there is only
// one polygon for both objects so in this case the function will return
// the location of the polygon from the original object.
// The Same story is with functions like Morfit_polygon_add_shadow_patch()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_duplicate(DWORD object_handle, int duplicate_polygons_flag);


//Note that after doing delete you cant use the handle any more
//so good practice is to do the following:
//	Morfit_object_delete(obj_handle);
//	obj_handle=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_delete(DWORD object_handle);

#define MORFIT_DELETE 1
#define MORFIT_DISABLE 2

// This function set a timer and an event that should happen after
// the time has elapsed.
// There only two events that could be used.
// MORFIT_DELETE and MORFIT_DISABLE.
// If MORFIT_DELETE is chosen then the object 
// will be automatically deleted after the time has elapsed
// If MORFIT_DISABLE is chosen then the object 
// will be automatically disabled after the time has elapsed
// The time is in milliseconds 
// Setting the timer to 0 will cancel any going event for this object.
// Note that after doing delete you cant use the handle any more
// so good practice is to do the following:
//	Morfit_object_set_expiration_timer(obj_handle,1000, MORFIT_DELETE);
//	obj_handle=NULL;
// examples:
// A) 
//	  Setting the timer to two seconds
//	  Morfit_object_set_expiration_timer(obj_handle, 2000, MORFIT_DISABLE);
// B)
//	  Canceling the timer
//	  Morfit_object_set_expiration_timer(obj_handle, 0, any_number_will_do);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_event(DWORD object_handle, int time_in_milliseconds, int event);

// Similar to Morfit_object_set_event() only that the event is triggered
// by an animation frame and not by time.
// When the animation on the given polygon will finish showing the given frame.
// The event will take place.
// Note that the given polygon must belong to the given object
// There only two events that could be used.
// MORFIT_DELETE and MORFIT_DISABLE.
// Example for usage: Lets say we have an explosion and now we have created
// an object for showing the smoke, the smoke will be an animation on a polygon.
// the animation will show smoke evaporating. using this function we can automatically delete
// the object once the animation is finished
// If animation_frame==-1 it has a special meaning, it means expire aftere the last frame.
// Note that after doing delete you cant use the handle any more
// so good practice is to do the following:
//	Morfit_object_set_event_on_animation_frame(obj_handle, polygon_handle, animation_frame, MORFIT_DELETE);
//	obj_handle=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_event_on_animation_frame(DWORD object_handle, DWORD polygon_handle, int animation_frame, int event);


//objects that are disabled are not drawn and are not
//taking CPU time (they also dont take part in collision detection).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_disable(DWORD object_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_enable(DWORD object_handle);

//Returns YES or NO.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_enabled(DWORD object_handle);

#define UNITS_PER_SECOND 1
#define UNITS_PER_RENDER 2
//When objects are set to go according to a specific track
//or when they move according to their physics, they have speed.
//We have two ways two work with the speed
//1-  UNITS_PER_SECOND
//	this is the default mode. It means that the object will be advanced 
//	in each render by the speed multiplied by the number of hundredths of a second
//	that have elapsed since the last render.
//	note that on slow computer the object will move with the same speed only that each render
//	the step will be bigger ...
//2-	
//	UNITS_PER_RENDER
//	Each render the object is advance by the speed, notice that we will
//	get a different speed for slow computers than on fast ones, though
//  the steps that the object is doing each render will always be equal.
//  
// The speed_units_system is always set for all the objects.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_speed_units(int speed_units_system);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_speed_units(void);


//Returns a handle to a polygon that belongs to the object and has
//the given name. If polygons_name==NULL, it will return a random polygon from the object.
//If the return value is NULL, it means that no polygon with the given name belongs
//to the object.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_polygon(DWORD object_handle, char *polygons_name);

//Returns YES if the given polygon is part of the given object
// NO otherwise.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_polygon_part_of(DWORD object_handle, DWORD polygon_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_number_of_polygons(DWORD object_handle);

// polygons_array[] is an array of DWORD. This array will be filled with handles to
// all the polygons of the object. 
// NOTE: you must allocate memory for the array before calling this function
// Example: 
//		int num_of_polys=Morfit_object_get_number_of_polygons(obj_handle);
//		// allocating mem using new or malloc etc ...
//		DWORD *poly_array=(DWORD *)malloc(num_of_polys*sizeof(DWORD));
//		Morfit_object_get_all_polygons(obj_handle, poly_array);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_all_polygons(DWORD object_handle, DWORD polygons_array[]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_chase_distance(DWORD object_handle, double chase_distance);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_object_get_chase_distance(DWORD object_handle);

// Ignore this object for collision detection 
// purposes. This means that when other object will call Morfit_object_is_movement_possible()
// ( or Morfit_engine_is_movement_possible() ) they would never get collision with
// this object. This function is useful for object like clouds, smoke, grass etc ...
// The default is that all the objects are collisional
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_make_non_collisional(DWORD object_handle);
// This is the default. 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_make_collisional(DWORD object_handle);
// Returns YES or NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_collisional(DWORD object_handle);


// The following three functions are only relevant when the chase type of
// the object is CHASE_PHYSICS. For example if your object is a billiard ball
// then the engine will automatically calculate its direction when it
// hits the tables edges.  If you cancel collision test then the engine would
// still calculate the speed and the friction etc ... but when the ball would hit
// the the table edge it will continue moving as if it was air.
// So why would you want to cancel the automatic collision detection ?
// You will want to cancel it when you do your own checking.
// Say for example that your object is a missile, that is planed to blow up
// when it is near the target. For this case you have to do your own test ...
// The default is: enabled
// If you didnt understand this explanation, forget it (those function are not important)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_cancel_collision_test_for_chase_physics(DWORD object_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_enable_collision_test_for_chase_physics(DWORD object_handle);
//Returns YES if collision detection test is performed (when the chase type is CHASE_PHYSICS)
// otherwise returns NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_collision_test_for_chase_physics(DWORD object_handle);


MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_collision_test_for_chase_physics(DWORD object_handle);

//This function is only relevant when the chase_type is set to CHASE_PHYSICS.
//Use this function to make the object rotate around its center.
//rotation_space: choose between WORLD_SPACE and OBJECT_SPACE
//rotate_around_x_axis: The number of angles that the object will rotate 
//		around the X axis, each time Morfit_engine_render() is called
// see also Morfit_object_get_physics_rotation()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_physics_rotation(DWORD object_handle, int rotation_space ,double rotate_around_x_axis, double rotate_around_y_axis, double rotate_around_z_axis);


//This function is only relevant when the chase_type is set to CHASE_PHYSICS.
// Return value: The rotation space (WORLD_SPACE or OBJECT_SPACE)
// through rotation_xyz[] the function returns the rotation angles
//		rotation_xyz[0] is the number of angles that the object will rotate 
//		around the X axis, each time Morfit_engine_render() is called
// see also Morfit_object_set_physics_rotation()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_physics_rotation(DWORD object_handle, double rotation_xyz[3]);

//Set the rotation center of the object. The default is the center of the object
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_rotation_center(DWORD object_handle, double center[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_rotation_center(DWORD object_handle, double center[3]);

//Determines whether the object will be moved automatically according to his chase type (The movement is done each time render is called)
// yes_no_flag should be YES or NO.
//The default is YES
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_advance_automatically(DWORD object_handle, int yes_no_flag);


// The following functions are used for creating a hierarchy among objects and manipulating
// multiple number of objects together. For example let's say
// that we want to have a human model in our application. We should construct the model from
// several objects, the hands, the legs, the head etc ... Each object can be constructed from
// smaller objects, the hands for example could contain objects for the fingers.
// When we move the hand we will want the finger objects to move together with the 
// hand object. We do it by setting the hand object as the father of each finger object. 
// Later we can call Morfit_object_move_including_sons(hand_object_handle) This will
// move the hand objects including all the fingers. 
// Terminology: The usage of the word TREE
//		Setting father-sons relations creates a structure similar to a family tree
//
// We can call this function with father_object==NULL
// this will mean that there is no father for this object.
// Returns OK or VR_ERROR.
// If the function fails it means that we tried to make a loop in hierarchy of the objects
// (for example setting object B as the father of object A and then setting object A as the father of B)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_father_object(DWORD object_handle, DWORD father_object);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_father_object(DWORD object_handle);

// returns YES or NO. 
// A NULL object_handle means the whole world
// Note that if groupA_handle==groupB_handle it will return YES
// If groupB_handle==NULL it will always return YES.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_is_objectA_included_in_objectB(DWORD objectA_handle, DWORD objectB_handle);

//Returns the first son of the given object. This function together with Morfit_object_get_next_son()
// create an easy way for going over all the descendants (son, grandchild etc ...) of an object.
// for example: 
//	for(son=Morfit_object_get_first_son(car_object); son!=NULL; son=Morfit_object_get_next_son(son)) {
//		//your code here ....
//	}
// Note that if you just want to go over all the direct sons (no grandchildren ...) you should
// use Morfit_object_get_first_direct_son() and Morfit_object_get_next_direct_son()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_first_son(DWORD object_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_next_son(DWORD object_handle, DWORD son_handle);

//Returns the first immediate son of the given object. This function together with Morfit_object_get_next_direct_son()
// create an easy way for going over all the direct son (the close family) of an object.
// for example: 
//	for(son=Morfit_object_get_first_direct_son(car_object); son!=NULL; son=Morfit_object_get_next_direct_son(son)) {
//		//your code here ....
//	}
// Note that if you want to go over all the descendants (including grandchildren ...) you should
// use Morfit_object_get_first_son() and Morfit_object_get_next_son()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_first_direct_son(DWORD object_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_next_direct_son(DWORD object_handle, DWORD son_handle);


// Advance the object (move relative) including all of its descendants
// space_flag could be WORLD_SPACE or OBJECT_SPACE or CAMERA_SPACE
// space_flag determines if the step is according to the objects
// coordinate system or the world coordinate  system etc ...
// for example if space_flag==OBJECT_SPACE and step==(-1,0,0)
// This means that the object will advance forward (If it is a car than
// forward is the direction of the front window).
// Try both option and see what happens.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_move_including_sons(DWORD top_object_handle, int space_flag, double x, double y, double z);

// Calculates the center of the collection of objects defined by the given object and all of its descendants
// The result is saved in the center argument.
// ("tree" means the whole family tree of the object)
//Return value: returns the number of objects in the tree
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_get_center_of_tree(DWORD top_object_handle, double center[3]);

#define CENTER_OF_TOP_OBJECT 1
#define CENTER_OF_TREE 2
#define CENTER_AS_GIVEN 3
// Move the object and all its descendants to a new location. center_flag can be one of the two: CENTER_OF_TOP_OBJECT or CENTER_OF_TREE
// If CENTER_OF_TREE is given then after calling this function the center of the tree will be in the given new location.
// If CENTER_OF_TOP_OBJECT then after calling this function the center of the top object will be in the given new location.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_location_of_tree(DWORD top_object_handle, double new_location[3], int center_flag);

//The object and all its descendants will be rotated according to the given arguments:
// degrees: The number of degrees to rotate.
// axis: this could be 1 or 2 or 3. Give one for rotating around the X axis. 2 for rotating around the Y axis and 3 for the Z axis
// space_flag: OBJECT_SPACE or  WORLD_SPACE. If we have chosen for example to rotate around the X axis
//								this flag determines whether it is the X axis of the object or the X axis of the world.
// center_flag: Could be one of the three, CENTER_OF_TOP_OBJECT, CENTER_OF_TREE, CENTER_AS_GIVEN.
//				This flag determines the center of rotation.
// center: this argument is only relevant if the center_flag is CENTER_AS_GIVEN. In this case the point given by this
//				argument will define the center of rotation.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_rotate_including_sons(DWORD top_object_handle, double degrees, int axis, int space_flag, int center_flag, double center[3]);

//Remove light from the given object.
//If the given object was lit using the Morfit_light API then
//this function could be used to restore the object normal appearance
//See also Morfit_group_remove_light(), Morfit_polygon_remove_light(), Morfit_light_remove_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_remove_light(DWORD object_handle);

//Sets the given bitmap to all the polygons of the object. The bitmap serves as a skin.
//Returns OK or VR_ERROR 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_bitmap(DWORD polygon_handle, DWORD bitmap_handle);

//Creates an empty object and returns its handle.
//The object is automatically added to the engine
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_create(char *name);

//Similar to Morfit_engine_add_world() the difference is that
//the added world file is added as a dynamic object.
//This function is most useful for adding md2 file (quake files)
//If the world contains a 3d animation (all md2 files contain 3d animation)
//The 3D animation will automatically be added to the engine
//see the 3D_animation API and the 3D_sequence API
//Example:
// girl=Morfit_object_create_from_file("people\\girl.md2");
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_create_from_file(char *file_name);


//Returns the object 3D_animation or NULL if it doesnt have any 3D animation
// Example:
// my_obj=Morfit_object_create_from_file("woman.md2"); //The md2 files contain a 3D animation. The 3D animation is automatically loaded to the engine
// my_3danim=Morfit_object_get_3D_animation();
// walk_sequence=Morfit_3D_sequence_get_using_name(my_3danim,"walk");
// standing_sequence=Morfit_3D_sequence_get_using_name(my_3danim,"stand");
// undressing_sequence=Morfit_3D_sequence_get_using_name(my_3danim,"undress");
// if(key_1_is_pressed) Morfit_object_set_3D_sequence(my_obj,walk_sequence); 
// if(key_2_is_pressed) Morfit_object_set_3D_sequence(my_obj,undressing_sequence); 
// and so on ...
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_3D_animation(DWORD object_handle);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_3D_animation(DWORD object_handle, DWORD animation3d_handle);


//Replace the current sequence with a new one.
// The engine will interpolate between the old sequence and the new one
// The duration of the interpolation process is controlled by transition_period
// transition_period is in mili seconds.
// If transition_period==0 then the engine wont do any interpolation between the old and the
// new sequences.
//Returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_set_3D_sequence(DWORD object_handle, DWORD sequence3d_handle, int transition_period);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_3D_sequence(DWORD object_handle);


//new_sequence3d_handle is the handle to the sequence that we want to play when the current sequence
//reached its last frame.
// arguments:
// transition_period	
//		The engine is going to interpolate between the old and the new animation and thus create a smooth animation
//		The duration of this transition period is given by the argument transition_period
//		If this value is 0 then the switch to the new sequence will happen immediately
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_replace_3D_sequence_when_finished(DWORD object_handle, DWORD new_sequence3d_handle, int transition_period);


//Scale the object (in object space).
//Example:
// double scale[3]={1,2,3}; //make it twice as wide and triple tall
// Morfit_object_set_scale(my_object, scale); 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_scale(DWORD object_handle, double scale[3]);
//Returns the scaling factor. The default is 1,1,1
// After calling this function
// scale[0] will hold the X scaling factor
// scale[1] will hold the Y scaling factor
// scale[2] will hold the Z scaling factor
// Example:
//		double scale[3];
//		Morfit_object_get_scale(my_object,scale);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_get_scale(DWORD object_handle, double scale[3]);

//Returns the handle to the group that represent this object.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_object_get_group_handle(DWORD object_handle);

//Calls Morfit_polygon_set_light() for all the polygons in the object
//For more details see Morfit_polygon_set_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_object_set_light(DWORD object_handle, BYTE rgb[3]);

/*
//Returns OK or VR_ERROR.
//The function automatically checks if the added polygon is valid.
//Note that you DONT need to call Morfit_engine_add_polygon()
//This is the only way to add polygons in Viewer_Mode.
//Exanple:
// popy=Morfit_polygon_create()
//Morfit_polygon_add_point(poly, p1);
// ...adding more pints
//Morfit_object_add_polygon(object_handel, poly);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_add_polygon(DWORD object_handle, DWORD polygon_handle);

//To see that it also work with Morfit_polygon_delete()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_object_delete_polygon(DWORD object_handle, DWORD polygon_handle);
*/

//Returns OK or VR_ERROR


//--------------------------------------------------------//
//=========== T H E    P O L Y G O N   A P I =============//
//--------------------------------------------------------//

// This API deals with polygons. Creating, setting the color or the bitmap etc ...

// Returns YES or NO.
// YES , if the given handle is a polygon handle. NO if not.
// If it is not a polygon handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_POLYGON()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_polygon(DWORD polygon_handle, char *function_asking);


// returns the handle to the polygon
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_handle_using_name(char *polygon_name);

// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_name(DWORD poly_handle, char *polygon_name);

MORFIT_IMPORT char * MORFIT_WINAPI Morfit_polygon_get_name(DWORD poly_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_handle_using_id_num(int poly_id_num);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_first_polygon(void); 

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_next(DWORD polygon_handle); 

//Note that the normal is the three first values .N==( plane[0], plane[1], plane[2])
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_get_plane(DWORD polygon_handle, double plane[4]); 

// if red==-1 && green == -1 && blue== -1
// the current color will be used
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_color_fill(DWORD polygon_handle, int red, int green, int blue); 


// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_bitmap_fill(DWORD polygon_handle, DWORD bitmap_handle);


// If the return is NULL then no bitmap is associated with the polygon
//the return value is The name of the bitmap without the extention 
// the bitmap_name is the name+path relative to the path given in Morfit_engine_load_world()
//If a bitmap exists in the world file
//but the engine couldnt find the bitmap file than it will still return its name.
//This is used when loading a world from the Internet, at first only the world is loaded
//and then we start streaming the bitmaps. We use this function to get the bitmap file name.
//If you want to check if the bitmap is in used then use Morfit_polygon_get_bitmap_handle()
// example:
// the executable path is d:\projects\test
// the bitmap path == d:\projects\test\bitmaps\animal\dog\boxer.bmp
// the bitmap path given in Morfit_engine_load_world() == "bitmaps"
// the return string here will be == "animal\dog\boxer"
MORFIT_IMPORT char * MORFIT_WINAPI Morfit_polygon_get_bitmap_name(DWORD polygon_handle); 

// if the return is NULL then no bitmap is associated with the polygon
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_bitmap_handle(DWORD polygon_handle); 


MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_get_color(DWORD polygon_handle, int *red, int *green, int *blue); 

// returns OK or VR_ERROR if no transparent color is set for this polygon
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_transparent_rgb(DWORD polygon_handle, int *red, int *green, int *blue); 

// Returns -1 if we transparent is not used for the given polygon
// else return the index to the transparent color, usually it
// will be 0 which means that the most used color is the transparent color
// if the return value is 1 it means that the second most popular
// color is the transparent color etc ...
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_transparent_index(DWORD polygon_handle); 

// returns OK or VR_ERROR
// if transparent_index== -1 transparent will be canceled for this polygon
// Obsolete. Use Morfit_bitmap_load() instead 
//MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_transparent_index(DWORD polygon_handle, int transparent_index); 

// returns OK or VR_ERROR
// if red and green and blue all equal to -1 transparent will be canceled for this polygon
// Obsolete. Use Morift_bitmap_load() instead 
//MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_transparent_rgb(DWORD polygon_handle, int red, int green, int blue); 

// returns YES or NO
// a rotated polygon will always turn itself to
// face the direction of the camera.
// this technique is used to make 2D images look like a 3D object
// usually we will use this technique for trees animals etc ...
// objects that look the same from all direction are excellent candidates
// (for example a tree or a vase) 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_rotated(DWORD polygon_handle); 

// yes_no_flag should be YES for setting the given polygon as rotated
// NO to set it as a normal polygon
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_rotated(DWORD polygon_handle, int yes_no_flag); 


MORFIT_IMPORT double MORFIT_WINAPI Morfit_polygon_get_light_diminution(DWORD polygon_handle); 

// return OK, VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_light_diminution(DWORD polygon_handle, double value); 

// return YES or NO
// light intensity values are used with bitmap filled polygons
// instead of using several bitmaps in different 
// brightness levels we can simply use this function
// we can also specify a different brightness value for each point
// of the polygon (using the POINT API functions)
// In that case the rendering of the polygon will be slower
// if all the points have the same brightness the rendering time
// is not damaged.
// relevant only for bitmap fill
// see also:
// Morfit_polygon_get_brightness()
// Morfit_polygon_set_brightness()
// Morfit_point_get_brightness()
// Morfit_point_set_brightness()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_uniform_brightness(DWORD polygon_handle); 

// If the brightness is not the same for all the 
// points we return the average.
// relevant only for bitmap fill
// see also:
// Morfit_polygon_set_brightness()
// Morfit_polygon_is_uniform_brightness()
// Morfit_point_get_brightness()
// Morfit_point_set_brightness()
MORFIT_IMPORT double MORFIT_WINAPI Morfit_polygon_get_brightness(DWORD polygon_handle); 

// returns OK, VR_ERROR
// relevant only for bitmap fill
// 100 means the same brightness as the original bitmap
// 200 means twice as bright as the original bitmap
// 50 is half bright as the original
// see also:
// Morfit_polygon_get_brightness()
// Morfit_polygon_is_uniform_brightness()
// Morfit_point_get_brightness()
// Morfit_point_set_brightness()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_brightness(DWORD polygon_handle, int value); 


MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_num_of_points(DWORD polygon_handle); 

// deletes the polygon
// Note an attempt to use a handle after it was 
// deleted will crash the program.
// Deleting a polygon will automatically deletes all his points and all its patches polygons.
// Note that you can also call this function to delete a patch polygon
// see also Morfit_polygon_delete_patches();
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_delete(DWORD polygon_handle); 

// Note an attempt to use a handle after it was 
// deleted will crash the program.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_delete_point(DWORD polygon_handle, DWORD point_handle); 


// Checks if all the points are on the same plane
// if there are less than three points etc ... The function also sets internal info
// returns YES if the polygon is valid or NO (if not valid).
// If the answer is NO it is usually because the polygon is
// not convex or because the points are not on the same
// plane or the bitmap cords are not good or the light intensity cords are not good.
// When doing Morfit_engine_add_polygon() this check is done
// automatically so it is impossible to add a bad polygon
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_valid(DWORD polygon_handle);


//Return YES if the polygon is convex.
// returns NO if the polygon is concave
// all polygons added to the world must be convex
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_convex(DWORD polygon_handle);
	
//Return YES or NO
// check that all points are on the same plane
// Will also return NO if there are less than 3 points in the poly, or if
// two of the three first points are identical.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_are_all_points_on_one_plane(DWORD polygon_handle);


MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_are_bitmap_x_cords_ok(DWORD polygon_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_are_bitmap_y_cords_ok(DWORD polygon_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_are_brightness_cords_ok(DWORD polygon_handle);



// returns the number of points that are on the same line
// 0 means no redundant points
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_count_redundant_points(DWORD polygon_handle);
	

// remove points that are on the same line
// return the number of points that where removed
// a negative number means that an error occurred
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_remove_redundant_points(DWORD polygon_handle); 



//use Morfit_point_get_next_point() the get the next points
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_first_point(DWORD polygon_handle); 

// creates a new empty polygon.
// returns a handle to the new polygons
// or NULL if an error occurred.
// Note ! the polygon won't be seen or checked for errors 
// till you do Morfit_engine_add_polygon()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_create(void); 


// returns a handle to the new point
// or NULL if an error occurred.
// Add the point as the last point (add to tail)
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_add_point(DWORD polygon_handle, double xyz_bmX_bmY_brightness[6]); 

// returns a handle to the new point
// or NULL if an error occurred.
// Add the point as the first point (add to head)
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_add_point_to_head(DWORD polygon_handle, double xyz_bmX_bmY_brightness[6]); 


MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_rotate_bitmap(DWORD polygon_handle); 
// how many rotation should be done in comparison to the original bitmap
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_bitmap_rotation(DWORD polygon_handle, int rotation_count) ;

MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_mirror_horizontal_bitmap(DWORD polygon_handle); 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_mirror_vertical_bitmap(DWORD polygon_handle); 


// the rotation is around the center of the polygon
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_rotate_x(DWORD polygon_handle, double degrees); 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_rotate_y(DWORD polygon_handle, double degrees); 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_rotate_z(DWORD polygon_handle, double degrees); 
// for general rotation operations.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_rotate(DWORD polygon_handle, double trans_mat[3][3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_move(DWORD polygon_handle, double step[3]); 

// the location is according to the center of the polygon
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_location(DWORD polygon_handle, double location[3]); 

// The location is according to the center of the polygon
// Note that if this polygons belong to a dynamic object then you
//	have to add the location of the dynamic object to the result.
//	(This note is not relevant in editor mode)

// The location is according to the center of the polygon
// A note regarding the function Morfit_object_duplicate() :
// Note that this function will fail if the polygon belongs to an object
// that was duplicated with the "dont_duplicate_polygons_flag"
// In this case we will get the location of the polygon on the original copy of the object
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_get_location(DWORD polygon_handle, double location[3]); 

// the scaling is according to the center of the polygon 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_scale(DWORD polygon_handle, double scale_x, double scale_y, double scale_z); 



// reverse the direction in which the polygon is visible
// remember that all the polygons have only one side which is visible.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_flip_visible_side(DWORD polygon_handle); 


// tries to join the two polygons to one polygon.
// if it is possible it deletes the two polygons create a new
// one and return the handle to the new one
// on failure returns NULL.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_join(DWORD polygon1_handle, DWORD polygon2_handle); 

// The bitmap cords of the target poly are set so they match the source_poly bitmap cords
// If the polys are adjacent calling this function would make the move from
// polygon to another smooth on the connection. If the polys are not on the same
// plane then the connection line will be smooth but the bitmap density would be
// different. 
// returns OK unless an error occurred (like a polygon with  2 points was received etc ...)
// returns VR_ERROR in case of error.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_match_bitmap_cords(DWORD source_polygon_handle, DWORD target_polygon_handle);
 

// duplicate a polygon.
// returns a handle to the new created polygon.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_duplicate(DWORD polygon_handle); 

// The given polygon is rotated so it will be parallel to 
// "reference_polygon_handle" (the second argument);
// return OK or VR_ERROR.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_rotate_to_match_polygon(DWORD polygon_handle, DWORD reference_polygon_handle);

// The given polygon is moved so his given point will match
// "point_to_match" (the third argument);
// return OK or VR_ERROR.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_move_to_match_point(DWORD polygon_handle, DWORD point_belongs_to_polygon, DWORD point_to_match);


// gets a point in space. return a handle to vertex of the polygon that
// is the closest to the given point.
// One important use of this function is in conjunction with Morfit_engine_2D_point_to_3D()
// When calling Morfit_engine_2D_point_to_3D() keep the 3d point and call this
// function with the 3d point.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_closest_point(DWORD polygon_handle, double p3d[3]);

//---------------------------------//
//-Polygons operations with groups-//
//---------------------------------//

// set the group that this polygon belongs to.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_group(DWORD polygon_handle, DWORD group_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_group(DWORD polygon_handle);

// returns YES or NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_in_group(DWORD polygon_handle, DWORD group_handle);

// What is orientation and why do we need it.
// When we want to drop an object\group on the ground (another surface) we need to know
// what surface of the object\group should be glued to the ground.
// The computer of course doesnt know on his own that a piano should stand on its legs ...
// With this flag the designer of the model can express his will that the piano should stand on its legs ...
//
// In order to fully define the orientation of a group, one polygon of the group should have ORIENTATION_BOTTOM or ORIENTATION_top
// and a second polygon should have ORIENTATION_FRONT or ORIENTATION_BACK beside those two polygons all the rest
// should have ORIENTATION_UNKNOWN. Nothing bad happens if they dont, it is just that it can cause contradict.
//
// See also Morfit_group_set_orientation()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_orientation(DWORD polygon_handle, int orientation_value);

//see also Morfit_group_get_orientation()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_orientation(DWORD polygon_handle);

//Note that this function works only if the polygon is convex.
//The function doesn't check whether the point is on the polygon plane
// to check if the point is on the plane first use Morfit_polygon_are_all_points_on_one_plane()
//
// actually this Morfit_polygon_is_point_inside_polygon determines whether a point is inside the infinity cylinder\tube shape that
// the given polygon is its profile.
// So we can also call Morfit_polygon_is_point_inside_polygon() with a point that is not 
// on the plane the function 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_point_inside_polygon(DWORD polygon_handle, double pnt[3]);

//The function doesn't check whether the point is on the polygon plane
//Use this function if the polygon could also be concave, otherwise use Morfit_polygon_is_point_inside_polygon()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_point_inside_polygon_concave(DWORD polygon_handle, double pnt[3]);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_set_animation(DWORD polygon_handle, DWORD animation_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_get_animation(DWORD polygon_handle);

// Assuming that there is an animation associated with the given polygon
// then this function makes it possible to jump to a specific frame. 
// If animation_frame==-1 then the last frame will be chosen.
// If the given animation_frame is bigger than the last frame then the last frame will be chosen.
// The first frame is numbered as 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_animation_frame(DWORD polygon_handle, int animation_frame);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_animation_frame(DWORD polygon_handle);

// calculate the center and returns in parameter "center"
// A note regarding the function Morfit_object_duplicate() :
// Note that this function will fail if the polygon belongs to an object
// that was duplicated with the "dont_duplicate_polygons_flag"
// In this case we will get the location of the polygon on the original copy of the object
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_get_center(DWORD polygon_handle, double center[3]);

//YES or NO. If NO the polygon wont be saved when doing Morfit_engine_save() with the SAVE_RELEASE flag
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_release_save_flag(DWORD polygon_handle, int YES_or_NO);

MORFIT_IMPORT int  MORFIT_WINAPI Morfit_polygon_get_release_save_flag(DWORD polygon_handle, int YES_or_NO);

//Polygons that are disabled are not drawn and are not
//taking CPU time (they also dont take part in collision detection) .
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_disable(DWORD polygon_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_enable(DWORD polygon_handle);

//returns YES if the polygon is disabled. NO if it is enabled
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_disabled(DWORD polygon_handle);

// Ignore this polygon for collision detection 
// purposes. This means that when Morfit_object_is_movement_possible()
// will be called ( or Morfit_engine_is_movement_possible() ) they would never get collision with
// this polygon. This function is useful for polygons representing clouds, smoke, curtains ,grass etc ...
// The default is that all the polygons are collisional
// see also Morfit_polygon_make_collisional() and Morfit_polygon_is_collisional()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_make_non_collisional(DWORD polygon_handle);

//This is the default. see also Morfit_polygon_make_non_collisional() and Morfit_polygon_is_collisional()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_make_collisional(DWORD polygon_handle);

//Return YES or NO. see also Morfit_polygon_make_collisional() and Morfit_polygon_make_non_collisional()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_is_collisional(DWORD polygon_handle);

// ------------------------------------------------------
// | Constants for glass types used for blending		|
// | with the function Morfit_polygon_set_translucent() |
// | Note that these constants are only relevant when   |
// | hardware rendering is used.								|
// ------------------------------------------------------
//
// One doesnt really have to read the explanations (though it
// is quite simple)	, you can test the different options and 
// pick the one you like.

//The default. The polygon will be 100% opaque.
#define DISABLE_BLENDING 0
	
// Filter glass can be used to block rgb channels
// like when looking through a cellophane paper
// For example if the color of the polygon is (red==255,0,0)
// Then when looking through this polygon the whole world will
// be painted with red. The blending formula for DARK_FILTER_GLASS
// is NEW_PIXEL=SRC*DEST  (SRC is the pixel of our polygon. DEST
// is the pixel in the background and NEW_PIXEL is final result.
// Example: We have a room with a window. We look outside through 
//		the window. Lets examine the rendering process
//		when rendering a specific pixel of the window.
//		The computer takes a pixel from the window 
//		(for example 0,0,64 == dark blue == 0.25, 0.25, 0.25 in [0-1] rgb scale)
//		and another pixel from outside the room that is exactly on the
//		line connecting between the eye (camera) and the pixel of the window
//		for example lets say that this line hits a cloud so our second pixel
//		is gray (rgb== 128,128,128 == 0.5, 0.5, 0.5 in [0-1] rgb scale) now
//		lets calculate the final pixel that we will have on the window
//		according to the function NEW_PIXEL=SRC*DEST == (0,0, 0.25)*(0.5, 0.5, 0.5)
//		== 0*0.5, 0*0.5, 0.25*0.5= (0,0,0.125) == (0,0,32 in [0-255] scale) 
//		== very dark blue.
//		This blending formula is called DARK_... because the result pixel is
//		darker or equal to the src pixel
#define DARK_FILTER_GLASS			0x31

//The blending formula for FILTER_GLASS is NEW_PIXEL=2*SRC*DEST
//This formula is usually better than DARK_FILTER_GLASS since
// the result pixel is less dark.
#define FILTER_GLASS				0x33

//The blending formula for OPAQUE_FILTER_GLASS is 
// NEW_PIXEL=SRC*SRC + SRC*DEST. It is similar to FILTER_GLASS
// It is called OPAQUE_... since it is a little bit more opaque than
// FILTER_GLASS
#define OPAQUE_FILTER_GLASS			0x43

// Create the effect of normal glass. Here is what happens when looking through 
// this glass: The light from bright objects easily penetrates the window
// while the light from darker objects is reflected from the glass (in this case 
// you get to see the bitmap of the window and not what is outside ...)
// Using this type of glass you can control the level of translucency
// Bright pixel in the bitmap will be totally opaque while dark pixel will
// blend with the background. Make a bright bitmap if you want your window
// to be more opaque. Make a dark bitmap if you want it to be more transparent.
// Note this side effect, the view outside the window will always look brighter
// than what it really is. This effect simulate our eye behavior. When we sit
// in a dark room and we open a window we are overwhelmed by the light. Once we get outside,
// we get used to it and it doesnt seem to be as bright as we felt before
// Here is the blending formula for this window:
// NEW_PIXEL= SRC(1-DEST)+DEST. Note that if DEST=(R,B,G) than 1-DEST is (1-R, 1-G,1-B)
// when working in [0-1] scale.
#define NORMAL_GLASS				0x52

// It is the only glass
// that make a real blending without decreasing or increasing the light.
// It is also the only one who gives a total control on the level of
// transparency, from being total opaque to being total transparent.
// Bright pixel in the bitmap will be totally opaque while dark pixel will 
// be transparent. Make a bright bitmap if you want your window
// to be more opaque. Make a dark window if you want it to be more transparent.
// The blending formula for this glass is
// NEW_PIXEL=SRC*SRC+DEST*(1-SRC)
#define CONTROL_GLASS				0x44

// Has the side effect of making the outside look brighter
// It is called transparent because the glass is a little bit
// more transparent than the other types.
// A dark bitmap (for the window) will make a very transparent glass
// a bright bitmap will make a bright blend between the window and the outside.
// Here is the blending formula:
// NEW_PIXEL=DEST+SRC*DEST
#define BRIGHT_TRANSPARENT_GLASS	0x32

//Similar to BRIGHT_TRANSPARENT_GLASS only a little bit less transparent
//Here is the blending formula:
// NEW_PIXEL=DEST+SRC*SRC
#define BRIGHT_TRANSLUCENT_GLASS	0x42

//similar to BRIGHT_TRANSLUCENT_GLASS only that
//the glass is more opaque. This glass can also be used to block color channels
//like with the filter modes (FILTER_GLASS).
//Here is the blending formula:
// NEW_PIXEL=SRC+SRC*DEST
#define BRIGHT_OPAQUE_GLASS			0x23

//This glass is special. It has the
//simple blending formula NEW_PIXEL=SRC+DEST
//Usually this type of blending is used for
//simulating light because of its additive characteristic
//If used as a window glass then we should use a dark bitmap
//otherwise we will have a very bright saturated window.
#define LIGHT_SOURCE_GLASS			0x22

//This glass creates a special effect. When looking
//through it, it inverts the world that we see.
//The blending formula is:
//NEW_PIXEL=SRC*(1-DEST).Note that if DEST=(R,B,G) than 1-DEST is (1-R, 1-G,1-B)
// when working in [0-1] scale.
#define INVERSE_GLASS				0x51

//Makes the polygon transparent as if it was glass
//Above are the different types of glass.
//call this function with DISABLE_BLENDING to
//change to normal rendering (100% opaque)
//The default is DISABLE_BLENDING
//Example: Morfit_polygon_set_translucent(my_poly,NORMAL_GLASS);
// Note that it will only work with hardware rendering 
// ( see Morfit_3D_card_check_hardware_support())
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_translucent(DWORD polygon_handle, BYTE glass_type);

//see Morfit_polygon_set_translucent()
MORFIT_IMPORT BYTE MORFIT_WINAPI Morfit_polygon_get_translucent(DWORD polygon_handle);

//Patches are polygons that are always in front of their father polygon
//For example if we shoot a wall in a game then we can add a patch polygon to
//make it look like a whole in the wall. Another example will be in a racing car
//game when we want to leave wheel marks on the road. We can easily do that
//by using Morfit_engine_is_movement_possible() to get the polygon of the road
//that is under the wheel and then to use this function to paste a wheel mark
//on the road polygon.
// The first parameter to this function is the polygon that we want to paste the
// patch on it.
// The second argument is the patch it self.
// Note that it is your responsibility to set the location and bitmaps of
// the patch polygon.
// See also Morfit_polygon_add_patch_easy() which saves you all the calculations.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_add_patch(DWORD polygon_handle, DWORD patch_polygon_handle);

// For explanation about patches see Morfit_polygon_add_patch()
// This function is similar to Morfit_polygon_add_patch()
// only that it is much easier to use. For example if we shoot a wall in a game then we can add a patch polygon to
// make it look like a whole in the wall. With this function you just
// have to specify the point on the wall where you want the patch to be put,
// the size of the patch and the bitmap that it will be using.
// The point and the polygon where your bullet hit the wall can be easily obtained
// by using Morfit_engine_is_movement_possible()
//
// Parameters
// ----------
// father_polygon
//			The polygon on which we want to place a patch
//			NOTE: the pach will inherit the father_polygon properties
//				  so if the father polygon is translucent the patch will also be translucent
//				  if the father_polygon is rotated so will be the patch
//				  If you want the patch to have different properties you
//				  have to set them after the patch was created. For example:
//				  double direction[3]={0,0,1};
//				  int rgb[3]={255,0,0} ; //red
//				  DWORD patch=Morfit_polygon_add_patch_easy(father_polygon, center, radius, direction, bitmap_handle,rgb);
//				  Morfit_polygon_set_rotated(patch,NO); //making sure that the patch wont be rotated
//				  Morfit_polygon_set_translucent(patch,DISABLE_BLENDING); //making sure that the patch wont be translucent
//				  A note regarding the function Morfit_object_duplicate():
//				  This function will fail if the father_polygon belongs to an object
//				  that was duplicated with the "dont_duplicate_polygons_flag" set
//					
// center
//			A point on the father polygon that will be the center of the patch
// radius
//			Used to specify the size of the patch. Note that the patches are actually
//			square polygons. This parameter gives the distance between the center of the square and one of the
//			square edges.
// direction
//			The direction of the patch. For example, if we have a car racing game
//			and we want the wheels to leave marks then we would like the wheel mark
//			to be in the direction of the car. So in this case we would give the direction
//			of the car as the direction of the patch. If you dont know, or if you dont care
//			about the direction you can give direction={0,0,0}.
// texture  
//			The texture that is used to paint the patch.
//			If NULL then the rgb color will be used
// rgb
//			Used only when texture==NULL. Specifies the color
//			rgb[0] is red. rgb[1] is green and rgb[2] is blue .
//
//
// Return value: returns a handle to the created patch polygon.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_polygon_add_patch_easy(DWORD father_polygon, double center[3], double radius, double direction[3], DWORD bitmap_handle,int rgb[3]);



#define ALL_PATCHES 1 //delete all the patches of a given polygon
#define REGULAR_PATCHES 2 //delete all the regular patches of a given polygon (patches that were mad using the function Morfit_polygon_add_patch() and Morfit_polygon_add_patch_easy() )
#define SHADOW_PATCHES 4 //delete all the shadow patches of a given polygon (patches that were created in the process of creating shade

//Delete patches of the given polygon. If the given polygon is a patch in itself
//then the function will return immediately (without deleting)
// Example A:
//		//Deleting all the patches of a given polygon
//		Morfit_polygon_delete_patches(my_polygon, ALL_PATCHES);
//
// Example B:
//		//Deleting all the patches that were created using the functions
//		//Morfit_polygon_add_patch() and Morfit_polygon_add_patch_easy()
//		Morfit_polygon_delete_patches(my_polygon, REGULAR_PATCHES);
//  
// Example C:
//		Delete all the patches that were created using the function Morfit_engine_create_shadow()
//		Morfit_polygon_delete_patches(my_polygon, SHADOW_PATCHES);
//
// Example D:
//		Delete patches that were created using the function Morfit_engine_create_shadow() with a serial_number==220
//		Morfit_polygon_delete_patches(my_polygon, 220);
//
// See also: Morfit_engine_create_shadow(), Morfit_polygon_add_patch() ,Morfit_polygon_add_patch_easy()
//			 Morfit_group_delete_patches()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_delete_patches(DWORD polygon_handle, int type_of_patches_to_delete_or_serial_number);


//Checks whether the given line segment intersect the given polygon.
//Returns YES if there is an intersection. Returns NO otherwise.
//The line segment is define by two points: double P1[3] and double P2[3]
//If there is an intersection the intersection point is saved within double intersection[3]
// Wont work in VIEWER_MODE with polygons that belong to a dynamic object (See the Morfit_object API)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_check_intersection_with_line_segment(DWORD polygon_handle, double P1[3], double P2[3], double intersection[3]);


//Checks whether the two given polygons intersect each other.
//Returns YES if there is an intersection. Returns NO otherwise.
//If there is an intersection the intersection point is saved within double intersection[3]
// Wont work in VIEWER_MODE with polygons that belong to a dynamic object (See the Morfit_object API)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_check_intersection_with_another_polygon(DWORD polygon1, DWORD polygon2, double intersection[3]);

//----------------------------------------------------------------------------
//=== Polygon function that has to do with light. See also the Light API =====
//----------------------------------------------------------------------------

// There are four properties that influence how light effects polygons, these are ambient, diffuse specular and specular_shining.
// Every defined light that is activated (see the light API) is combined internally of
// three types of lights (ambient, diffuse and specular)
// By using these functions one can modify how a surface react with each type of light.
// Different materials react differently For example
// materials that tend to reflect light better (metals, marble etc ...)
// will have higher values of the specular property. 
// The value given should be a positive number
// The default value is 86. Typical values are between 0 to 500
// Feel free to play with those values till you get the desired effect
// Here is some more info about the light properties
// Specular:
// The specular property defines for a surface how close it is to an ideal reflecting surface
// A mirror for example is a perfect reflecting surface. 
// Different materials have different values .For example
// materials that tend to reflect light better (metals, marble etc ...)
// will have higher values of the specular property.
// Diffuse:
// Diffuse light comes from a particular direction but is reflected evenly of the surface
// Dull surfaces like solid matte plastic exhibit what is called diffuse reflection
// Ambient:
// Ambient light is light that doesn't come from any particular direction
// Objects illuminated by ambient light are evenly lit on all surfaces.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_ambient(DWORD polygon_handle, int value);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_ambient(DWORD polygon_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_diffuse(DWORD polygon_handle, int value);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_diffuse(DWORD polygon_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_specular(DWORD polygon_handle, int value);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_get_specular(DWORD polygon_handle);
// The shining property influences only the specular light
// The default is 1. Typical values are between 0 to 10
// The lower this value is the bigger the light spot created from the specular lighting will be.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_specular_shining(DWORD polygon_handle, BYTE value);
// The shining property influences only the specular light
// The default is 1. Typical values are between 0 to 10
// The lower this value is the bigger the light spot created from the specular lighting will be.
MORFIT_IMPORT BYTE MORFIT_WINAPI Morfit_polygon_get_specular_shining(DWORD polygon_handle);

//Remove light from the polygon.
//If the given polygon was lit using the Morfit_light API then
//this function could be used to restore the polygon normal appearance
//See also Morfit_object_remove_light(), Morfit_group_remove_light(), Morfit_light_remove_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_remove_light(DWORD polygon_handle);

//Exactly like Morfit_group_wrap_a_bitmap_fixed(0 but just for one polygon.
// See also Morfit_group_wrap_a_bitmap()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_polygon_wrap_a_bitmap_fixed(DWORD polygon_handle, DWORD bitmap_handle, int repeat_x, int repeat_y, double locationXY_to_get_bitmap_top_left_corner[2], double locationXY_to_get_bitmap_bottom_right_corner[2]);

//Set the light values of each vertex directly
//Usually it is easier to use the light API to set the vertices
//color.
//The function calls Morfit_point_set_rgb() for all the points of the given polygon
//Note that this function will only work in hardware rendering mode
//One can try playing with this function to create nice effects.
//For example fading the polygon to the color of the background.
//See also Morfit_point_set_rgb()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_polygon_set_light(DWORD polygon_handle, BYTE rgb[3]);

//----------------------------------------------------//
//=========== T H E    P O I N T   A P I =============//
//----------------------------------------------------//

// About this API:
// Every polygon is built from points. This API deals with those points.

// Returns YES or NO.
// YES , if the given handle is a point handle. NO if not.
// If it is not a point handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_POINT()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_point_is_point(DWORD point_handle, char *function_asking);


// use Morfit_polygon_get_first_point() to get the first point
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_point_get_next_point(DWORD point_handle); 

// Gets the point (x,y,z) coordinate.
//Please note that if the point belongs to a dynamic object then the returned (x,y,z) will be in OBJECT_SPACE.
// To get the point in WORLD_SPACE you should write the following code:
//
// double xyz[3];
// Morfit_point_get_xyz(my_point, xyz);
// double xyz_world_space[3]
// Morfit_object_convert_point_to_world_space(my_object, xyz, xyz_world_space);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_get_xyz(DWORD point_handle, double xyz[3]); 


// Sets the point (x,y,z) coordinate.
// After changing the points of a polygon dont forget to call Morfit_polygon_is_valid()
// This call is needed for recalculating internal data of the polygon (such as the polygon's normal)
// Please note that if the point belongs to a dynamic object then the (x,y,z) should be in OBJECT_SPACE.
// To get a x,y,z coorinate in OBJECT_SPACE you should write the following code:
//
// double xyz[3];
// xyz[0]=100; xyz[1]=200; xyz[2]=300;  //setting the coordinate (world space)
// double xyz_object_space[3]
// Morfit_object_convert_point_to_object_space(my_object, xyz, xyz_object_space);
// Morfit_point_set_xyz(my_point, xyz);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_set_xyz(DWORD point_handle, double xyz[3]); 

MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_get_bitmap_xy(DWORD point_handle, double xy[2]); 

MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_set_bitmap_xy(DWORD point_handle, DWORD owner_polygon_handle ,double xy[2]); 


// This function will return the rgb values of the point
// Red will be returned in rgb[0] 
// Green will be returned in rgb[1] 
// Blue will be returned in rgb[2] 
// Note that these values are only relevant with hardware rendering.
// The default is (255,255,255).
// By changing the rgb value we can create light and atmospheric effects.
//
// How the rgb values are combined with the texture color and the polygon color
// to form the final color of each pixel:
// ----------------------------------------------------------------------------
// The final color of a pixel in a polygon is
// an outcome of the rgb values of the vertexes and the polygon texture or color
// The rgb of the vertexes is interpolated for every pixel of the polygon
// The interpolated value is multiplied by the texture color of every pixel.
// (If there is no texture then it is multiplied by the color of the polygon)
// Before multiplying the rgb is converted to a 0 till 1 scale.
// Example: Lets say we have a red polygon with its color set to (240,10,10)
// Lets assume that this is a triangle and that the rgb value of the vertexes is 
// (255,0,0 ) , (0,255,0) , (0,0,255). If we take a point in the center of the polygon
// then the interpolated value from the three vertexes will be something like (83,83,83)
// when 83 is converted from 0-255 scale to 0-1 scale we get that the interpolated value
// is (0.33, 0.33, 0.33). Now let multiply this value with the color of the polygon
// we get: (0.33, 0.33, 0.33) * (240, 10, 10) == (80, 3, 3)
// The result pixel will be (80,3,3)
//
// Special cases.
// --------------
// 1) If the RGB value of all the vertexes is (255,255,255)
// Then it wont have any effect since in scale of [0-1]
// it will become (1,1,1) and then the multiplication wont change
// the value of the pixel
// 2) If the polygon has no bitmap and its color is white (255,255,255)
// In this case the rgb values of the vertexes determine alone the color
// of the final pixel. This is also known as Gouraud shading
//
MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_get_rgb(DWORD point_handle, BYTE rgb[3]);

// This function will set the rgb values of the point
// Red should be given in rgb[0] 
// Green should be given in rgb[1] 
// Blue should be given in rgb[2] 
// Note that these values are only relevant with hardware rendering.
// By changing the rgb value we can create light and atmospheric effects.
// The light API is based on this function. Usually one would
// use the light API function though sometimes it nice to have the direct control
// for creating special effects.
//
// How the rgb values are combined with the texture color and the polygon color
// to form the final color of each pixel:
// ----------------------------------------------------------------------------
// The final color of a pixel in a polygon is
// an outcome of the rgb values of the vertexes and the polygon texture or color
// The rgb of the vertexes is interpolated for every pixel of the polygon
// The interpolated value is multiplied by the texture color of every pixel.
// (If there is no texture then it is multiplied by the color of the polygon)
// Before multiplying the rgb is converted to a 0 till 1 scale.
// Example: Lets say we have a red polygon with its color set to (240,10,10)
// Lets assume that this is a triangle and that the rgb value of the vertexes is 
// (255,0,0 ) , (0,255,0) , (0,0,255). If we take a point in the center of the polygon
// then the interpolated value from the three vertexes will be something like (83,83,83)
// when 83 is converted from 0-255 scale to 0-1 scale we get that the interpolated value
// is (0.33, 0.33, 0.33). Now let multiply this value with the color of the polygon
// we get: (0.33, 0.33, 0.33) * (240, 10, 10) == (80, 3, 3)
// The result pixel will be (80,3,3)
//
// Special cases.
// --------------
// 1) If the RGB value of all the vertexes is (255,255,255)
// Then it wont have any effect since in scale of [0-1]
// it will become (1,1,1) and then the multiplication wont change
// the value of the pixel
// 2) If the polygon has a bitmap and its color is white (255,255,255)
// In this case the rgb values of the vertexes determine alone the color
// of the final pixel. This is also known as Gouraud shading
//
MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_set_rgb(DWORD point_handle, DWORD father_polygon, BYTE rgb[3]);




// relevant only for bitmap fill
// 100 means the same brightness as the original bitmap
// 200 means twice as bright as the original bitmap
// 50 is half bright as the original
// see also:
// Morfit_polygon_get_brightness()
// Morfit_polygon_set_brightness()
// Morfit_polygon_is_uniform_brightness()
// Morfit_point_get_brightness()
MORFIT_IMPORT double MORFIT_WINAPI Morfit_point_get_brightness(DWORD point_handle); 

// note that if not all the points have the same brightness value
// the rendering of this polygon will be slower.
// relevant only for bitmap fill
// 100 means the same brightness as the original bitmap
// 200 means twice as bright as the original bitmap
// 50 is half bright as the original
// see also:
// Morfit_polygon_get_brightness()
// Morfit_polygon_set_brightness()
// Morfit_polygon_is_uniform_brightness()
// Morfit_point_get_brightness()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_point_set_brightness(DWORD point_handle, double value); 

//-----------------------------------------------------//
//======== T H E    G R O U P   A P I =================//
//-----------------------------------------------------//

// This API is used in editor mode to manipulate groups of polygons
// See also the OBJECT API for manipulating things in viewer_mode mode.
// With this API you can group polygons together. 
// Example,
// say we have a room with three tables inside. Each table has four legs
// and each leg has 6 polygons. We will probably like to build it like that:
// Group "leg" contains the six polygons
// group "table" which will include the four "leg" groups and the table top polygons
// group "room" which will include the three tables and the walls polygons


// A general note for most of the functions in this API:
// After a new group is created, polygons can be associated with this group
// by calling Morfit_polygon_set_group()
// IMPORTANT: if the polygons that are associated with the group are not part of the
//			  world (after creating a new polygon, we can add it to the world by calling Morfit_engine_add_polygon() )
//			  most of the function in the group API wont work for those polygons.


// Returns YES or NO.
// YES , if the given handle is a group handle. NO if not.
// If it is not a group handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_GROUP()
// NOTE, unlike all the other IS_xxx function this function consider a NULL
// as a legal handle, since a NULL group means the whole world.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_is_group(DWORD group_handle, char *function_asking);


// returns a handle of the newly created group
// After a new group is created, polygons can be associated with this group
// by calling Morfit_polygon_set_group()
// IMPORTANT: if the polygons that are associated with the group are not part of the
//			  world (after creating a new polygon, we can add it to the world by calling Morfit_engine_add_polygon() )
//			  most of the function in the group API wont work for those polygons.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_create(char *name);

// Just runs on the list of all the existing groups
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_first_group(void);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_next(DWORD group_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_using_name(char *name);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_first_polygon(DWORD group_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_next_polygon(DWORD group_handle, DWORD polygon_handle);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_father_group(DWORD group_handle);

// We can call this function with father_group==NULL
// means no father for this group.
// if the function fails it means that we tried to make a loop in hierarchy of the groups
// Returns OK or VR_ERROR.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_set_father_group(DWORD group_handle, DWORD father_group);



// A NULL group_handle means the whole world
// returns YES or NO. 
// note for example that if groupA_handle==groupB_handle returns YES
// or that if groupB_handle==NULL it will always return YES.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_is_groupA_included_in_groupB(DWORD groupA_handle, DWORD groupB_handle);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_group_get_name(DWORD group_handle);

// A NULL group_handle will get the rotation reference point of the whole world
// This is the point that all the rotations will use as the center of rotation
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_rotate_reference_point(DWORD group_handle, double center[3]);

// A NULL group_handle will get the rotation reference point of the whole world
// This is the point that all the rotations will use as the center of rotation
// see also Morfit_object_set_rotation_center()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_rotate_reference_point(DWORD group_handle, double center[3]);

// A NULL group_handle will get the center of mass of all the world
// The operations set_location and move are done according to the center of mass
// This function calls Morfit_group_get_bounding_box() and then
// calculates the center of the box.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_center_of_mass(DWORD group_handle, double center[3]);

// box[0][0] is the minimum X
// box[0][1] is the minimum Y
// box[0][2] is the minimum Z
// box[1][0] is the max X 
// box[1][1] is the max Y
// box[1][2] is the max Z
// This function is not very speedy 
// Unlike most of the get function which just return a value
// this function makes all the calculation going over all the vertexes
// in the group.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_bounding_box(DWORD group_handle, double box[2][3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_name(DWORD group_handle, char *name);

// A NULL group_handle means the whole world
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_number_of_polygons(DWORD group_handle);

// The same just with radians.
// space flag can be OBJECT_SPACE or  WORLD_SPACE
// A NULL group_handle means the whole world
// axis_flag (0 for the X axis. 1 for the Y axis. 2 for the Z axis)
// space flag could be: CAMERA_SPACE, OBJECT_SPACE, WORLD_SPACE
// see also Morfit_group_is_rotation_enabled()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_rotate(DWORD group_handle, double degrees, int space_flag, int axis_flag);


// A NULL group_handle means the whole world
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_rotate_using_matrix(DWORD group_handle, double rotate_matrix[3][3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_transform_using_matrix4x4(DWORD group_handle, double trans_matrix[4][4]);


// A NULL group_handle means the whole world
// moves the center of mass of the group to the given location
// Note that there is no Morfit_group_get_location(), instead use
// Morfit_group_get_center_of_mass().
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_location(DWORD group_handle, double location[3]);

// ZZZ
// I am about to cancel this function since it is the same as
// Morfit_group_get_center_of_mass().
// mean while I leave it just so I can link to the executable
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_location(DWORD group_handle, double *X, double *Y, double *Z);


// A NULL group_handle means the whole world
// moves all the vertex belonging to the group. The result is that the
// center of mass also moves with the given step 
// space flag could be: CAMERA_SPACE, OBJECT_SPACE, WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_move(DWORD group_handle, double step[3], int space_flag);

// A NULL group_handle means the whole world
// space flag could be: CAMERA_SPACE, OBJECT_SPACE, WORLD_SPACE
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_scale(DWORD group_handle, int space_flag,double scale_x, double scale_y, double scale_z);

//Get the width, height and depth of the group. Please note that
//The dimensions will be returned inside the parameter "dimension"
// dimension[0] will become the depth
// dimension[1] will be the width
//dimension[2] will be the height
//the dimensions are according to the bottom and the front of the group.
//To declarea polygon as being the bottom of the group see those function
// Morfit_polygon_set_orientation()
//Returns OK or VR_ERROR;
//Example:
//		double size[3];
//		Morfit_group_get_dimensions(my_group, size);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_dimensions(DWORD group_handle, double dimensions[3]);


// deletes the group but not the polygon included
// group handle cant be NULL
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_ungroup(DWORD group_handle);

// deletes all the polygons that belong to this group
// and all the groups that belong to this group
// return the number of polygons that were deleted
// A NULL group_handle will delete the whole world.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_delete_members(DWORD group_handle);

// Returns YES or NO.
// The static/dynamic properties are relevant when we will load the world
// in viewer mode. Only objects that are declared dynamic (not static) in
// editor mode will be able to move (using the object API)
// see also Morfit_group_set_static(), Morfit_group_set_dynamic()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_is_static(DWORD group_handle);

// The static/dynamic properties are relevant when we will load the world
// in viewer mode. Only objects that are declared dynamic (not static) in
// editor mode will be able to move (using the object API)
// see also Morfit_group_is_static(), Morfit_group_set_dynamic()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_static(DWORD group_handle);

// The static/dynamic properties are relevant when we will load the world
// in viewer mode. Only objects that are declared dynamic (not static) in
// editor mode will be able to move (using the object API)
// see also Morfit_group_set_static(), Morfit_group_is_static()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_dynamic(DWORD group_handle);

//Usually when we build a world (using Morfit World Builder for example)
//we have many models which we want them to be disabled when the world
//is loaded (in viewer mode) . For example, we could have few models of a bird that
//are interchanged to form a 3D animation. If the movement is composed of
// 3 models, then two of them will always be disabled, and one will be enabled.
// Using this function you can decide who is going to be loaded as disabled and
// who as an enabled object.
//Note that this function is only relevant to groups that were set as dynamic
//( using Morfit_group_set_dynamic() ). 
// The default is NO
// See also Morfit_object_disable()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_load_as_disabled(DWORD group_handle, int YES_or_NO);

//Returns YES or NO.
//See also Morfit_group_load_as_disabled(), Morfit_object_disable();
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_load_as_disabled_status(DWORD group_handle);

// returns a handle to the new group
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_duplicate_tree(DWORD group_handle);

// The function get three arguments.
// group_handle: the group to rotate
// polygon_in_the_group: a polygon that belongs to the group
// reference_polygon: any polygon.
// inverse_flag: YES or NO. If YES the Normal of the reference polygon is inversed (as if we took the back side of the reference polygon)
// The function rotates the group so that "polygon_in_the_group" will
// be parallel to "reference_polygon"
// returns OK, VR_ERROR.
// A NULL group handle means the whole world
// Note this very nice trick:
//		If the reference polygon also belongs to the group we can call
//		this function several times consecutively.
//		example say we have a box and we call this function as follows:
//		Morfit_group_rotate_to_match_polygon(grp, left_poly, front_poly);
//		after the first call the box will rotate in 90 degrees so the left
//		polygon is now were the front poly was. BUT the front poly is part of
//		the group ,so it was rotated too. consecutive calls to this function
//		will cause a 90 degrees rotation each time. like a dog trying to catch its tail.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_rotate_to_match_polygon(DWORD group_handle, DWORD polygon_in_the_group, DWORD reference_polygon, int inverse_flag);

// Similar to Morfit_group_rotate_to_match_polygon()
// with the difference that here we have an auxiliary line (going through points p1 and p2)
// To make things clearer let's say we have a square polygon_in_the_group
// and a square reference_polygon, there are four final position for the group
// so that polygon_in_the_group points to the same direction as reference_polygon.
// (each one of the four edges of one group polygon can be aligned with an edge of the
// reference polygon). Morfit_group_rotate_to_match_polygon() rotates so it will make
// the minimal rotation. This is usually what we want. So usually we will use
// Morfit_group_rotate_to_match_polygon(). We will use this function when we want
// to turn around a specific line. All the rest is exactly like in Morfit_group_rotate_to_match_polygon()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_rotate_around_line_to_match_polygon(DWORD group_handle, DWORD polygon_in_the_group, DWORD reference_polygon, int inverse_flag, double p1[3], double p2[3]);


// The same as Morfit_group_rotate_to_match_polygon() only that uses a direction instead of a reference polygon.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_rotate_to_match_direction(DWORD group_handle, DWORD polygon_in_the_group, double direction[3]);


// The given group is moved so his given point will match
// "point_to_match" (the third argument);
// return OK or VR_ERROR.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_move_to_match_point(DWORD group_handle, DWORD point_belongs_to_group, DWORD point_to_match);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_is_bitmap_used(DWORD group_handle, DWORD bitmap_handle);

// finds how many intersections between polygons of groupA (that dont belong to grpB)
// and polygons of group B (that are not included in A)
// groupA or groupB could be NULL (means the whole world) or any other group
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_count_intersections(DWORD groupA, DWORD groupB);

// Returns a handle to a polygon.
// The returned polygon is the first polygon that his orientation fits (according to the orientation field of the polygon)
// See also Morfit_polygon_set_orientation() and Morfit_polygon_get_orientation()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_bottom_polygon(DWORD group_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_top_polygon(DWORD group_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_front_polygon(DWORD group_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_back_polygon(DWORD group_handle);


// What is orientation and why do we need it.
// When we want to drop an object\group on the ground (another surface) we need to know
// what surface of the object\group should be glued to the ground.
// The computer of course doesnt know on his own that a piano should stand on its legs ...
// With this flag the designer of the model can express his will that the piano should stand on its legs ...
//
// In order to fully define the orientation of a group, one polygon of the group should have ORIENTATION_BOTTOM or ORIENTATION_top
// and a second polygon should have ORIENTATION_FRONT or ORIENTATION_BACK beside those two polygons all the rest
// should have ORIENTATION_UNKNOWN. Nothing bad happens if they dont, it is just that it can cause contradiction.
//
// Going back to Morfit_group_set_orientation(),
// the orientation_value should be one of the five values ORIENTATION_UNKNOWN ,ORIENTATION_TOP ORIENTATION_BOTTOM, ORIENTATION_FRONT, ORIENTATION_BACK
// if given ORIENTATION_UNKNOWN, then all the polygons of the group will be set with ORIENTATION_UNKNOWN.
//								In this case polygon_handle could be NULL
// if given ORIENTATION_BOTTOM, then the given polygon will be set with ORIENTATION_BOTTOM, and all the other polygons of the group that had ORIENTATION_BOTTOM or ORIENTATION_TOP will be set with ORIENTATION_UNKNOWN
// if given ORIENTATION_TOP, then the given polygon will be set with ORIENTATION_TOP, and all the other polygons of the group that had ORIENTATION_BOTTOM or ORIENTATION_TOP will be set with ORIENTATION_UNKNOWN
// if given ORIENTATION_FRONT, then the given polygon will be set with ORIENTATION_FRONT, and all the other polygons of the group that had ORIENTATION_FRONT or ORIENTATION_BACK will be set with ORIENTATION_UNKNOWN
// if given ORIENTATION_BACK, then the given polygon will be set with ORIENTATION_BACK, and all the other polygons of the group that had ORIENTATION_FRONT or ORIENTATION_BACK will be set with ORIENTATION_UNKNOWN
// See also Morfit_polygon_set_orientation()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_orientation(DWORD group_handle, DWORD polygon_handle, int orientation_value);


//Gets the group axis system according to the orientation of its polygons.
//If there are more than one polygon with the same orientation
// it will choose first, those polygons that belong directly to the group.
// In order to define the group axis system we need to have
// at least two polygons with the orientation flag given.
// one polygon should have the orientation FRONT or BACK and
// the other should be BOTTOM or TOP
// If there is only one polygon with orientation, the function will complete
// the rest according to the computer's understanding ....
// If there is no polygon with a given orientation it will again try to build
// the best system it can ...
// Return value
//--------------
// OK or VR_ERROR. In any case the axis_system given is legal.
// in case of error the axis system will be the same as the world axis system (1,0,0; 0,1,0; 0,0,1)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_calculate_axis_system(DWORD group_handle, double x_axis[3], double y_axis[3], double z_axis[3]);


/*
// Set the object to chase after
// the given argument should NOT be NULL
// Note that if the group was previously chasing a camera or a group
// , those chasing operation are canceled. (The group can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_object_to_chase(DWORD group_handle, DWORD object_to_chase_handle);

// If the return value is NULL it means no object is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_chased_object(DWORD group_handle);

// Set the camera to chase after
// the given argument should NOT be NULL
// Note that if the group was previously chasing another object or a group
// , those chasing operation are canceled. (The object can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_camera_to_chase(DWORD group_handle, DWORD camera_to_chase_handle);

// If the return value is NULL it means no camera is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_chased_camera(DWORD group_handle);

// Set the group to chase after
// the given argument should NOT be NULL
// Note that if the group was previously chasing a camera or an object
// , those chasing operation are canceled. (The object can chase only one thing at a time).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_group_to_chase(DWORD group_handle, DWORD group_to_chase_handle);

// If the return value is NULL it means no group is being chased
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_get_chased_group(DWORD group_handle);
*/


// name could be a name of a camera , object or a group.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_name_to_chase(DWORD group_handle, char *name);

// If the return value is NULL it means nothing is being chased
MORFIT_IMPORT char * MORFIT_WINAPI Morfit_group_get_chased_name(DWORD group_handle);


// return OK or VR_ERROR
// the offset is returned through argument "offset"
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_chase_offset(DWORD group_handle, double offset[3]);

// return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_set_chase_offset(DWORD group_handle, double offset[3]);

// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_chase_softness(DWORD group_handle);


// The returned number is between 0 and one
// a number close to 0 means that the tracking is weak
// 1 means that the tracking is very sharp.
// it the given number is bigger than one it is set as one
// if it is smaller than 0 than it set as 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_chase_softness(DWORD group_handle, double softness);

// look in the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT char *MORFIT_WINAPI Morfit_group_get_chase_type_name(DWORD group_handle);

// Like Morfit_group_get_chase_type_name() only that returns the equivalent constant
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_chase_type(DWORD group_handle);

// look in the header file for possible values and their meanings
// (look for NO_CHASE, CHASE_LOCATION and others ...)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_chase_type(DWORD group_handle, int chase_type);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_track_name(DWORD group_handle, char *track_name);

MORFIT_IMPORT char * MORFIT_WINAPI Morfit_group_get_track_name(DWORD group_handle);

// the offset is return through argument "offset"
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_track_offset(DWORD group_handle, double offset[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_track_offset(DWORD group_handle, double offset[3]);



// Calling this function will make the group fall down from
// it's track till it reaches "height_above_ground" distance from the ground
// fall_through_dynamic_objects could be YES or NO. the idea here is that if for example we have a runner (human being)
// and the track is very high in the air then it might fall on the top of the airplanes so we would like it to fall through the planes on the ground
// if on the other hand there are cars on the ground we would like it to fall on the top of the cars and not to pass through.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_falling_from_track(DWORD group_handle, double	height_above_ground, int fall_through_dynamic_objects);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_unset_falling_from_track(DWORD group_handle);

// returns the current status in the three params: set_flag, height_above_ground, fall_through_dynamic_objects
// set_flag could be YES or NO 
// fall_through_dynamic_objects could be YES or NO . See Morfit_group_set_falling_from_track() for more details
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_falling_from_track_params(DWORD group_handle, int *set_flag, double	*height_above_ground, int *fall_through_dynamic_objects);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_speed(DWORD group_handle, double speed[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_speed(DWORD group_handle, double speed[3]);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_absolute_speed(DWORD group_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_absolute_speed(DWORD group_handle, double speed);

// rotates the group so that the orientation of the group matches the given directions
// The given directions dont have to be normalized.
// one of the direction can be 0,0,0 in this case it is calculated automatically.
// If the given axis are not orthogonal, the function 
// handle it by building an orthogonal system that is close as possible
// to the given axis.
// see also Morfit_group_calculate_axis_system()
// Here are some examples, note that
// all the examples give the same result.
// Example A:
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0; 
//	y_axis[0]=-1; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=1; 
//	Morfit_group_rotate_to_match_axis_system(x_axis, y_axis, z_axis);
//
// Example B:
//	//Example B would give exactly the same result as example A
//	x_axis[0]=0; x_axis[1]=111; x_axis[2]=0; 
//	y_axis[0]=-17; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=12; 
//	Morfit_group_rotate_to_match_axis_system(x_axis, y_axis, z_axis);
//
// Example C:
//	//Note that  z_axis=(0,0,0) and will be automatically 
//  // calculated by the function
//	//Example C would give exactly the same result as example A and B
//	x_axis[0]=0; x_axis[1]=111; x_axis[2]=0; 
//	y_axis[0]=-17; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=0; 
//	Morfit_group_rotate_to_match_axis_system(x_axis, y_axis, z_axis);
//
// Example D:
//  // Note that z_axis=(0,0,0) and that the x_axis and the y_axis are not orthogonal to each other.
//  //Note that we will get again the same result
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0; 
//	y_axis[0]=-1; y_axis[1]=11; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=0; 
//	Morfit_group_rotate_to_match_axis_system(x_axis, y_axis, z_axis);
//
// Example E:
//  // Note that z_axis=(-1,0,0) which doesn't give a right hand system
//	// in this case the z_axis will be ignored and calculated by doing cross between the x_axis and the y_axis
//  //Note that we will get again the same result
//	x_axis[0]=0; x_axis[1]=1; x_axis[2]=0; 
//	y_axis[0]=-1; y_axis[1]=0; y_axis[2]=0; 
//	z_axis[0]=0; z_axis[1]=0; z_axis[2]=-1; 
//	Morfit_group_rotate_to_match_axis_system(x_axis, y_axis, z_axis);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_rotate_to_match_axis_system(DWORD group_handle, double x_axis[3], double y_axis[3], double z_axis[3]);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_rotate_around_line(DWORD group_handle, double p1[3], double p2[3], double degrees);

// Stretch a bitmap on all the polygons that belong to a group.
// works best if the group is flat like floor or terrain.
// If group_handle==NULL it will effect the whole world
// If bitmap_handle==NULL it wont change the bitmap.
// Note that if you want the bitmap to repeat more than once on the model (tile mode)
// then the dimensions of the bitmap must be in the power of two (for example 32,64,128,256,512,1024,2048 etc ... 
// all these numbers are powers of two).
// returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_wrap_a_bitmap(DWORD group_handle, DWORD bitmap_handle, int repeat_x, int repeat_y);



// This function reduces the number of polygons by
// eliminating redundant polygons and by joining few polygons
// to one polygons. 
// accuracy is used when we try to check whether two polygons
// have the same plane (so we can unite them to one polygon). 
// If this number for example is 0.1 and 
// the X component if the normals are planeA[0]=1 and planeB[0]=0.9
// then the join operation will take place.
// can be done only in editor mode.
// returns the number of polygons that were reduced.
// Returns VR_ERROR on failure on success returns the number of polygons that were reduced
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_reduce_polygons_count(DWORD group_handle ,double accuracy);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_create_reduced_copy(DWORD group_to_copy, double optimization_level) ;

// similar to Morfit_group_duplicate_tree() just that the new copy will be made of triangles only.
// Returns a handle to the new copy
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_group_create_copy_made_of_triangles(DWORD group_to_copy) ;



// Returns YES or NO.
// NO means that you cant use Morfit_group_rotate() to rotate the group
// The function will return NO, only if the group has at least one rotated polygon inside
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_is_rotation_enabled(DWORD group_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_convert_point_to_world_space(DWORD group_handle, double group_space_point[3], double result[3]);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_convert_point_to_group_space(DWORD group_handle, double world_space_point[3], double result[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_chase_distance(DWORD group_handle, double chase_distance);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_chase_distance(DWORD group_handle);

//Exactly like Morfit_polygon_delete_patches() only that it does it for the whole polygons of the group.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_delete_patches(DWORD group_handle, int type_of_patches_to_delete_or_serial_number);



//Set the color of all the patches in the group
// values for red green and blue should be in the range [0-255]
// patches_type should be one of the following: ALL_PATCHES, SHADOW_PATCHES, REGULAR_PATCHES
// or the serial number that was given when the patches were created
// Example A:
//		//Setting the color to all the patches of the given group
//		Morfit_group_set_patches_color(my_room, ALL_PATCHES);
//
// Example B:
//		//Setting the color to all the patches that were created using the functions
//		//Morfit_polygon_add_patch() and Morfit_polygon_add_patch_easy()
//		Morfit_group_set_patches_color(my_room, REGULAR_PATCHES);
//  
// Example C:
//		Setting the color to all the patches that were created using the function Morfit_engine_create_shadow()
//		Morfit_group_set_patches_color(my_room, SHADOW_PATCHES);
//
// Example D:
//		Delete patches that were created using the function Morfit_engine_create_shadow() with a serial_number==220
//		Morfit_group_set_patches_color(my_room, 39);
//
// See also: Morfit_engine_create_shadow(), Morfit_polygon_add_patch() ,Morfit_polygon_add_patch_easy()
//			 Morfit_polygon_delete_patches(), Morfit_group_delete_patches()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_patches_color(DWORD group_handle, int red, int green, int blue, int patches_type);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_patches_bitmap(DWORD group_handle, DWORD bitmap_handle, int patches_type);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_patches_translucent(DWORD group_handle, BYTE translucent_type, int patches_type);





//The functions below are the equivalent of Morfit_group_get\set_physics_...
//They will be useful for you only if you build some kind of World Editor (Such as Morfit World Builder)
//The functions wont show any change till we save the world and reload it in Viewer mode
//and when the chase_type is set to CHASE_PHYSICS.
//
// Return value: The rotation space (WORLD_SPACE or OBJECT_SPACE)
// through rotation_xyz[] the function returns the rotation angles
//		rotation_xyz[0] is the number of angles that the object will rotate 
//		around the X axis, each time Morfit_engine_render() is called
// see also Morfit_object_set_physics_rotation()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_physics_rotation(DWORD group_handle, double rotation_xyz[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_physics_rotation(DWORD group_handle, int rotation_space ,double rotate_around_x_axis, double rotate_around_y_axis, double rotate_around_z_axis);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_get_physics_force(DWORD group_handle, double force[3]);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_physics_force(DWORD group_handle, double force[3]);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_physics_friction(DWORD group_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_physics_friction(DWORD group_handle, double friction);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_physics_elasticity(DWORD group_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_physics_elasticity(DWORD group_handle, double elasticity);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_group_get_physics_maxspeed(DWORD group_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_physics_maxspeed(DWORD group_handle, double max_speed);


//This function is not so important ...
//This function associates a number with the group
//later (When the world is saved and load in viewer mode
//we can get this number using Morfit_object_get_control_type_number()
//Note that the function does nothing it is just a set and get mechanism. 
//The number that you give has no meaning to the Engine. 
//The meaning is as given by the application that is using the engine.
//parameters:
// num: any integer that is equal or greater than 64
// (the first 63 numbers are reserved for future use) 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_control_number(DWORD group_handle, int num);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_get_control_number(DWORD group_handle);

// Similar to Morfit_group_wrap_a_bitmap()
// The difference is that Morfit_group_wrap_a_bitmap() will
// stretch the bitmap so that the top right corner of the bitmap
// will fit to a corner of the group. This function
// will fit the corner of the bitmap the given location in the world
// locationXY_to_get_bitmap_top_left_corner[0], locationXY_to_get_bitmap_top_left_corner[1]
// This is the (X,Y) coordinate in the world that the top left corner of the bitmap will
// be associated with. 
// This way the given group might only get a portion of the bitmap.
// In the special case where locationXY_to_get_bitmap_top_left_corner, and locationXY_to_get_bitmap_bottom_right_corner
// are the bounding box of the group then this function will do the same as
// Morfit_group_wrap_a_bitmap()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_group_wrap_a_bitmap_fixed(DWORD group_handle, DWORD bitmap_handle, int repeat_x, int repeat_y, double locationXY_to_get_bitmap_top_left_corner[2], double locationXY_to_get_bitmap_bottom_right_corner[2]);

// Obselete .(works only in software mode)
// Set the brightness of each polygon of the group according to the intensity of the light source.
// values for ambient and are in the range [0-400]
// values for light_intensity light_intensity are in the range [0-400]
// see Morfit_polygon_set_brightness() for explanation of what those values mean
// ambient is the minimum light intensity that is, if the light source has zero intensity or points
// to the opposite direction , the polygon will have the ambient intensity. This is the light that reflects
// from the surroundings.
// Examples:
// A)	direction[0]=1; direction[1]=0; direction[2]=0;
//		Morfit_group_light_group(grp, direction,20, 400) //A very strong source of light in a dark environment
//
// B)	direction[0]=1; direction[1]=1; direction[2]=0; //The direction is diagonally
//		Morfit_group_light_group(grp, direction, 100, 100) //An average source of light in an average lit environment
//
// Note that actually one can also try negative values for the ambient and the light_intensity.
// note that the formula is final_intensity= ambient + angle_between_polygon_and_light_direction* light_intensity
// where angle_between_polygon_and_light_direction is normalized to the range [0-1]
// a negative light_intensity means that our light source gives darkness instead of light ! (a great new invention !)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_light_group(DWORD group_handle, double direction[3], double ambient, double light_intensity);


//Remove light from the group.
//If the given group was lit using the Morfit_light API then
//this function could be used to restore the group normal appearance
//If the given group handle is NULL then light will be removed from the whole world.
//See also Morfit_object_remove_light(), Morfit_polygon_remove_light(), Morfit_light_remove_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_remove_light(DWORD group_handle);

// Set the color of all the polygons that belong to the given group.
// rgb[0] ==red
// rgb[1]==green;
// rgb[2]==blue
//Example:
//	BYTE rgb[3]={255,0,0}; //red color
//  Morfit_group_set_color(NULL, rgb); //Set the whole world to red
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_color(DWORD group_handle, BYTE rgb[3]);

//Calls Morfit_polygon_set_light() for all the polygons in the group
//For more details see Morfit_polygon_set_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_light(DWORD group_handle, BYTE rgb[3]);

//Set the ambient light value to all the polygons contained in the given group
//For more details see Morfit_polygon_set_ambient()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_ambient(DWORD group_handle, int value);

//Set the diffuse light value to all the polygons contained in the given group
//For more details see Morfit_polygon_set_diffuse()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_diffuse(DWORD group_handle, int value);

//Set the specular light value to all the polygons contained in the given group
//For more details see Morfit_polygon_set_specular()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_group_set_specular(DWORD group_handle, int value);


//-----------------------------------------------------------//
//========= T H E   3 D _ A N I M A T I O N   A P I =========//
//-----------------------------------------------------------//


//This API deals with 3D model animation (mesh morphing)
//A 3D animation is a set of 3D models that are slightly different from one another
//Those 3D models are called 3D frames. For example a 3D animation of a man walking
//would contain several frames for completing a whole walking cycle.
//Usually the 3D character has several movements that it can perform.
//(For example, walk, jump, hit, fall down etc ...) each movement is combined
// of several frames and is called a 3D sequence.
// To summarize it: Each 3D animation is built from many 3D frames. The 3D frames are divided
// into separate 3D sequences. If it all sounds complicated then the following example will 
//clear things up. 

// my_obj=Morfit_object_create_from_file("woman.md2"); //The md2 files contain a 3D animation. The 3D animation is automatically loaded to the engine
// my_3danim=Morfit_object_get_3D_animation();
// walk_sequence=Morfit_3D_animation_get_sequence_using_name(my_3danim,"walk");
// standing_sequence=Morfit_3D_animation_get_sequence_using_name(my_3danim,"stand");
// undressing_sequence=Morfit_3D_animation_get_sequence_using_name(my_3danim,"undress");
// if(key_1_is_pressed) Morfit_object_set_3D_sequence(my_obj,walk_sequence); 
// if(key_2_is_pressed) Morfit_object_set_3D_sequence(my_obj,undressing_sequence); 
// and so on ...
//
//Please also note the 3D_sequence API which is used in conjunction with this API



// This function, together with Morfit_3D_animation_get_next()
// are used for going over all the defined 3D animations
// Example
// for(DWORD anim3d=Morfit_3D_animation_get_first(); anim3d!=NULL; anim3d=Morfit_3D_animation_get_next(anim3d) {
//		//Write here the code to do for each anim3d
// }
// Note that the function Morfit_3D_animation_create() adds a new anim3d
// to top of the queue. So Morfit_3D_animation_get_first()
// will always return the last anim3d that was created.
// The same rule is for all Morfit_xxxx_get_first() functions.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_animation_get_first(void);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_animation_get_next(DWORD anim3d_handle);


//Deletes all the existing 3d animations
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_animation_delete_all(void);

//Deletes the given anim3d.
// Note not to use the handle after it the anim3d was deleted
// Example:
// Morfit_3D_animation_delete(my_anim3d);
// my_anim3d=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_animation_delete(DWORD anim3d_handle);


//Returns a handle to the anim3d according to the given name
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_animation_get_using_name(char *anim3d_name);

//Returns YES or NO. NO is returned if the given handle
//is not a handle of a 3D_animAtion. YES is returned otherwise
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_animation_is_3D_animation(DWORD anim3d_handle, char *function_asking);


//-----------------------------------------------------------//
//========= T H E    3 D _ S E Q U E N C E    A P I =========//
//-----------------------------------------------------------//

//This API deals with 3D animation sequence (mesh morphing)
// Each 3D animation is built from many 3D frames. The 3D frames are divided
// into separate 3D sequences. For example there could be a "walking sequence"
// which is made of several frames that animate a full walking cycle.
//See also the Morfit_3D_animation API,
// Morfit_object_set_3D_sequence(), Morfit_object_get_3D_sequence()
// Morfit_object_replace_3D_sequence_when_finished(), Morfit_object_create_from_file()



// This function, together with Morfit_3D_sequence_get_next()
// are used for going over all the defined 3D sequences
// Example
// for(DWORD seq3d=Morfit_3D_sequence_get_first(); seq3d!=NULL; seq3d=Morfit_3D_sequence_get_next(seq3d) {
//		//Write here the code to do for each seq3d
// }
// Note that the function Morfit_3D_sequence_create() adds a new seq3d
// to top of the queue. So Morfit_3D_sequence_get_first()
// will always return the last seq3d that was created.
// The same rule is for all Morfit_xxxx_get_first() functions.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_sequence_get_first(DWORD animation3D_handle);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_sequence_get_next(DWORD sequence3d_handle);


//Returns a handle to the seq3d according to the given name
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_sequence_get_using_name(DWORD animation3D_handle, char *sequence3d_name);


//Deletes all the existing 3d animations
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_delete_all(DWORD animation3D_handle);

//Deletes the given seq3d.
// Note not to use the handle after it the seq3d was deleted
// Example:
// Morfit_3D_sequence_delete(my_seq3d);
// my_seq3d=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_delete(DWORD animation3D_handle,DWORD sequence3d_handle);



//Returns YES or NO. NO is returned if the given handle
//is not a handle of a 3D_sequence. YES is returned otherwise
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_is_3D_sequence(DWORD sequence3d_handle, char *function_asking);

// ========ZZZZ 

//The default speed is 1. A speed of 2 means twice slower. A speed of 0.5 means twice as fast.
//The default duration between to consecutive frames is 1 tenth of a second.
// See also Morfit_3D_sequence_set_frame_duration()
// Example:
// Lets assume that the frame duration wasn't changed from it default (you can change it using Morfit_3D_sequence_set_frame_duration() )
//That means 1 tenth of a second between two frames.
//So if the speed is equal to two then the duration between consecutive frames will be 2 tenth of a second
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_set_speed(DWORD sequence3d_handle, double speed);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_3D_sequence_get_speed(DWORD sequence3d_handle);


//Returns the number of frames that belongs to the given sequence.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_get_number_of_frames(DWORD sequence3d_handle);

//The time is in mili of seconds
//0 is the first frame of the sequence and (number_of_sequence_frames-1) is the last
//returns -1 if an error occurred.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_get_frame_duration(DWORD sequence3d_handle, int frame_number);
//returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_set_frame_duration(DWORD sequence3d_handle, int frame_number, int duration);


//Returns YES or NO
//A cyclic sequence means that when the last frame is reached is starts all over again
// A non cyclic sequence will stop animating when the sequencs reaches the last frame.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_is_cyclic(DWORD sequence3d_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_set_cyclic(DWORD sequence3d_handle, int YES_or_NO);


//Move the sequence to a specific position.
//current_frame should be in the range [0 - number_of_frames_in_sequence]
//Note that current_frame is double. Values like 3.76 are allowed
//In this case frames 3 and frame 4 will be interpolated to represent the given frame number
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_set_current_frame(DWORD sequence3d_handle, double current_frame);


//Note that current_frame is double. Values like 3.76 are allowed
//In this case frames 3 and frame 4 will be interpolated to represent the given frame number
//
MORFIT_IMPORT double MORFIT_WINAPI Morfit_3D_sequence_get_current_frame(DWORD sequence3d_handle);

//Will stop the animation (model morphing)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_pause(DWORD sequence3d_handle);

//This function will continue playing the animation after it was paused.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_play(DWORD sequence3d_handle);

//Return YES or NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_is_paused(DWORD sequence3d_handle);

//Change the direction of the 3D sequence. For example
//If our character walks then one we will walk backwards we will want to change
//the order of the sequence.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_sequence_backwards_play(DWORD sequence3d_handle, int YES_or_NO);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_is_backwards(DWORD sequence3d_handle);

//Returns the number of times that we have passed the last frame in the sequence
//If the sequence is not cyclic then this function will return 0 or 1.
//This function can be used to check if the sequence was finished.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_sequence_get_number_of_laps(DWORD sequence3d_handle);

//This function is very useful and is often used
// together with Morfit_object_set_3D_sequence()
//This function creates a copy of the given sequence and add it
//to the 3D_sequence list of the given 3D_animation. 
//Usually the given animation3D_handle is the 3D animation that
// sequence_to_duplicate belongs too.
// Using this function we can create for each object
// its own copy of the 3D_sequence thus when we will change the sequence
// properties it will effect only this object.
// name is the name to be given to the duplicated copy.
//Return value: The function returns a handle to the new sequence that was created.
//See also Morfit_object_set_3D_sequence() (very recommended)
// Example:
// Morfit_3D_sequence_duplicate(robot_animation, walk_sequence,"robot1_walk");
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_3D_sequence_duplicate(DWORD animation3D_handle, DWORD sequence_to_duplicate, char *name);



//----------------------------------------------//
//========= T H E    L I G H T   A P I =========//
//----------------------------------------------//

//This API deals with making light. It supports dynamic colored Gouraud shading light !
// Please also notice this powerful function: Morfit_engine_create_shadow()
// Morfit_engine_create_shadow() uses projection method techniques for creating light
// while the light API is using Gouraud shading technique. Both methods
// could be mixed together to create great effects.
// Please also note that Gouraud shading is using vertex lighting.
// This means that the effects will be much better if there are more vertexes (that means more polygons)


//Use this function to create a new light.
// light_name is the name you want to call this light (give what ever name you want)
// The location is the x,y,z coordinates of the light location
// The location can be moved later using the function Morfit_light_set_location()
// Example:
// double position[3]={10,20,30} ; //x=10, y=20, z=30
// DWORD light=Morfit_light_create("my_light",position);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_light_create(char *light_name, double location[3]);


#define LIGHT_SET	0
#define LIGHT_ADD	1
#define LIGHT_SUBTRACT 2

// This function is the function that actually creates the light !
// You wont see any light till you call this function.
// For dynamic lighting this function should be call over and over
// each time there is some change (for example the lit object changed position)
// For faster lighting in viewer mode use the function 
// Morfit_light_set_entity_to_light(my_light,my_object);
// to light every object in the world separately.

// The light operation could be any one of the following
// LIGHT_SET, LIGHT_ADD, LIGHT_SUBTRACT
// Here is what each one will do:
// LIGHT_ADD:
//		The calculated light will be added to the existing light.
//		Each call will make the illuminated entity brighter
// LIGHT_SUBTRACT:
//		This will cause the light source to create darkness !!!
//		In the real world we dont have an equivalent for that.
//		Subsequent calls will make the illuminated entity becomes darker on each call 
// LIGHT_SET:
//		The entity will be illuminated while ignoring previous illuminations.
//		Normally you will use this option.
//		Subsequent calls wont make any different unless 
//		The location, direction or other properties of the light have changed between calls or
//		that we are illuminating a dynamic objects that has change it position
//		(and thats why we have to recalculate its illumination)
// Example:
//	Morfit_light_activate(my_light, LIGHT_SET);
//
// The light is created with the following defaults:
// A non-directional light, use Morfit_light_set_type_of_light() to change it (and then use Morfit_light_set_direction() to set the direction).
// The light could reach an infinite distance without getting weaker. Use Morfit_light_set_distance_reach(0 to change it
// The whole world is illuminated. Use Morfit_light_set_entity_to_light() to change it. This will make this function much faster.
// The default color is white (255,255,255) Use Morfit_light_set_color() to change it.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_activate(DWORD light_handle, int light_operation);


//Returns a handle to the light according to the given name
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_light_get_using_name(char *light_name);


// This function, together with Morfit_light_get_next_light()
// are used for going over all the defined lights
// Example
// for(DWORD light=Morfit_light_get_first_light(); light!=NULL; light=Morfit_light_get_next_light(light) {
//		//Write here the code to do for each light
// }
// Note that the function Morfit_light_create() adds a new light
// to top of the queue. So Morfit_light_get_first_light()
// will always return the last light that was created.
// The same rule is for all Morfit_xxxx_get_first_xxxx() functions.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_light_get_first_light(void);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_light_get_next_light(DWORD light_handle);

//Sets the location of the light.
// Example
// double location[3]={10,20,30} //setting the X,Y,Z coordinates
// Morfit_light_set_location(my_light,location);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_location(DWORD light_handle, double location[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_get_location(DWORD light_handle, double location[3]);


// Sets the direction of the light. The direction of the light is relevant only if the 
// light type is set to be directional.
// The direction is set by giving a point in the world towards which the light should be pointed
// See also Morfit_light_set_direction()
// Example:
// double location[3]={0,0,10000}; //we make a sun so let put it up in the sky
// DWORD my_light=Morfit_light_create("the sun", location);
// double point={0,0,0}; //The sun should be pointing down
// Morfit_light_point_at(my_light, point);
// Morfit_light_set_type_of_light(my_light, LIGHT_DEFAULT_POINTED_LIGHT); //by default the light is not directional.
// Morfit_light_activate(my_light, LIGHT_SET); //let there be light ...
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_point_at(DWORD light_handle, double point[3]);


//Sets the direction of the light. The direction of the light is relevant only if the 
// light type is set to be directional.
// Note that a direction of {1,1,1} is exactly the same as {2,2,2}
// Example:
// double location[3]={0,0,0}
// DWORD my_light=Morfit_light_create("my_light", location);
// double direction={1,1,0};
// Morfit_light_set_direction(my_light, direction);
// Morfit_light_set_type_of_light(my_light, LIGHT_DEFAULT_POINTED_LIGHT); //by default the light is not directional.
// Morfit_light_activate(my_light, LIGHT_SET); //let there be light ...
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_direction(DWORD light_handle, double direction[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_get_direction(DWORD light_handle, double direction[3]);


//Set the color of the light. The default is {255,255,255} which is white.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_color(DWORD light_handle, BYTE color[3]);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_get_color(DWORD light_handle, BYTE color[3]);

//Remove light.
//Use Morfit_light_set_entity_to_light() for choosing the entity that
//the light will be removed from.
//See also Morfit_polygon_remove_light(), Morfit_object_remove_light(), Morfit_group_remove_light()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_remove_light(DWORD light_handle);


// Constant values for type_of_light (The values could be ored together e.g LIGHT_DIRECTIONAL | LIGHT_AMBIENT
#define LIGHT_DIRECTIONAL 1
#define LIGHT_EFFECTED_BY_DISTANCE_LINEAR 2
#define LIGHT_EFFECTED_BY_DISTANCE_SQUARE 4
#define LIGHT_AMBIENT 8
#define LIGHT_DIFFUSE 16
#define LIGHT_SPECULAR 32

//In most cases you will probably use one of the two combinations below
#define LIGHT_DEFAULT (LIGHT_EFFECTED_BY_DISTANCE_LINEAR | LIGHT_AMBIENT |LIGHT_DIFFUSE | LIGHT_SPECULAR)
#define LIGHT_DEFAULT_POINTED_LIGHT (LIGHT_DIRECTIONAL | LIGHT_EFFECTED_BY_DISTANCE_LINEAR | LIGHT_AMBIENT |LIGHT_DIFFUSE | LIGHT_SPECULAR)
// The type of light can be combined from the following options 
// LIGHT_DIRECTIONAL
//		Denote that the light is directional. The direction could be set by Morfit_light_get_direction()
// LIGHT_EFFECTED_BY_DISTANCE_LINEAR 
//		The light is reduced according to the distance from the light source location
//		The reduction is linear
//		This flag is included in the default light type though
//		NOTE that in order to feel its effect you have first to define the light source
//		maximum reach. Do that with Morfit_light_set_distance_reach()
// LIGHT_EFFECTED_BY_DISTANCE_SQUARE 
//		The effect is that the light reduction is small near the light sourse and very strong
//		near the end of the light reach area
// LIGHT_AMBIENT 8
//		If this flag is not set then the ambient light component will not be used
// LIGHT_DIFFUSE 16
//		If this flag is not set then the diffuse light component will not be used
// LIGHT_SPECULAR 32
//		If this flag is not set then the ambient light component will not be used
//In most cases you will probably use one of the two combinations below
// LIGHT_DEFAULT (LIGHT_EFFECTED_BY_DISTANCE_LINEAR | LIGHT_AMBIENT |LIGHT_DIFFUSE | LIGHT_SPECULAR)
// LIGHT_DEFAULT_POINTED_LIGHT (LIGHT_DIRECTIONAL | LIGHT_EFFECTED_BY_DISTANCE_LINEAR | LIGHT_AMBIENT |LIGHT_DIFFUSE | LIGHT_SPECULAR)
//
// The default light type is LIGHT_DEFAULT
// Example A:
//		//Setting a directional light
//		Morfit_light_set_type_of_light(my_light,LIGHT_DEFAULT_POINTED_LIGHT);
// Example B:
//		//using LIGHT_EFFECTED_BY_DISTANCE_SQUARE
//		Morfit_light_set_type_of_light(my_light, LIGHT_DIRECTIONAL | LIGHT_EFFECTED_BY_DISTANCE_SQUARE | LIGHT_AMBIENT |LIGHT_DIFFUSE | LIGHT_SPECULAR);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_type_of_light(DWORD light_handle, int type_of_light);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_light_get_type_of_light(DWORD light_handle);

//Gives much more accurate lighting that takes into account obstacles between
// the lit surface and the source of light.
// The disadvantage is that lighting is much more slower when it is on.
// Dont use it for lighting every render.
// The default is NO (not activated)
// Example:
// Morfit_light_set_ray_tracing(my_light, YES);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_ray_tracing(DWORD light_handle, int YES_or_NO);


MORFIT_IMPORT int MORFIT_WINAPI Morfit_light_is_ray_tracing(DWORD light_handle);


//Set the distance that the light source can reach. The strength of the light is 
// decreasing as it gets further away from the light source. 
// A distance reach of -1 has a special meaning. It means an infinite reach.
// This is the default (infinite reach) so in order to see the effect of the distance
// one needs to call this function first.
// Example:
// Morfit_light_set_distance_reach(my_light, 100000);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_distance_reach(DWORD light_handle, double distance_reach);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_light_get_distance_reach(DWORD light_handle);


//Set the target object that will be lit by our light.
// entity_to_light could be a handle to a group an object or a polygon.
// The default entity is the whole world
// To make the function Morfit_light_activate() you should change it to illuminate just the 
// the entity that needs lighting.
// Examples:
// A)
//		Morfit_light_set_entity_to_light(my_light, polyogn_handle);
//		In this case when the light will be activated it will only influence
//		the given polygon.
// B)
//		Morfit_light_set_entity_to_light(my_light, NULL);
//		NULL is a valid group_handle. It means the whole world
//		In this case when the light will be activated it will influence
//		the whole world.
// C)
//		Morfit_light_set_entity_to_light(my_light, chair_group_handle);
//		When the light will be activated it will only light the chair
//		This is a nice way to paint a specific item in the world.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_light_set_entity_to_light(DWORD light_handle, DWORD entity_to_light);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_light_get_entity_to_light(DWORD light_handle);


// Activates the light automatically before each render.
// The usage of this function is for dynamic lighting.
// If the light source moves every render (or other property of the light is changed)
// then the light has to be updated as well
// If however the light source properties do not change between every render then you
// should not use this method (it will waste CPU time).
// Another use for this method is for lighting dynamic objects.
// Again use it only if the dynamic object moves or rotates every render
// otherwise it is better to call Morfit_light_activate() explicitly after
// each time that the object changes its position.
// light_operation:
//		Determines how the light is going to be activated every render.
//		possible values are: LIGHT_ADD, LIGHT_SUBTRACT and LIGHT_SET
//		Normally you would give LIGHT_SET. The other two options can be 
//		used for creating special effects like gradually darkening the world
//		or a "get killed" effect when the screen turns into red (using a red colored light)
//		The light_operation argument is only relevant if YES_or_NO==YES
//Examples:
// A)
//		Morfit_light_activate_before_each_render(my_light, YES, LIGHT_SET);
// B)
//		Morfit_light_activate_before_each_render(my_light, NO, 0); //doesnt matter what number is given (for the light operation)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_activate_before_each_render(DWORD light_handle, int YES_or_NO, int light_operation);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_light_is_activated_before_render(DWORD light_handle, int *light_operation);

// Each source of light is combined of three different channels, they are
// called Ambient, Diffuse and specular. 
// Ambient light:
//		Ambient light is light that doesn't come from any particular direction
//		Objects illuminated by ambient light are evenly lit on all surfaces.
//		For example if we create a room with a few light sources then even
//		if all the light sources are turned off we will still have some light in the room.		
//		The ambient channel used to simulate this non-directional environment light
// Diffuse light:
//		Diffuse light comes from a particular direction but is reflected evenly of the surface		
//		A good example of a diffuse light source is fluorescent lighting.
//
// Every source light is actually a combination of the three type of lights
// Feel free to play with these values till you get the desired results.
// The rule is that if it looks good then it is correct..	
// The resulted lighting is a combination of the material characteristic and the type of light
// For controlling the material light properties see Morfit_polygon_set_ambient(), Morfit_group_set_ambient(), Morfit_object_set_ambient()
//
// The given value should be a positive number or zero.
// The default is one. Common values are in the range of 0 to 10 
// Examples:
// A)
//		Morfit_light_set_ambient(my_light, 1); //the default
// B)
//		Morfit_light_set_ambient(my_light, 2.8); //A very strong ambient lighting.
// C)
//		Morfit_light_set_ambient(my_light, 0); //Shutting off the ambient channel
//											   //It is better by not including the ambient light
//											   //flag when calling Morfit_light_set_type_of_light()
//
// The same goes for the diffuse and specular lighting.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_ambient(DWORD light_handle, double value);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_diffuse(DWORD light_handle, double value);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_specular(DWORD light_handle, double value);


MORFIT_IMPORT double MORFIT_WINAPI Morfit_light_get_ambient(DWORD light_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_light_get_diffuse(DWORD light_handle);

MORFIT_IMPORT double MORFIT_WINAPI Morfit_light_get_specular(DWORD light_handle);

// Use this function to control the size of the light spot that
// the specular lighting is creating.
// The default value is 1.
// The smaller the number is the bigger the light spot is.
// Values should be any positive number or zero.
// Normally values would be in the range of 0 to 10
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_specular_shining(DWORD light_handle, double value);
MORFIT_IMPORT double MORFIT_WINAPI Morfit_light_get_specular_shining(DWORD light_handle);

//Returns YES or NO. NO is returned if the given handle
//is not a handle of a light. YES is returned otherwise
MORFIT_IMPORT int MORFIT_WINAPI Morfit_light_is_light(DWORD light_handle, char *function_asking);

//Deletes all the existing lights
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_delete_all(void);

//Deletes the given light.
// Note not to use the handle after it the light was deleted
// Example:
// Morfit_light_delete(my_light);
// my_light=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_delete(DWORD light_handle);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_light_get_name(DWORD light_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_light_set_name(DWORD light_handle, char *name);
//--------------------------------------------------------//
//=========== T H E    A N I M A T I O N   A P I =========//
//--------------------------------------------------------//

// animation is a set of bitmaps that replaces itself according
// to a given time sequence.
// A polygon can have a regular bitmap or it can have an animation.
// The idea is that one can just give a list of bitmaps with time sequence
// and the engine deals with all the rest.
// Animations are very useful when used on a rotated polygons.
// You can then define animation  sequences from 8 sides
// and the graphic engine sees that the right bitmap is
// shown each time.
// Each animation can include up to 8 different bitmap sequences
// This is used for representing a rotated polygon from 8 different sides.
// actually there are only 5 bitmaps sequences (the rest are figured automatically
// by the engine by mirroring some bitmaps)
// Here are the 5 constants that represent the 5 different list
#define  BITMAP_LIST_FRONT 1  //a list of bitmaps representing the view from the front
#define  BITMAP_LIST_FRONT_SIDED 2  //a list of bitmaps representing the view from the front-side (45 degrees) angle
#define  BITMAP_LIST_SIDE 3  //a list of bitmaps representing the view from the side
#define  BITMAP_LIST_BACK_SIDED 4  //a list of bitmaps representing the view from the back-side (135 degrees) angle
#define  BITMAP_LIST_BACK 5  //a list of bitmaps representing the view from the back
//
// To understand animation better, just look at one of the sample worlds
// that contain an animation. Try playing with the list of bitmaps and the other params.


// Returns YES or NO.
// YES , if the given handle is an animation handle. NO if not.
// If it is not an animation handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_ANIMATION()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_is_animation(DWORD animation_handle, char *function_asking);


// The given name should be in capital letters
// If the return value is 0 it means 
// that there is no animation with the given name.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_get_handle(char *animation_name);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_get_first_animation(void); 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_get_next(DWORD animation_handle); 

//Creates an empty animation 
//name: give any name you want. 
//		NOTE that if the name is already in use by another animation
//		the function would automatically add a number to the end of the name
// After creating the animation use Morfit_animation_add_bitmap() to add bitmaps
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_create(char *name); 


// bitmap_list: is one of the five constants: BITMAP_LIST_FRONT, BITMAP_LIST_FRONT_SIDED, BITMAP_LIST_SIDE, BITMAP_LIST_BACK_SIDED, BITMAP_LIST_BACK
// bitmap_handle: is the frame to add
// bitmap_position_index: 0 means put this frame as the first frame
//						  1 means that we want to insert the bitmap after the first bitmap
//								(our bitmap will become the second bitmap)
//						  n means that we want to insert the bitmap AFTER the n bitmap
//						  -1 has a special meaning it will put the frame as the last one
//						  If the given index is too big than the frame will be set as the last frame.
//
// The return value: return the location of the added bitmap in the given list.
// usually this value is equal to the given "bitmap_position_index" argument (unless
// bitmap_position_index==-1 or is too big)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_add_bitmap(DWORD animation_handle, int bitmap_list ,DWORD bitmap_handle, int bitmap_position_index); 

// removes a bitmap from the given list
// bitmap_list: is one of the five constants: BITMAP_LIST_FRONT, BITMAP_LIST_FRONT_SIDED, BITMAP_LIST_SIDE, BITMAP_LIST_BACK_SIDED, BITMAP_LIST_BACK
// bitmap_position_index: 0 means remove the first frame
//						  1 means remove the second frame etc ...
//						  -1 has a special meaning it will remove the frame at the end of the list
//						  If the given index is too big than the last frame will be removed.
//
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_remove_bitmap(DWORD animation_handle, int bitmap_list ,int bitmap_position_index); 

// return a handle to the bitmap in the specified list and index
// bitmap_list: is one of the five constants: BITMAP_LIST_FRONT, BITMAP_LIST_FRONT_SIDED, BITMAP_LIST_SIDE, BITMAP_LIST_BACK_SIDED, BITMAP_LIST_BACK
// bitmap_position_index: 0 will return the first bitmap
//						  1 the second bitmap etc ...
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_get_bitmap(DWORD animation_handle, int bitmap_list ,int bitmap_position_index); 

// time_for_each_frame: should be equal to Morfit_animation_get_number_of_frames()
// before calling this function you should initialize the array ( DWORD time_for_each_frame[])
// the time is in hundreds of seconds.
// Example:
//		time_for_each_frame[0]= 100; //The first frame will be shown for one second
//		time_for_each_frame[1]= 200; //The second frame will be shown for one second
//		Morfit_animation_set_times(my_animation, time_for_each_frame, 2);
// 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_set_times(DWORD animation_handle, DWORD time_for_each_frame[], int size_of_array); 

// time_for_each_frame: should be equal to Morfit_animation_get_number_of_frames()
// the time is in hundreds of seconds.
// Example:
//		DWORD time_for_each_frame[10]
//		Morfit_animation_set_times(my_animation, time_for_each_frame, 10);
// 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_times(DWORD animation_handle, DWORD time_for_each_frame[], int size_of_array); 

//Get the duration of the given frame. (in hundreds of seconds)
// frame_index: 0 means the first frame
//			    1 means the second frame etc ...
// to get the last frame frame_index should be equal to the numbers of frames minus one.
//For Example:
//	time=Morfit_animation_get_frame_time(my_anim,0); // This would return the time
//												// in hundreds of second that
//												// the first bitmap will be shown
//												// before it replaced by the second bitmap \ frame.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_get_frame_time(DWORD animation_handle, int frame_index); 

// Set the duration of the given frame. (in hundreds of seconds)
// returns OK or VR_ERROR
// For Example:
//	Morfit_animation_set_frame_time(my_anim,0,100); // This would set the duration 
//												// in hundreds of second (100== 1 second) of
//												// the first bitmap will be shown
//												// before it replaced by the second bitmap \ frame.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_set_frame_time(DWORD animation_handle, int frame_index, DWORD time); 


MORFIT_IMPORT char * MORFIT_WINAPI Morfit_animation_get_name(DWORD animation_handle); 

//NOTE that if the name is already in use by another animation
//the function would automatically add a number to the end of the name
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_set_name(DWORD animation_handle, char *name); 

// examples:
// factor==10 would make the animation ten time slower
// factor==0.1 would make the animation ten time faster
//		 only if all the numbers in the array are bigger then 10 
// Say we have this times series 1, 2, 20
// now if we call with factor 0.1 we get the series 1, 1, 2
// Note !! If we call again with factor=10
// we get back the series we started with 1,1,2 => 1,2,20
// The mechanism is smart enough to deal with that.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_factor_speed(DWORD animation_handle, double factor);


// speed==1 means restore normal speed
// speed==2 means twice slower then normal speed
// speed==0.5 means twice faster then normal speed
//		animation frames are never skipped. See
//		remarks on Morfit_animation_factor_speed() to
//		understand the implication.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_set_speed(DWORD animation_handle, double speed);


MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_delete_all(void);

//Note that you cant use the handle after it was deleted
// A good practice will be like that:
//		Morfit_animation_delete(my_animation);
//		my_animation=NULL;
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_delete(DWORD animation_handle);


// sending YES will write the given background to file after call to Morfit_engine_save() with SAVE_ONLY_WHATS_NEEDED 
// Note that if Morfit_engine_save() is called without SAVE_ONLY_WHATS_NEEDED, all the animations will be saved
// Note ! If the animation is used directly by one of the polygons
// in the saved group it will be saved no matter how the save_flag is set !
// The need for this function is because though the engine can figure out itself
// what animations are needed to the saved group it doesn't know what animation will
// be needed in run time. Using this flag one can determine the animation resources
// to use in run-time.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_set_save_flag(DWORD animation_handle, int yes_no_flag); 

// returns YES or NO
// see Morfit_animation_set_save_flag() for more details
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_save_flag(DWORD animation_handle); 

//Returns the number of frames in the animation.
// On Error returns 0
// Example: Say we have an animation of a runner. The animation is combined
// from 5 bitmaps series, the runner from the front,45 degrees, side, 135 degrees, and from the back
// (look how it is defined in the wld file, FRONT, FRONT_SIDED, SIDE, BACK).
// Every series must contain the same number of bitmaps.
// calling this function will return the number of bitmap in each series.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_number_of_frames(DWORD animation_handle); 

//Returns the number of bitmaps in the animation.
// On Error returns 0
// Example: Say we have an animation of a runner. The animation is combined
// from 5 bitmaps series, the runner from the front,45 degrees, side, 135 degrees, and from the back
// (look how it is defined in the wld file, FRONT, FRONT_SIDED, SIDE, BACK).
// Every series must contain the same number of bitmaps.
// calling this function will return the number of bitmap in each series multiply by the number
// of series. 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_number_of_bitmaps(DWORD animation_handle); 

// This function returns an array with the handle to all the 
// bitmaps.
// bitmaps_array[] is an array of DWORD. This array will be filled with handles to
// all the bitmaps of the animation. 
// NOTE: you must allocate memory for the array before calling this function
// Example: 
//		int num_of_bitmaps=Morfit_animation_get_number_of_bitmaps(animation_handle);
//		// allocating mem using new or malloc etc ...
//		DWORD *bitmaps_array=(DWORD *)malloc(num_of_bitmaps*sizeof(DWORD));
//		Morfit_animation_get_all_bitmaps(animation_handle, bitmaps_array);
//
// Note that if a certain bitmaps is used twice by the animation, than its handle will
// appear twice in the bitmaps_array.
// handles 
MORFIT_IMPORT void MORFIT_WINAPI Morfit_animation_get_all_bitmaps(DWORD animation_handle, DWORD bitmaps_array[]); 

// Returns YES if the last world that was loaded, using Morfit_engine_load_world()
// or Morfit_engine_add_world().
// Returns NO otherwise 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_is_part_of_the_last_world(DWORD animation_handle); 

// Returns the number of polygons that are using the given bitmap
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_number_of_polygons_with_animation(DWORD animation_handle);


//Create a new animation that has the same bitmaps and timing as the given animation.
// Returns the new animation. If an error occurred, it will return NULL.
//
// Here are some ideas for using this function.
// You will need this function if you want to use the same animation but with different timing.
// For example, let say that your animation is a tree blowing in the wind. You probably
// have lots of trees and each of them use the same animation. Now if you dont want
// all the trees to move as one then you can do one of the following:
// 1) Use Morfit_polygon_set_animation_frame() to give each tree a different frame
// Or
// 2) Use this function to duplicate an animation and then to give different timing.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_animation_duplicate(DWORD animation_handle, char *new_name);

// This function can be used to replace the bitmap of a certain frame in the animation.
// bitmap_list: is one of the five constants: BITMAP_LIST_FRONT, BITMAP_LIST_FRONT_SIDED, BITMAP_LIST_SIDE, BITMAP_LIST_BACK_SIDED, BITMAP_LIST_BACK
// frame_index: 0 means the first frame. -1 has a special meaning, it means the last frame
// bitmap_handle: A handle of the bitmap that will be set for the given frame.
// See also Morfit_animation_get_bitmap()
// Return OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_set_bitmap(DWORD animation_handle, int bitmap_list ,int frame_index, DWORD bitmap_handle);


//The return value is The name of the bitmap without the extension 
// the bitmap_name is the name+path relative to the path given in Morfit_engine_load_world()
//If a bitmap exists in the world file
//but the engine couldnt find the bitmap file than it will still return its name.
//This is used when loading a world from the Internet, at first only the world is loaded
//and then we start streaming the bitmaps. We use this function to get the bitmap file name.
//If you want to check if the bitmap is in used then use Morfit_animation_get_handle()
MORFIT_IMPORT char *MORFIT_WINAPI Morfit_animation_get_frame_bitmap_name(DWORD animation_handle, int bitmap_list ,int frame_index);


//This function is very similar to Morfit_bitmap_get_transparent_index()
//For info check Morfit_bitmap_get_transparent_index()
//This function is needed only in the rare cases that some of the
//animation bitmaps could not be loaded when the world was loaded.
//For example when loading a world from the Internet, at first only the world is loaded
//and then we start streaming the bitmaps. We use this function to get the bitmap transparent index
//If you want to check if the bitmap is in used then use Morfit_animation_get_frame_bitmap_handle()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_animation_get_frame_transparent_index(DWORD animation_handle, int bitmap_list ,int frame_index);


//--------------------------------------------------------//
//=========== T H E   B I T M A P   A P I ================//
//--------------------------------------------------------//

// This API deals with bitmaps and the way they are used by the Engine


// Returns YES or NO.
// YES , if the given handle is a bitmap handle. NO if not.
// If it is not a bitmap handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_BITMAP()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_is_bitmap(DWORD bitmap_handle, char *function_asking);


// Returns a handle to a previously  loaded bitmap (using the file name)
// If the return value is NULL it means 
// that no bitmap with the given name and the given transparent index was loaded to the engine.
//Think of the transparent_index as part of the name 
//there could be several bitmaps with the same name but each can have a different
//transparent index. Note that the engine keeps a separate copy for each transparent index
//Example:
// Morfit_bitmap_get_handle("bitmaps\\people\\man12.bmp",-1);
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_bitmap_get_handle(char *file_name, int transparent_index);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_bitmap_get_first_bitmap(void); 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_bitmap_get_next(DWORD bitmap_handle); 

// File name extension (if given) is ignored. The engine will search
// for recognized extensions (jbm, bmp or jpg) and will load which ever
// exists. If the engine finds more then one recognized extension 
// (for example grass.bmp and grass.jpg) it will load the file
// which was most recently modified 
// If the specified bitmap was already loaded then it just retrieves
// its handle (in that case it is exactly like Morfit_bitmap_get_handle() )
// transparent_index should be -1 for no transparent and 0 
// for removing the most frequent color in the bitmap (usually
// the most used color is the background)
// transparent_index==1 means remove the second most used color etc ...
// Note the difference between this command and Morfit_utilities_load_bitmap_from_file()
// This command loads a bitmap into the engine, while Morfit_utilities_load_bitmap_from_file()
// is just an extension to the Win32 API making it easy to load a bitmap from
// the disk and to get its HBITMAP handle (a Win32 type)
// Examples:
//	A-
//		note that we dont have to give the bitmap extension 
//		if we do it is simply ignored
//		Morfit_bitmap_load("c:\\bitmaps\\my_bitmap",-1); 
//	B-
//		Load a bitmap and set the most used color as transparent
//		Morfit_bitmap_load("c:\\bitmaps\\my_bitmap",0); 
//	C-
//		Load a bitmap and set the second most used color as transparent
//		Morfit_bitmap_load("c:\\bitmaps\\my_bitmap",1); 
//
//	NOTE this case !
//	D-
//		This example has some good news and some bad news.
//		The good news is that if c:\\bitmaps\\grass27
//		is exactly the same as c:\\NEW_bitmaps\\grass27
//		Then we shouldnt worry about wasting memory by loading two identical bitmaps
//		When we try to load the second bitmap the engine
//		will see that it already has a bitmap with that name and
//		it will return the handle to the first loaded bitmap without doing anything.
//		The bad news is that if the bitmaps are different, the engine
//		wont overwrite the old one. It will just return the handle to the already
//		loaded bitmap without doing anything else.
//		handle1=Morfit_bitmap_load("c:\\bitmaps\\grass27",-1); 
//		handle2=Morfit_bitmap_load("c:\\NEW_bitmaps\\grass27",-1); 
//		if(handle1!=handle2) error_message(); //Never happens
//
//		A solution for this in case we want to overwrite the old bitmap
//		is to first delete the old bitmaps and then to load the new one.
//
//	E-
//		If we have two bitmaps in the same directory one is called
//		my_bitmap.jpg and the other is called my_bitmap.bmp
//		handle=Morfit_bitmap_load(my_bitmap.jpg,-1);
//		Note that the engine will load my_bitmap.bmp and not
//		my_bitmap.jpg. Thats because loading bitmaps in jpg format is much slower
//		And also because the jpg version of a bitmap is usually not as good as the original
//		(depending how much compression we used)
//
// see also Morfit_bitmap_rgb_color_to_index()
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_bitmap_load(char *file_name, int transparent_index);

// Returns the an index to a color in the palette that is the closest color
// to the given rgb. 
//This function can be used together with Morfit_bitmap_load() so the transparency color
//is calculated according to the rgb ...
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_rgb_color_to_index(DWORD bitmap_handle,BYTE red, BYTE green, BYTE blue);

//Receive an index to a color in the palette and returns its RGB.
//returns OK or VR_ERROR (returns VR_ERROR if the index is bigger (or equal) than the number of colors in the palette)
//See also Morfit_bitmap_get_memory()
// Example: //Get the rgb of the most used color in the bitmap (palette index 0)
// BYTE red,green,blue;
// Morfit_bitmap_index_to_rgb(my_bitmap, 0, &red, &green, &blue);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_index_to_rgb(DWORD bitmap_handle, BYTE index ,BYTE *red, BYTE *green, BYTE *blue);


// returns OK or VR_ERROR. VR_ERROR if there is no transparent color for this bitmap.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_transparent_rgb(DWORD bitmap_handle, int *red, int *green, int *blue) ;

// returns -1 if we transparent is not used for the given bitmap
// else return the index to the transparent color, usually it
// will be 0 which means that the most used color is the transparent color
// if the return value is 1 it means that the second most popular
// color is the transparent color etc ...
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_transparent_index(DWORD bitmap_handle) ;


//Create a new bitmap which is a resampled version of
//the given bitmap. If new_width and new_height are
// equal to the width and the height of the given
// bitmap, it will just duplicate the bitmap ...
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_bitmap_resample(DWORD source_bitmap_handle, int new_width, int new_height);

// dont ever use the handle after the bitmap was unloaded
MORFIT_IMPORT void MORFIT_WINAPI Morfit_bitmap_unload(DWORD bitmap_handle);

//Returns the name as it appears in the file (without the extension)
MORFIT_IMPORT char *MORFIT_WINAPI Morfit_bitmap_get_name(DWORD bitmap_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_number_of_polygons_using_bitmap(DWORD bitmap_handle);


MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_width(DWORD bitmap_handle);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_height(DWORD bitmap_handle);

//Using this function one can check and modify the actual pixels of the bitmap
//Returns an array of pixel indexes in the size of width*height
//see Morfit_bitmap_get_height() and Morfit_bitmap_get_width() to get the width and the height
//An index 255 means that it is a transparent color. an index of 0 means that this is the most
//frequently used color in the bitmap etc ...
// Here are few examples:
//	BYTE *bmp_ptr=Morfit_bitmap_get_memory(morfit_bitmap_handle);
//	int width=Morfit_bitmap_get_width(morfit_bitmap_handle);
//	for(int i=0; i<width; i++) bmp_ptr[0]=0; //setting the first line in the texture to have the rgb of index 0 in the palette
//	bmp_ptr[width]=255; //Setting the first pixel in the second line to be transparent
//						//Note that this bitmap must be a transparent bitmap for this to work.
//  BYTE last_pixel_index=bmp_ptr[width*height-1]; //examining the last pixel (bottom-down)
//	BYTE red,green,blue;
//  // Lets get the color of that pixel
//	Morfit_bitmap_index_to_rgb(morfit_bitmap_handle, last_pixel_index, &red,&green, &blue);
MORFIT_IMPORT BYTE * MORFIT_WINAPI Morfit_bitmap_get_memory(DWORD bitmap_handle);

// the palette is an array of WORDs; each 16 bits represents a pixel
// the most significant bits are red; the least significant are for blue (green in the middle)
// the RGB bit count for each color is 5-5-5 (the most significant bit not used)
// or 5-6-5. which one of them depends on the current graphics card you are using
// Use Morfit_utilities_rgb16_to_rgb24() to get the colors
// Example:
//		WORD *pal=Morfit_bitmap_get_palette(bm_handle);
//		BYTE red,green,blue;
//		Morfit_utilities_rgb16_to_rgb24(pal[0],&red,&green,&blue); //Return the rgb of the first color in the palette
//														 //Note that this color is the most frequent used color.
// See also Morfit_bitmap_index_to_rgb() that can be used to get specific color from the palette
MORFIT_IMPORT WORD * MORFIT_WINAPI Morfit_bitmap_get_palette(DWORD bitmap_handle);

//With this function you can change the colors of a bitmap.
//For example:
// The next line will set the most used color in my_bitmap (index 0 == the most used )to the color of red (red==255,0,0)
// Morfit_bitmap_set_palette_color(my_bitmap,0,   255,0,0 );
//Note that the bitmap memory is not modified. Only the palette is modified.
//For changing the bitmap itself see Morfit_bitmap_get_memory()
// Returns OK or VR_ERROR (returns VR_ERROR if the index is bigger (or equal) than the number of colors in the palette)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_set_palette_color(DWORD bitmap_handle, BYTE index_of_color_to_be_changed, BYTE red, BYTE green, BYTE blue);

// returns the number of colors in the palette
MORFIT_IMPORT int MORFIT_WINAPI Morfit_bitmap_get_palette_size(DWORD bitmap_handle);

// saves a bitmap on the disk.
// The file format is according to the extension
// ( Supported types by morfit.dll version 1.0 are windows bitmap (bmp) and jpeg (jpg) )
// If full_path_name==NULL than the bitmap will be save in the current directory
// in a windows bitmap file format.
// Examples: 
//	A- Morfit_bitmap_save( my_bitmap_handle, "c:\\John\\bitmaps\\grass.bmp");
//  B- Morfit_bitmap_save( my_bitmap_handle, "grass.jpg");
//  C- Morfit_bitmap_save( my_bitmap_handle, NULL);
//  D- Morfit_bitmap_save( my_bitmap_handle, "..\\grass.jbm");
MORFIT_IMPORT void MORFIT_WINAPI Morfit_bitmap_save(DWORD bitmap_handle, char *full_path_name);

//-------------------------------------------------------//
//======== T H E    T R A C K   A P I ===================//
//-------------------------------------------------------//

// Track is merely a sequence of points.
// cameras and objects can move on tracks in various  ways

// Returns YES or NO.
// YES , if the given handle is a track handle. NO if not.
// If it is not a track handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_TRACK()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_is_track(DWORD track_handle, char *function_asking);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_track_get_using_name(char *name);

// returns 1 if cyclic else returns 0
MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_is_cyclic(DWORD track_handle);

MORFIT_IMPORT char * MORFIT_WINAPI Morfit_track_get_name(DWORD track_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_set_name(DWORD track_handle, char *name);

MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_get_number_of_points(DWORD track_handle);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_track_get_first_track(void);

MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_track_get_next(DWORD track_handle);

//returns the point in pt[]
// returns VR_ERROR if the index is too big or negative
// else returns OK
MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_get_point(DWORD track_handle, int point_index, double pt[3]);

// point element can be 0 or 1 or 2
// 0 means get the x element. 1 ==> y. 2 ==>z
// note that if the point_index or the element number
// are out of range the function returns 0. there is no way 
// to know if the 0 is because of error or no.
MORFIT_IMPORT double MORFIT_WINAPI Morfit_track_get_point_element(DWORD track_handle, int point_index,  int point_element);

// Returns an the array of points
// Getting the array and accessing it yourself
// is a little faster then accessing each point separately
// the disadvantage is that your program could crash
// if you access the array with an out of range index
// indexes should be in the range 0,1,2 ... ,(number_of_points-1)*3+2
// Access example:
// points_array=Morfit_track_get_points(track_handle);
// x=points_array[point_index*3+0];
// y=points_array[point_index*3+1];
// z=points_array[point_index*3+2];
//
// The last index possible is 
// array[(number_of_points-1)*3 +2] we have  (number_of_points-1)  because we start with 0
// to get the number of points do:
// number_of_points=Morfit_track_get_number_of_points(track_handle);
// The function will always return the same address (array) for a given track.
MORFIT_IMPORT double *  MORFIT_WINAPI Morfit_track_get_points(DWORD track_handle);

// P is a point anywhere in space
// returns the index to the point on the track that
// is the closest.
// NOTE that if an object or a camera has a track and the track_offset is
// not (0,0,0) then you must do the following to get a correct result
//
//	P[0]=P[0]-track_offset[0];
//	P[1]=P[1]-track_offset[1];
//	P[2]=P[2]-track_offset[2];
//	index=Morfit_track_find_closest_point_on_track(track, P);
//	Morfit_track_get_point(track, index, pt);
//	pt[0]=pt[0]+track_offset[0];
//	pt[1]=pt[1]+track_offset[1];
//	pt[2]=pt[2]+track_offset[2];
//
MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_find_closest_point_on_track(DWORD track_handle, double P[3]);


// points_buffer contains the x,y,z of the points (example: x1,y1,z1, x2,y2,z2, x3,y3,z3 ....)
// note that if number_of_points==3 points we need array with 9 doubles (double points[9] )
// note that if track_name is not unique (there is already another track with the same name),
// the name will be modified so it will be unique. If you use the track name
// then it is a good practice to check the name after the track was created.
// or to make sure in advance that the name is unique.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_track_create(char *track_name, int is_cyclic, double *points_buffer, int number_of_points);

//It is the responsibility of the user that the points buffer is big enough for the number of points.
// The given buffer will be copied inside the engine
// points_buffer contains the x,y,z of the points (example: x1,y1,z1, x2,y2,z2, x3,y3,z3 ....)
// note that if number_of_points==3 points we need array with 9 doubles (double points[9] )
MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_set_points_buffer(DWORD track_handle, double *points, int number_of_points);

//It is the responsibility of the user that the points buffer is big enough.
// if the set number of points is bigger than the room in the points buffer, the
// program might crash.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_set_number_of_points(DWORD track_handle, int number_of_points);

// deletes a track
// be carful not to use this handle after it was deleted
// a good practice is to do like that:
//	Morfit_track_delete(my_track);
//  my_track=NULL;
//
MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_delete(DWORD track_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_delete_all(void);

// sending YES will write the given track to file after call to Morfit_engine_save() with SAVE_ONLY_WHATS_NEEDED 
// Note that it if Morfit_engine_save() is called without SAVE_ONLY_WHATS_NEEDED, all the tracks will be saved
// sending NO will cause  Morfit_engine_save() not to save this track (only if SAVE_ONLY_WHATS_NEEDED is used)
// The default value is NO
// see also Morfit_animation_set_save_flag()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_track_set_save_flag(DWORD track_handle, int yes_no_flag); 

// returns YES or NO
// The default value is NO
// see Morfit_track_set_save_flag() for more details
MORFIT_IMPORT int MORFIT_WINAPI Morfit_track_get_save_flag(DWORD track_handle); 

//-------------------------------------------------------//
//======== T H E    B A C K G R O U N D   A P I =============//
//-------------------------------------------------------//

// Background is the background on which the world is rendered.
// The idea is that you give a bitmap and the engine automatically 
// deals with it. For example when you turn around the engine shift the background
// image so it is not noticeable that it isnt part of the world.
// The engine also sees to it that you can turn 360 degrees without
// seeing the background edges ...
 

// Returns YES or NO.
// YES , if the given handle is a background handle. NO if not.
// If it is not a background handle , a message box will appear,
// the title of this message box will be the parameter "function_asking"
// if function_asking==NULL than no popup will be created.
// See also IS_BACKGROUND()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_background_is_background(DWORD background_handle, char *function_asking);


// The given name should be in capital letters
// If the return value is 0 it means 
// that there is no background with the given name.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_get_handle(char *background_name);


MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_get_first_background(void); 
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_get_next(DWORD background_handle); 

//creates a new background
//Returns a handle to the new background
//arguments:
// name: any string will do , example "my_sky"
// bitmap_handle: see Morfit_bitmap_load() for getting the handle
// Note that you have to call Morfit_background_use() so that the background will be shown
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_create(char *name, DWORD bitmap_handle);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_set_name(DWORD background_handle, char *name);

MORFIT_IMPORT char *MORFIT_WINAPI Morfit_background_get_name(DWORD background_handle);

//The purpose of the distance value is to make the background act more realistic
//by moving up and down according to the camera movement
//The distance value:
//The bigger this number is, the more apparent are the 
//changes in the height  of the background, 
//when the height of the camera changes.  The  background moves 
//up and down according to the height of the camera, to  make it 
//look real (example: If you have a car going up or down a hill, the sky's
//height must change(the sky is the background).) 
// example: Morfit_background_set_distance(bg_handle, 30000);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_set_distance(DWORD background_handle, double value); 

//The purpose of the distance value is to make the background act more realistic
//by moving up and down according to the camera movement
//The distance value:
//The bigger this number is, the more apparent are the 
//changes in the height  of the background, 
//when the height of the camera changes.  The  background moves 
//up and down according to the height of the camera, to  make it 
//look real (example: If you have a car going up or down a hill, the sky's
//height must change(the sky is the background).) 
MORFIT_IMPORT double MORFIT_WINAPI Morfit_background_get_distance(DWORD background_handle); 

//The bigger this number is, the background image will start from a higher
//place. The default is 0
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_set_bottom(DWORD background_handle, double value); 

MORFIT_IMPORT double MORFIT_WINAPI Morfit_background_get_bottom(DWORD background_handle); 




//return OK on success else VR_ERROR
// a value of 100 means normal brightness at the bottom of the background
// a value of 50 means a color that is the average between the background
// and the atmosphere color.
// a value of 200 means twice as bright than the original hue.
// feel free to test with different values.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_background_set_bottom_intensity(DWORD background_handle, double value); 

MORFIT_IMPORT double MORFIT_WINAPI Morfit_background_get_bottom_intensity(DWORD background_handle); 

//return OK on success else VR_ERROR
// the changes in the intensity for each scan line
// going from the bottom of the background up.
// 0 means no changes.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_background_set_intensity_step(DWORD background_handle, double value); 

MORFIT_IMPORT double MORFIT_WINAPI Morfit_background_get_intensity_step(DWORD background_handle); 

MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_delete(DWORD background_handle);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_delete_all(void); 

// Tell the engine to use the given background.
// A NULL handle means that we dont want to use any background
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_use(DWORD background_handle); 

//Returns the background handle that is currently in use
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_get_current_background(void); 

// sending YES will write the given background to file after call to Morfit_engine_save() with SAVE_ONLY_WHATS_NEEDED 
// Note that it if Morfit_engine_save() is called without SAVE_ONLY_WHATS_NEEDED, all the backgrounds will be saved
// sending NO will cause  Morfit_engine_save() not to save this background
// The default value is NO 
// Note that if it is used it will be saved no matter what the flag is
// see also Morfit_animation_set_save_flag()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_set_save_flag(DWORD background_handle, int yes_no_flag); 

// returns YES or NO
// The default value is NO 
// see Morfit_background_set_save_flag() for more details
MORFIT_IMPORT int MORFIT_WINAPI Morfit_background_get_save_flag(DWORD background_handle); 

//Replace the bitmap of the background with the given bitmap.
//See also Morfit_bitmap_load()
MORFIT_IMPORT void MORFIT_WINAPI Morfit_background_set_bitmap(DWORD background_handle, DWORD bitmap_handle); 

// Returns a handle to the bitmap that is in use by the given background.
MORFIT_IMPORT DWORD MORFIT_WINAPI Morfit_background_get_bitmap(DWORD background_handle); 

// Returns the name of the bitmap. Note the difference between calling Morfit_background_get_bitmap()
//and then getting the bitmap name using Morfit_bitmap_get_name()
// The difference is that here we will get the name even if the bitmap was not loaded yet.
// For example when our world is on the Internet then we first download the world and only then 
// the bitmaps are downloaded. If we call this function we would still get the name even though the bitmap wasn't
// loaded to the engine yet. If you didnt understand this explanation then relax, it is not so important.
MORFIT_IMPORT char * MORFIT_WINAPI Morfit_background_get_bitmap_name(DWORD background_handle); 


//-------------------------------------------------------//
//======== T H E     E N T I T Y      A P I =============//
//-------------------------------------------------------//

//This API contains functions that already exist in other Morfit APIs.
//The idea is that one function can serve all API. For example the Morfit_entity_get_name()
//can get the name of a camera, an object a group etc ... Some people use this API a lot and
//other dont use it at all. Both ways are fine.


//Gets the name of the entity.
//entity could be a handle to one of the following camera,group,object,track,background,bitmap
//The requested name is copied to the given buffer.
//buffer_size is the buffer size in bytes. If this value is shorter than the requested name
//then the name will be truncated.
//The return value is the length of the name
MORFIT_IMPORT int MORFIT_WINAPI Morfit_entity_get_name(DWORD entity, char *buffer, int buffer_size);


//-------------------------------------------------------//
//======== T H E    3 D  C A R D      A P I =============//
//-------------------------------------------------------//

// This API include specific functions for working with the 3D accelerator.
// We tried to make the existence of the card transparent to the programmer
// so that things should work exactly the same with card or without.

//Note that some of the function exist also in the engine API
//those function do exactly the same. It is preferred if you use just the function from this
//API.

// return YES or NO
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_check_hardware_support(void);


// Get YES or NO. Returns OK or VR_ERROR
// If gets YES, the function will look for a 3D card installed on the computer
// if it wont find, the function will return VR_ERROR.
// It is a good practice to call Morfit_3D_card_use(NO);
// before you exit your application.
// The default is NO.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_use(int YES_or_NO);

//Returns YES if a 3D accelerator card is in use.
//Returns NO if software rendering is used.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_is_used(void);


//Set full screen mode and the desktop resolution
// Returns OK or VR_ERROR
// here are four Examples:
// Morfit_3D_card_set_full_screen_mode(1024,768);
// Morfit_3D_card_set_full_screen_mode(800,600);
// Morfit_3D_card_set_full_screen_mode(640,480);
// Morfit_3D_card_set_full_screen_mode(320,200);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_set_full_screen_mode(int resolution_x, int resolution_y);


//Returns YES if the 3D card is programed to use fullscreen.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_is_full_screen_mode(void);

//This is the default. Can be called instead, before or after Morfit_3D_card_use(YES);
//returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_set_window_mode(void);


/* 
//	The functions below are used with full screen modes
//
//example:
//	if(Morfit_3D_card_set_resolution(800, 600)==VR_ERROR) return(VR_ERROR);
//	if(Morfit_3D_card_use(YES)==VR_ERROR) return(VR_ERROR);
//
//	The default is 640x480
//	Note that if the card doesnt support this resolution, it will set the closest
//  resolution to the given one. You can call Morfit_engine_get_3D_accelerator_resolution()
//	to check what was actually set.
//	Returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_3D_card_set_resolution(int width, int height);

//Returns the current setting for the 3D accelerator card.
//example:
// int res_x, res_y;
// Morfit_engine_get_3D_accelerator_resolution(&res_x,&res_y);
// output_message("The current resolution setting for 3D hardware is %d X %d \n",res_x,res_y);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_card_get_resolution(int *width, int *height);


//Set the area on the screen that will be used to display the rendered image.
//the default is top_left={0,0}, and bottom_right={ card_resolution_x -1, card_resolution_y -1 }
// Example:
//		Morfit_3D_card_set_rendering_window(100,100,299,299);
//
//		// Do some stuff like Morfit_engine_render( ...)
//		// Now say we want to restore the default (full screen rendering)
//		int width,height;
//		Morfit_3D_card_get_resolution(&width, &height);
//		Morfit_3D_card_set_rendering_window(0,0,width-1,height-1);
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_card_set_rendering_window(int minx, int miny, int maxx, int maxy);

// The x,y coords of the top left corner are given by (top_left[0],top_left[1])
// The x,y coords of the bottom right corner are given by (bottom_right[0],bottom_right[1])
// The x,y coords should be in the range according to the current resolution
//		(Morfit_3D_card_get_resolution() and Morfit_3D_card_set_resolution() )
//		if they are not in the range they will be cliped (it is ok ...).
MORFIT_IMPORT void MORFIT_WINAPI Morfit_3D_card_paste_bitmap(DWORD bitmap_handle, int top_left[2], int bottom_right[2]);

*/
//-------------------------------------------------------//
//======== T H E    U T I L T I E S   A P I =============//
//-------------------------------------------------------//

// The function in this API have nothing to do with the 
// Morfit VR_Engine ! You can think of them as an extension to the 
// WIN32 API.
// They are here because they are useful in many applications especially
// applications that use lots of graphics.


//Loads a file into memory.
//returns a pointer to the allocated memory and the size of the file
//If the file could not be loaded a NULL is returned
//This file can be also treated as a string (there will always be a terminating NULL ...).
//Example:
//		int file_size;
//		char *buff=(char *)Morfit_utilities_file_to_memory("help.txt", &file_size);
//		MessageBox(NULL,buff,"Help", MB_OK);
//		Morfit_utilities_free_file_memory(buff);
MORFIT_IMPORT BYTE *MORFIT_WINAPI Morfit_utilities_file_to_memory(char *file_name, int *file_size);

//Used together with Morfit_utilities_file_to_memory() to free memory
//that we don't need any more.
//note that "void *mem_ptr" is a pointer to void which means
//that it will accept any type of pointer.
MORFIT_IMPORT void MORFIT_WINAPI Morfit_utilities_free_file_memory(void *mem_ptr);

// stretch a bitmap on the given window
// border_to_leave is usually 0. We can give a
// different value if we want to keep the window
// frame lines visible.
// if border_to_leave==0 then all the window
// will be covered by the bitmap. if border_to_leave
// is equal to 2 (for example) then there will be 
// a border of two pixels left from each side.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_paste_resource_bitmap(HWND hwnd, UINT bitmap_resource_id, int border);

// You can use Morfit_utilities_load_bitmap_from_file() to get a handle to the bitmap and then to use this function
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_paste_bitmap(HWND hwnd, HBITMAP bitmap_handle, int border);

// This is a very useful function.
// It can be used for pasting 2D bitmaps on the rendered image
// For example an image denoting the health condition of the player
// or the existence of ammunition
// The function copies a bitmap on the given device context.
// Use Morfit_utilities_load_bitmap_from_file() to get a handle to the bitmap (HBITMAP)
// Use Morfit_engine_render_on_dc() to get the device context handle (HDC hdc)
//
// Parameters:
//
// hdc:				a handle to the device context. usually you would obtain this
//					handle from calling hdc=Morfit_engine_render_on_dc()
//		
// hbm:				a HBITMAP handle of the bitmap. you can use 
//					Morfit_utilities_load_bitmap_from_file() to get
//					the handle.
//
// x,y:				the coordinate where the bitmap should be placed
//
// bm_stretch_width,
// bm_stretch_height:	Using these params you can stretch the bitmap
//						If you dont want to stretch the bitmap give -1
//						
//
// Examples:
//
// A) 
//	//Copy the bitmap to the top left corner of the window
//	Morfit_utilities_copy_bitmap_on_dc(hdc, hbm, 0,0, -1,-1);
//
// B) 
//	//Copy the bitmap to the top left corner of the window
//	//The bitmap will be stretched to a 100x100 square size (size in pixels)
//	Morfit_utilities_copy_bitmap_on_dc(hdc, hbm, 0,0, 100, 100);
//
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_copy_bitmap_on_dc(HDC hdc, HBITMAP hbm, int x, int y, int bm_stretch_width, int bm_stretch_height);


// This function has nothing to do with Morfit graphics engine
// Think of it as an extension to the Win32 API.
//
//It is also possible to load a jpeg file (*.jpg).
// If bitmap_file_name ends with ".jpg" and there is no file with the same name only with a .bmp extension 
// in the same directory then the function will load the jpg file
//
// Note the difference between this command and Morfit_bitmap_load()
// Morfit_bitmap_load() command loads a bitmap into the engine, while Morfit_utilities_load_bitmap_from_file()
// is just an extension to the Win32 API making it easy to load a bitmap from
// the disk and to get its HBITMAP handle (a Win32 type)
//
MORFIT_IMPORT HBITMAP  MORFIT_WINAPI Morfit_utilities_load_bitmap_from_file(char *bitmap_file_name);


// This function has nothing to do with Morfit graphics engine
// Think of it as an extension to the Win32 API.
//
// bitmap_ile_name should have a bmp extension.
//returns OK or VR_ERROR
MORFIT_IMPORT int MORFIT_WINAPI Morfit_utilities_save_bitmap(HBITMAP hbm, char *bitmap_ile_name);


//Creates a new bitmap file
//The new bitmap file is a resampled version of the source bitmap file
//The given bitmap file should be in 8 bit per pixel or 24 bit per pixel file format.
// The return value is OK or VR_ERROR
// Example:
// Morfit_utilities_resample_bitmap("C:\\morfit\\logos\\biglogo.bmp", "..\\small_logo.bmp", 32,32);
// This would create a 32x32 bitmap file in the name small_logo.
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_utilities_resample_bitmap(char *source_bitmap_file, char *new_bitmap_file_name, int new_width, int new_height);

//convert a jpg files into 256 colors bitmap
// returns OK or VR_ERROR;
//example:
// rc=Morfit_utilities_jpg2bmp("bitmaps\jpeg\horse.jpg");
// This will create a 256 colors bitmap with the name horse.bmp
// the bitmap will be created in the same directory of horse.jpg
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_utilities_jpg2bmp(char *jpg_file_name);

//Like Morfit_utilities_jpg2bmp() only the other way around.
// Note that the bitmap should be 256 colors
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_utilities_bmp2jpg(char *bmp_file_name);

// The output format is determined according to the extension of the output file
// The same with the input file format.
// example Morfit_utilities_convert_3d_formats("test.x", "test.mft", "", SAVE_BITMP_AS_JPG);
// Note that this function just do Morfit_engine_load_world() and Morfit_engine_save()
// and that means that any world that is currently in the engine will be unloaded
// and the input_file_name world will be.
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_utilities_convert_3d_formats(char *input_file_name, char *world_directory_path, char *bitmaps_directory_path, char *output_file_name, int save_flags);

//Convert a 16bit rgb color to 24bit rgb. The result is return through red,green and blue.
//See also Morfit_bitmap_get_palette();
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_rgb16_to_rgb24(WORD rgb16, BYTE *red, BYTE *green, BYTE *blue);

//Returns YES or NO.
MORFIT_IMPORT int  MORFIT_WINAPI Morfit_utilities_is_windows98(void);


// gets an address and display its content
// size is the size of the given buffer in bytes.
// You can use this function for debugging if you have problems interfacing the dll.
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_test_address(BYTE *mem_address, int size);

//Test receiving a string. the string that is received is "Testing string transfer"
MORFIT_IMPORT char *MORFIT_WINAPI Morfit_utilities_test_string(void);

//popup a dialog with the given string
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_test_LPSTR(LPSTR str);

//popup a dialog with the given string
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_test_LPCSTR(LPCSTR str);

//popup a dialog box with the given pointer and the value it points at
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_test_PDWORD(DWORD *ptr);

//popup a dialog box with the given pointers and the value they point at
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_utilities_test_2PDWORD(DWORD *ptr1, DWORD *ptr2);

//-----------------------------------------------------//
//==+++====== T H E    M A T H   A P I ===========+++==//
//-----------------------------------------------------//

// The function in this API have nothing to do with the 
// Morfit VR_Engine ! You can think of them as an extension to the 
// WIN32 API.
// They are here because they are useful in many applications especially
// applications that use 3D graphics.


// Constants for the math API
#define	ON_PLANE 				1//on the same plane
#define	IN_BACK_OF_PLANE        2
#define	IN_FRONT_OF_PLANE       3
#define	CUTS_PLANE     			4



// returns the distance between two points in the power of two
// example: p1=(0,0,0) p2=(10,0,0)
// the distance is 10 so the return value will be 100 
// see also Morfit_math_get_distance() which is the same only it
// calls sqrt() at the end.
MORFIT_IMPORT double  MORFIT_WINAPI Morfit_math_get_square_distance(double p1[3], double p2[3]);

// returns the distance between two points
// example: p1=(0,0,0) p2=(10,0,0)
// the distance is 10 so the return value will be 10
// If speed is important it is better to use Morfit_math_get_square_distance()
// which is much faster because it doesn't do the sqrt()
MORFIT_IMPORT double  MORFIT_WINAPI Morfit_math_get_distance(double p1[3], double p2[3]);

// stores the result in "intersection_point" which is valid in all cases
// pt1 and pt2 are two points on a line
// return value:
// YES if pt1 and pt2 are in different sides of the plane
//		in this case intersection_point will be the expected intersection point
// NO if pt1 and pt2 are on the same side of the plane
//	 in this case intersection_point will be the intersection point if the infinite line that contains p1 and p2
//
// NO if the line is on the plane. 
//		In this case the intersection point will be pt1
//
// YES, If one edge of the segment is on the plane (and the other one is not).
//
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_does_segment_intersect_plane(double pln[4],double pt1[3], double pt2[3], double intersection_point[3]);

// Return the distance between point P and the line going through points A and B.
MORFIT_IMPORT double MORFIT_WINAPI Morfit_math_get_distance_between_point_and_line(double P[3], double A[3], double B[3]);

// P is a point
// AB is a line
// The result is returned through closest_point_on_line
//	 closest_point_on_line is the a point on the line defined by A and B that is closest to P
// Returns OK or VR_ERROR (error if point A is equal to point B)
// Example:
//	P[0]=1; P[1]=2; P[2]=30;
//	A[0]=10; A[1]=20; A[2]=30;
//	B[0]=100; B[1]=200; B[2]=300;
//	double  closest_point_on_line[3];
//  Morfit_math_get_closest_point_on_line(P,A,B,closest_point_on_line);
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_get_closest_point_on_line(double P[3], double A[3], double B[3], double closest_point_on_line[3]);


// return YES or NO
// Returns YES if point pt is on the given line segment 
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_is_point_on_segment(double pt[3], double segment_start[3], double segment_end[3]);

// Get three points and calculate their plane equation (the plane equation: Ax+By+Cz+D=0 )
// Note that (pln[0],pln[1],pln[2]) are the normal of the plane.
// The direction of the normal (there are two possibilities) is determined according to
// the direction of the points. The Normal will point towards the side in which the points will be in clockwise order
// The return value is OK or VR_ERROR. note that we will get VR_ERROR if
// the points are on the same line or are all equal.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_points_to_plane(double pln[4], double p1[3], double p2[3], double p3[3]);

// Gets a plane equation (Ax+By+Cz+D=0 ) and a point
// and returns the following constants 
// ON_PLANE (if the point is on the plane)
// IN_BACK_OF_PLANE
// IN_FRONT_OF_PLANE
// The side which is called front is the side that the normal of the plane points towards)
// (the normal is: N=(pln[0], pln[1], pln[2]);
// the argument thickness is the thickness of the plane (actually half of the width of the plane).
// If for example thickness==6 than all the points that their distance from the plane
// is 6 or less will result a return value of ON_PLANE.
// Usually you will call this function with thickness==0
// But if you want to check whether a point is on the plane you
// should call this function with thickness bigger than 0 (for example 0.0001) 
// and thats to avoid floating point errors (if the plane was created using
// three points and you took only 6 decimal places after the decimal point then the
// plane equation wont be 100% accurate, there is also a limit to the accuracy
// of floating points numbers in a binary world)
// You can also call this function with a negative thickness though 
// it is not so useful, in this case the half of the space which is considered in front of the plane
// will get bigger ... In this case you will never get ON_PLANE)
// Note also that this function is extremely fast.
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_get_plane_point_relations(double pln[4], double pt[3], double thickness);


// Takes three points and returns whether they are in clockwise order or not
// when looking from above (looking in direction 0,0,-1). If all the points
// have the same x or y values then one cant tell (when looking from above) if it is clockwise
// so in this case we look from front (looking in direction 0,0,-1) and if
// that doesn't succeed we look from the right side (looking in direction 0,-1,0)
// Returns YES or NO
// Note that the three points create a plane and from each side of the plane
// what is clockwise is exactly the other way around.
//
// If you want to check if the points are clockwise from a given point
// use Morfit_math_get_plane_point_relations() like that
// create a plane from the three points and call the function when the point
// in which you look from is the given point.
 MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_is_clockwise(double p1[3], double p2[3], double p3[3]);

// return if points are in clockwise when
// looking on the three points from the given direction.
// The given direction doesn't have to be normalized.
// see also is_clockwise()
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_is_clockwise_from_direction(double view_direction[3], double p1[3], double p2[3], double p3[3]);

// Calculates the ray that reflects from a surface according to the
// physic law: the hitting angle is equal to the reflected angle.
// Arguments:
// normal is the normal of the plane that the ray hits.
// hitting_ray is the ray that hits the plane
// the result is given in reflected_ray (the result is normalized)
// return value: OK, or VR_ERROR (in case of an error).
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_get_reflected_direction(double normal[3], double hitting_ray[3], double reflecting_ray[3]);


//Returns the scalar product between two vectors.
//The return value is the length of the first vector multiply by
//the length of the second multiplied by the cosine of the angle between the
//two vectors.
//In a formula way it looks like that:
// return value= scalar_product= |vec1|*|vec2|*cos(alpha) . Alpha is the angle between the vectors
//For more information about scalar products see your math book (look for Linear Algebra and vectors)
MORFIT_IMPORT double MORFIT_WINAPI Morfit_math_product(double vec1[3], double vec2[3]);

//Returns the cross product between vec1 and vec2.
//The result is returned in the argument "result"
//The returned vector is a vector that is perpendicular both to vec1 and vec2
//The length of the returned vector is equal to
//The length of vec1 multiplied by the length of vec2 multiplied by
//the sinus of the angle between the two vectors.
//For more information about scalar products see your math book (look for Linear Algebra and vectors)
MORFIT_IMPORT void MORFIT_WINAPI Morfit_math_cross(double vec1[3], double vec2[3], double result[3]);

//returns OK or VR_ERROR
//normalize the vector. This means make it a unit vector.
//In other words the direction of the vector will stay the same
//but its length will become one
//example:
//		double vec[3]={6,8,0} //length==10
//		Morfit_math_normalize_vec(vec);
//		//Now the vec will be equal to { 0.6, 0.8, 0} (length==1)
MORFIT_IMPORT int MORFIT_WINAPI Morfit_math_normalize_vector(double vec[3]);

//Returns the length (magnitude) of the vector
MORFIT_IMPORT double MORFIT_WINAPI Morfit_math_get_vector_length(double vec[3]);

//-----------------------------------------------------//
//======== T H E    P R O F I L E R   A P I =============//
//-----------------------------------------------------//

// One of the most important issue in many applications that use 3D graphics
// is Performances.
// This API makes it extremely easy to time any function (not just Morfit's functions)
// using two macros.
// Here is an example of how to do it.
//
//		MORFIT_START_TAKING_TIME("2d point to 3D"); //The text that is given here will appear in the log file profiling summery
//		any_function_that_you_would_like_to_time(...); //calling the function that we want to time
//		MORFIT_STOP_TAKING_TIME();
//
// Note that the result of the profiling will be written automatically
// to the log file (look for the file log.log in your executable working directory)
// Note also that these macros will only work in C++, when writing in C
// do this instead:
//
//   static int time_id=-1;
//		time_id=Morfit_profiler_start_measuring(time_id,"some text");
//		any_function_that_you_would_like_to_time(...); //calling the function that we want to time (you can any function not just functions of Morfit)
//		Morfit_profiler_end_measuring(time_id);


MORFIT_IMPORT int MORFIT_WINAPI Morfit_profiler_start_measuring(int time_id, char *name);

MORFIT_IMPORT void MORFIT_WINAPI Morfit_profiler_end_measuring(int time_id);

#define MORFIT_START_TAKING_TIME(name)\
	{\
		  static int time_id=-1;\
		  time_id=Morfit_profiler_start_measuring(time_id, name);

#define MORFIT_STOP_TAKING_TIME() Morfit_profiler_end_measuring(time_id); }


//-----------------------------------------------------//
//======== T H E    G A R B A G E   A P I =============//
//-----------------------------------------------------//

// NOTE !!!!!!
//Functions in the Garbage API are just test function that
// will be deleted soon.


// All what is below should be removed
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_garbage_set_joystick_button1(void);
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_garbage_set_joystick_button2(void);

// ZZZ to delete this function when we take the contents out of the dll
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_garbage_keyboard_event(UINT nchar);

//I use it to check save in X format
MORFIT_IMPORT void  MORFIT_WINAPI Morfit_garbage_test1(char *file_name);




//-----------------------------------------------------//
//========   H E L P   A P P E N D I C E S  ===========//
//-----------------------------------------------------//




//	The *.flt file format
//	---------------------
/*
	example *.flt file:
	255 255 0
	4000
	3  30000
	3	20000
	In the first line there is the RGB of the transparent color.
	In the second line there is the 
	scope/interval of the transparent color
	in other words if we do distance=(r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2
	when ^2 means  the power two. r1,g1,b1 is the transparent color rgb
	(r2,g2,b2) is a color from the bitmap. we now define how close this 
	color can be to the transparent color
	In the third line and till the end there are 2 integers in each line;
	lets call them n and d
	after this program converts all
	the colors that are near the transparent. We make another round
	where we take all the colors that have n transparent neighbors
	and convert them to transparent this time we allowed a
	the distance to be up to d
	if there is no third line it is also OK (it wont do a second path)
	the next lines are similar to the third line
	each additional line will cause another filtering pass);

*/







#ifdef __cplusplus
}
#endif



#endif MRFT_API_H