⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 export.cpp

📁 3dmax导出3d模型二次开发插件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//************************************************************************** 
//* Export.cpp	- Virtools File Exporter
//*
//* Romain Sididris - Copyright (c) Virtools 2000 
//*
//* (Based on Ascii File Exporter source code
//*  By Christer Janson
//*  Kinetix Development
//*  Copyright (c) Kinetix 1997, All Rights Reserved. )
//*
//* This module contains the main export functions
//*
//***************************************************************************
#include "Precomp.h"
#include "Max2Nmo.h"

#include "bitmap.h"
#include "icustattribcontainer.h"



#ifdef MAX51
#include "PBBitmap.h"
#include "d3dx8.h"
#include "IViewportManager.h"
#endif


extern BOOL		g_CharacterStudio312;

_inline unsigned long	GetMSB(unsigned long data);


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

  Convenient Functions For Lightmap Manipulation
  
****************************************************************************/
#ifdef MAX51

class LM {
protected:	
	enum { lightmap_params };
	
	enum { 
		pb_light_texture,
		pb_diffuse_texture,
		pb_diffuse_mapping,
		pb_lightmap_filename,
		pb_diffuse_filename,
		pb_lightmap_on,
		pb_diffuse_on,
		pb_lightmap_mapping,
	};
	
	static IParamBlock2* GetLightMapParameters( Mtl* mtl ){
			
		//--- Find Effects
		IDXShaderManagerInterface* shaderManager = GetDXShaderManager();
		if( !shaderManager ) return NULL;
		
		CustAttrib *cust = shaderManager->FindViewportShaderManager(mtl);
		if( !cust ) return NULL;
		
		IViewportShaderManager* viewShader = (IViewportShaderManager *)(cust->GetInterface(VIEWPORT_SHADER_MANAGER_INTERFACE));
		if( !viewShader ) return NULL;
		
		ReferenceTarget* rt = viewShader->GetActiveEffect();
		if( !rt ) return NULL;
		
		//--- if it's a lightmap material
		#define LIGHTMAP_CLASS_ID	Class_ID(0x727d33be, 0x3255c000)
		if( rt->ClassID() == LIGHTMAP_CLASS_ID ){
			
			//--- Get Parameter Block Info
			IDXDataBridge* db = (IDXDataBridge*)(rt->GetInterface( VIEWPORT_SHADER_CLIENT_INTERFACE ));
			if( !db ) return NULL;

  			return rt->GetParamBlockByID( lightmap_params );
		}
		return NULL;	
	}

public:	
	static BOOL ShaderEnabled( Mtl* mtl ){
		return ( GetLightMapParameters( mtl ) != NULL );
	}
	
	//--- Read Base Texture Parameters
	static BOOL BaseTextureEnabled( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		BOOL diffuseOn = FALSE;
		pblock->GetValue( pb_diffuse_on, 0, diffuseOn, FOREVER);
		return diffuseOn;
	}
	
	static const char* BaseTextureFilename( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		TCHAR* diffuseFilename;
		pblock->GetValue( pb_diffuse_filename, 0, (TCHAR*&)diffuseFilename, FOREVER );
		return diffuseFilename;
	}
	
	static int BaseTextureMapping( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		int diffuseMapping = 1;
		pblock->GetValue( pb_diffuse_mapping, 0, diffuseMapping, FOREVER);
		return diffuseMapping;
	}
	
	//--- Read Lightmap Texture Parameters
	static BOOL LightmapTextureEnabled( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		BOOL lightOn = FALSE;
		pblock->GetValue( pb_lightmap_on, 0, lightOn, FOREVER);
		return lightOn;
	}
	
	static const char* LightmapTextureFilename( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		TCHAR* lightFilename;
		pblock->GetValue( pb_lightmap_filename, 0, (TCHAR*&)lightFilename, FOREVER );
		return lightFilename;
	}
	
	static int LightmapTextureMapping( Mtl* mtl ){
		IParamBlock2* pblock = GetLightMapParameters(mtl);
		int lightMapping = 3;
		pblock->GetValue( pb_lightmap_mapping, 0, lightMapping, FOREVER);
		return lightMapping;
	}
};
#endif // MAX51


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

  GeomObject output (Geom objects are tri or patch based meshes)
  
****************************************************************************/
void Max2Nmo::ExportGeomObject(INode* node)
{
	ObjectState os = node->EvalWorldState(GetStaticFrame());
	if (!os.obj)
		return;
	
	// Targets are actually geomobjects, but we will export them
	// from the camera and light objects, so we skip them here.
	if (os.obj->ClassID() == Class_ID(TARGET_CLASS_ID, 0))
		return;
	
	BOOL Biped = FALSE;
	BOOL SaveMesh = TRUE;
	Control* tmC = node->GetTMController(); 
	if ((tmC->ClassID()== FOOTPRINT_CLASS_ID) || (tmC->ClassID()== BIPSLAVE_CONTROL_CLASS_ID) || (tmC->ClassID()== BIPBODY_CONTROL_CLASS_ID)) {
		Biped = TRUE;
	}
	



	CK3dEntity* Entity = NULL;

	if (GetExportAsCharacter())
		Entity = (CK3dEntity*)VirtoolsExporter->AddCharacterBodyPart(node->GetName(),node);
	else
		Entity = (CK3dEntity*)VirtoolsExporter->Add3dObject(node->GetName(),node);
		

	ExportNodeBase(node, Entity);

	if (!Biped || GetSaveBipedGeom()) {
		if (os.obj->ClassID() == Class_ID(PATCHOBJ_CLASS_ID, 0))
			ExportPatchMesh(node,Entity);
		else
			ExportMesh(node,Entity);
	} else {
		Report(REPORT_HLEVEL,"%sBiped Object: %s.....",StrGroupIndent().Str(),node->GetName());
	}

	if (Biped && !GetSaveBipedGeom() ) Entity->Show(CKHIDE);
	// Rename the floor reference object
	if (tmC->ClassID() == FOOTPRINT_CLASS_ID) {
		Entity->SetName("FloorRef");
	}

	ExportAnimKeys(node,Entity);
	Report(REPORT_HLEVEL,"...Done\r\n");
}	

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

  Shape (Curve) output
  
****************************************************************************/
void Max2Nmo::ExportShapeObject(INode* node)
{
	TimeValue t = GetStaticFrame();
	ObjectState os = node->EvalWorldState(t);
	if (!os.obj || os.obj->SuperClassID()!=SHAPE_CLASS_ID) {
		return;
	}

	Report(REPORT_HLEVEL,"%sCurve : %s.....",StrGroupIndent().Str(),node->GetName());

	int deleteIt;
	SplineShape *pSplineShape = GetSplineShapeFromNode(node,t,deleteIt);

	Matrix3 ObjectTM = node->GetObjectTM(t);
	if(pSplineShape && pSplineShape->shape.SplineCount()==1) {
		// We only convert if the shape contains only one spline
		
		Spline3D* spline3D = pSplineShape->shape.GetSpline(0);
		if(spline3D) {
			CKCurve* VirtoolsCurve = VirtoolsExporter->AddCurve(node->GetName(),node);
			int KnotCount = spline3D->KnotCount();

			for (int i=0; i<KnotCount;++i) {
				CKCurvePoint* pt = VirtoolsExporter->AddCurvePoint(VirtoolsCurve,NULL,NULL);
				
				SplineKnot SKnot =  spline3D->GetKnot(i);
				Point3 WorldKnot = ObjectTM.PointTransform(SKnot.Knot());
				int KnotType = SKnot.Ktype();
				int SegType = SKnot.Ltype();
				// Max and Virtools tangents conversion =>
				// scale by a factor of 3 ?????
				Point3 WorldInTan	= -spline3D->GetRelInVec(i)*3.0f;
				Point3 WorldOutTan  = spline3D->GetRelOutVec(i)*3.0f;

				if (KnotType != KTYPE_AUTO) {
					pt->UseTCB(FALSE);
					pt->SetTangents(&VxVector(WorldInTan.x,WorldInTan.z,WorldInTan.y),
									&VxVector(WorldOutTan.x,WorldOutTan.z,WorldOutTan.y));
				}

				if (SegType == LTYPE_LINE)	pt->SetLinear(TRUE);



				// Swap Y & Z to reflect referential changes between Max and Virtools
				pt->SetPosition(&VxVector( WorldKnot.x,WorldKnot.z,WorldKnot.y),NULL,TRUE );
			}
			if (spline3D->Closed()) VirtoolsCurve->Close();

			ExportNodeBase(node,VirtoolsCurve);
			ExportAnimKeys(node,VirtoolsCurve);
		}

		// Deletes created shape
		if (deleteIt) 	pSplineShape->DeleteMe();
	}
	Report(REPORT_HLEVEL,"Done\r\n");


}


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

  Light output
  
****************************************************************************/
void Max2Nmo::ExportLightObject(INode* node)
{
	TimeValue t = GetStaticFrame();
	ObjectState os = node->EvalWorldState(t);
	if (!os.obj) return;

	Report(REPORT_HLEVEL,"%sLight : %s.....",StrGroupIndent().Str(),node->GetName());

	GenLight* light = (GenLight*)os.obj;
	struct LightState ls;
	Interval valid = FOREVER;
	Interval animRange = ip->GetAnimRange();
	light->EvalLightState(t, valid, &ls);


	INode* target = node->GetTarget();

	VXLIGHT_TYPE	LightType   = VX_LIGHTPOINT;

	switch(ls.type) {
		case OMNI_LIGHT:  LightType   = VX_LIGHTPOINT; break;
		case TDIR_LIGHT:
		case DIR_LIGHT:   LightType   = VX_LIGHTDIREC; break;
		case TSPOT_LIGHT: 
		case FSPOT_LIGHT: LightType   = VX_LIGHTSPOT; break;
	}

	CKLight* VirtoolsLight			= NULL;
	CK3dEntity* VirtoolsLightTarget = NULL;

	// Virtools Objects creation
	VirtoolsLight = (CKLight*)VirtoolsExporter->AddLight(target? TRUE:FALSE,LightType,node->GetName(),node);
	ExportNodeBase(node, VirtoolsLight);

	if (target && (LightType  == VX_LIGHTSPOT)) {
		VirtoolsLightTarget = ((CKTargetLight* )VirtoolsLight)->GetTarget();
		ExportNodeBase(target, VirtoolsLightTarget);
	}
		
	VirtoolsLight->SetColor(VxColor(ls.color.r,ls.color.g,ls.color.b));
	VirtoolsLight->SetRange(ls.attenEnd);
	VirtoolsLight->SetSpecularFlag(ls.affectSpecular);
	VirtoolsLight->Active(ls.on);
	VirtoolsLight->SetHotSpot(DegToRad(ls.hotsize));
	VirtoolsLight->SetFallOff(DegToRad(ls.fallsize));


// Export animation keys for the light node
	ExportAnimKeys(node,VirtoolsLight);
		
// If we have a target, export animation keys for the target too.
	if (target && VirtoolsLightTarget) {
		ExportAnimKeys(target,VirtoolsLightTarget);
	}
	Report(REPORT_HLEVEL,"Done\r\n");
}



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

  Camera output
  
****************************************************************************/
void Max2Nmo::ExportCameraObject(INode* node)
{
	TimeValue t = GetStaticFrame();
	ObjectState os = node->EvalWorldState(t);
	if (!os.obj) return;
	
	Report(REPORT_HLEVEL,"%sCamera : %s.....",StrGroupIndent().Str(),node->GetName());

	CameraObject *cam = (CameraObject *)os.obj;
	CameraState cs;
	Interval valid = FOREVER;
	Interval animRange = ip->GetAnimRange();
	cam->EvalCameraState(t,valid,&cs);


	INode* target = node->GetTarget();
	
	CKCamera*	VirtoolsCamera		 = NULL;
	CK3dEntity* VirtoolsCameraTarget = NULL;

// Virtools Objects creation
	VirtoolsCamera = VirtoolsExporter->AddCamera(target? TRUE:FALSE,node->GetName(),node);
	ExportNodeBase(node, VirtoolsCamera);

	if (target) {
		VirtoolsCameraTarget = ((CKTargetCamera* )VirtoolsCamera)->GetTarget();
		ExportNodeBase(target, VirtoolsCameraTarget);
	}
	
	if (cs.manualClip) {
		VirtoolsCamera->SetFrontPlane(cs.hither<1.0f ? 1.0f : cs.hither);
		VirtoolsCamera->SetBackPlane(cs.yon);
	} else {
		VirtoolsCamera->SetFrontPlane(cs.nearRange<1.0f ? 1.0f : cs.nearRange);
		VirtoolsCamera->SetBackPlane(cs.farRange);
	}
	VirtoolsCamera->SetFov(cs.fov);

// Export animation keys for the light node
	ExportAnimKeys(node,VirtoolsCamera);
		
// If we have a target, export animation keys for the target too.
	if (target && VirtoolsCameraTarget) {
		ExportAnimKeys(target,VirtoolsCameraTarget);
	}

	Report(REPORT_HLEVEL,"Done\r\n");
}



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

  Helper object output
  
****************************************************************************/
void Max2Nmo::ExportHelperObject(INode* node)
{
// We don't really know what kind of helper this is, but by exporting
// the Classname of the helper object, the importer has a chance to
// identify it.
	Object* helperObj = node->EvalWorldState(GetStaticFrame()).obj;
	TSTR className="Dummy"; 
	if (helperObj) {
		helperObj->GetClassName(className);
	}
	
	if (node->IsGroupHead() && !GetGroupAsPlace()) className = "Group";

	CK3dEntity* dummy = NULL;
	if (node->IsGroupHead() && GetGroupAsPlace()) {
		dummy = (CK3dEntity *)VirtoolsExporter->AddPlace(node->GetName(),node);
		className = "Place";
	} else {
		if(GetExportAsCharacter())
			dummy = (CK3dEntity*)VirtoolsExporter->AddCharacterBodyPart(node->GetName(),node);
		else
			dummy = VirtoolsExporter->AddDummyObject(node->GetName(),node);
	}
	
	Report(REPORT_HLEVEL,"%s%s : %s.....",StrGroupIndent().Str(),className,node->GetName());

	ExportNodeBase(node,dummy);
	ExportAnimKeys(node,dummy);

	if (node->IsGroupHead()) GroupIndent+=2;


	Report(REPORT_HLEVEL,"Done\r\n");
}


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

  Node Base (Hierarchy + position )
  
****************************************************************************/
void Max2Nmo::ExportNodeBase(INode* node,CK3dEntity* entity)
{
	VxMatrix VirtoolsMat;
	Matrix3  MaxMat = node->GetNodeTM(GetStaticFrame());
	
	// Special Matrix conversion for lights
	if (CKIsChildClassOf(entity,CKCID_CAMERA) || CKIsChildClassOf(entity,CKCID_LIGHT))
		ConvertMaxLightMatrix2Virtools(MaxMat,VirtoolsMat);
	else
		ConvertMaxMatrix2Virtools(MaxMat,VirtoolsMat);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -