void SkeletonExporter::export_particle_spray(INode *node)
{
  char sval[50];
  Interval range = ip->GetAnimRange();
  ObjectState os = node->EvalWorldState(0);
  if (!os.obj) return;

  SimpleParticle *partsys;
  Object *p; IDerivedObject *q; Modifier *m;
  partsys=(SimpleParticle *)os.obj;
  Point3 row;
  Matrix3 mat;
  Mtl *materiale;
  INode *padre=node->GetParentNode();
  int mod_names=0, k, mod_count=0;
  char modNames[25][50], refname[50];
  int sf, sm, mf, n;

  if ((padre) && (strcmp(padre->GetName(), "Scene Root")!=0))
    sf=strlen(padre->GetName())+1;
  else sf=0;
  
  materiale=node->GetMtl();
  if (materiale) sm=strlen(materiale->GetName())+1;
  else sm=0;

  mf=0;

  // trovo i modificatori Wind e Gravity con il loro
  // nome
  p=node->GetObjOrWSMRef();
  if ((p->SuperClassID()==GEN_DERIVOB_CLASS_ID) &&
	 (p->ClassID()==Class_ID(WSM_DERIVOB_CLASS_ID, 0)))
  {
	q=(IDerivedObject *)p;
	n=q->NumModifiers();
	mod_names=mod_count=0;
	for (k=0; k<n; k++)
	{
      m=q->GetModifier(k);
      Class_ID cidd = m->ClassID();
	  if ((cidd==Class_ID(WINDMOD_CLASS_ID, 0)) ||
		  (cidd==Class_ID(GRAVITYMOD_CLASS_ID, 0)) ||
		  (cidd==Class_ID(BOMB_OBJECT_CLASS_ID, 0)))
	  {
		 SimpleWSMMod *wm=(SimpleWSMMod *)m;
		 strcpy(refname, wm->nodeRef->GetName());
		 strcpy(modNames[mod_count], refname);
		 mod_names+=(strlen(refname)+1);
         mod_count++;
	  }
	}
  }

  write_chunk_header(fA3D, SPRAY_PARTICLE_SYSTEM_ID, node->GetName(),
	                 4+sf+4+sm+  // padre, materiale
					 12+48+  //pivot, matrice world(t=0)
					 4+mf+   // nome mesh/oggetto
					 4+4+4+4+ // emitter: width, height, speed , variation
					 4+4+4+4+ // life, startTime, stopTime, max_particles
					 4+mod_names // num WSM, nomi WSM
					 );

  fprintf(fTXT, "Spray particle system found\n");
  fprintf(fTXT, "Name : %s\n", node->GetName());
  if (padre) fprintf(fTXT, "Parent name : %s\n", node->GetParentNode()->GetName());
  if (materiale) fprintf(fTXT, "Material name : %s\n", materiale->GetName());
  if (makeADP)
    fprintf(fADP, "  particle %c%s%c\n  {\n", '"', node->GetName(), '"');

  // -----------    scrivo il padre (flag, nome)   ------------------
  fwrite(&sf, sizeof(int), 1, fA3D);
  if (sf>0)
  {
	 write_string0(fA3D, padre->GetName());
	 if (makeADP) fprintf(fADP, "     father=%c%s%c;\n", '"', padre->GetName(), '"');
  }
  else
	 if (makeADP) fprintf(fADP, "     father=%cNONE%c;\n", '"', '"');


  // ---------   scrivo il materiale di base (flag, nome)   ----------
  fwrite(&sm, sizeof(int), 1, fA3D);
  if (sm>0)
  {
     write_string0(fA3D, materiale->GetName());
	 //if (makeADP) fprintf(fADP, "     material=%c%s%c;\n", '"', materiale->GetName(), '"');
  }
  else
	 //if (makeADP) fprintf(fADP, "     material=%cNONE%c;\n", '"', '"');


  // ---------------   scrittura del punto di pivot   ----------------
  GetPivotOffset(node, &row);
  fprintf(fTXT, "Pivot point : %f, %f, %f\n", row.x, row.y, row.z);
  write_point3(&row, fA3D);

  // -------------------   scrittura matrice   -----------------------
  mat = node->GetNodeTM(0);
  write_matrix(&mat, fA3D);

  // ---------   scrittura dell'eventuale nome della mesh   ----------
  fwrite(&mf, sizeof(int), 1, fA3D);
  if (mf>0)
  {
    write_string0(fA3D, "TO_DO");
    if (makeADP) fprintf(fADP, "    lod=%cTO_DO, 0, 99999.99%c;\n", '"', '"');
  }


  // *************  ESPORAZIONE DATI DEL PARTCLE SYSTEM  *************
  float initVel, var, width, height;
  int count, life, start_time, stop_time;

  partsys->pblock->GetValue(PB_EMITTERWIDTH, 0, width, FOREVER);
  partsys->pblock->GetValue(PB_EMITTERHEIGHT, 0, height, FOREVER);
  partsys->pblock->GetValue(PB_SPEED, 0, initVel, FOREVER);
  partsys->pblock->GetValue(PB_VARIATION, 0, var, FOREVER);
  partsys->pblock->GetValue(PB_LIFETIME, 0, life, FOREVER);
  life=life/ GetTicksPerFrame();
  partsys->pblock->GetValue(PB_STARTTIME, 0, start_time, FOREVER);
  start_time=start_time / GetTicksPerFrame();
  stop_time=range.End() / GetTicksPerFrame();
  partsys->pblock->GetValue(PB_RNDPARTICLES, 0, count, FOREVER);

  fprintf(fTXT, "Emitter width: %f\n", width);
  fprintf(fTXT, "Emitter height: %f\n", height);
  fprintf(fTXT, "Emitter speed (init vel): %f\n", initVel);
  fprintf(fTXT, "Emitter variation: %f\n", var);
  fprintf(fTXT, "Life: %d\n", life);
  fprintf(fTXT, "Start time: %d\n", start_time);
  fprintf(fTXT, "Stop time: %d\n", stop_time);
  fprintf(fTXT, "Max particles: %d\n", count);

  // informazioni in formato binario (.A3D)
  fwrite(&width, sizeof(float), 1, fA3D);
  fwrite(&height, sizeof(float), 1, fA3D);
  fwrite(&initVel, sizeof(float), 1, fA3D);
  fwrite(&var, sizeof(float), 1, fA3D);
  fwrite(&life, sizeof(int), 1, fA3D);
  fwrite(&start_time, sizeof(int), 1, fA3D);
  fwrite(&stop_time, sizeof(int), 1, fA3D);
  fwrite(&count, sizeof(int), 1, fA3D);

  fwrite(&mod_count, sizeof(int), 1, fA3D);
  fprintf(fTXT, "Modificatori (wind, gravity, bomb) collegati: %d\n", mod_count);
  for (k=0; k<mod_count; k++)
  {
     fprintf(fTXT, "Modificatore %d: %s\n", k, modNames[k]);
	 write_string0(fA3D, modNames[k]);
	 //if (makeADP)
       //fprintf(fADP, "     modifier=%c%s, ON%c;\n", '"', modNames[k], '"');
  }


  //------------------------
  // ESPORTAZIONE KEYFRAMER
  //------------------------
  Control *c;
  int size_key;

  // NB: per gli oggetti mesh e quant'altre tipologie di
  // oggetti che possono essere linkati (ovvero dove e'
  // possibile implmenetare gerarchie), esporto SEMPRE una key 
  // di posizione, una di rotazione ed una di scaling
  // POSITION CONTROLLER
  c=node->GetTMController()->GetPositionController();
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=36;
	 else
	 if (IsBezierControl(c)) size_key=40;
	 else size_key=16;
	 fprintf(fTXT, "Particle position track present.\n");
     write_chunk_header(fA3D, POSITION_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_point3_track(c, 1, fA3D);
  }
  else
  {
	fprintf(fTXT, "Particle position track present. (1 key case)\n");
	if (!c) 	fprintf(fTXT, "c nullo !\n");
    fflush(fTXT);
	size_key=36;
    write_chunk_header(fA3D, POSITION_TRACK_ID,
	                   node->GetName(), 1+2+4+1*size_key);
    export_1key_point3_track(c, 1, fA3D);
  }


  // ROTATION CONTROLLER
  c=node->GetTMController()->GetRotationController();
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=40;
	 else size_key=20;
	 fprintf(fTXT, "Particle rotation track present.\n");
     write_chunk_header(fA3D, ROTATION_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_rot_track(c, fA3D);
  }
  else
  {
	fprintf(fTXT, "Particle rotation track present. (1 key case)\n");
    fflush(fTXT);
	size_key=40;
    write_chunk_header(fA3D, ROTATION_TRACK_ID,
	                   node->GetName(), 1+2+4+1*size_key);
    export_1key_rot_track(c, fA3D);
  }

  
  // SCALE CONTROLLER
  c=node->GetTMController()->GetScaleController();
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=36;
	 else
	 if (IsBezierControl(c)) size_key=40;
	 else size_key=16;
	 fprintf(fTXT, "Particle scaling track present.\n");
     write_chunk_header(fA3D, SCALE_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_scale_track(c, fA3D);
  }
  else
  {
	fprintf(fTXT, "Particle scaling track present. (1 key case)\n");
	size_key=36;
    write_chunk_header(fA3D, SCALE_TRACK_ID,
	                   node->GetName(), 1+2+4+1*size_key);
    export_1key_scale_track(c, fA3D);
  }

  // keyframer emitter width
  c=partsys->pblock->GetController(PB_EMITTERWIDTH);
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Particle emitter width track present.\n");
     write_chunk_header(fA3D, PARTICLE_EMITTER_WIDTH_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D);
  }

  // keyframer emitter length
  c=partsys->pblock->GetController(PB_EMITTERHEIGHT);
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Particle emitter length track present.\n");
     write_chunk_header(fA3D, PARTICLE_EMITTER_LENGTH_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D);
  }

  // keyframer particles speed
  c=partsys->pblock->GetController(PB_SPEED);
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Particle emitter speed track present.\n");
     write_chunk_header(fA3D, PARTICLE_EMITTER_SPEED_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D);
  }

  // keyframer particles variations
  c=partsys->pblock->GetController(PB_VARIATION);
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Particle emitter variation track present.\n");
     write_chunk_header(fA3D, PARTICLE_EMITTER_VARIATION_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D);
  }


  if (makeADP)
  {
    fprintf(fADP, "     texture=%cNONE%c;\n", '"', '"');
	my_ftoa(width, sval);
	fprintf(fADP, "     emitter_width=%c%s%c;\n", '"', sval, '"');
	my_ftoa(height, sval);
    fprintf(fADP, "     emitter_height=%c%s%c;\n", '"', sval, '"');
    fprintf(fADP, "     faded_particles=%cOFF%c;\n", '"', '"');
    fprintf(fADP, "     max_particles=%c%d%c;\n", '"', count, '"');
    fprintf(fADP, "     start_time=%c%d%c;\n", '"', start_time, '"');
    fprintf(fADP, "     end_time=%c%d%c;\n", '"', stop_time, '"');
    fprintf(fADP, "     life=%c%d%c;\n", '"', life, '"');
	my_ftoa(initVel, sval);
    fprintf(fADP, "     speed=%c%s%c;\n", '"', sval, '"');
	my_ftoa(var, sval);
    fprintf(fADP, "     variation=%c%s%c;\n", '"', sval, '"');
    fprintf(fADP, "     size_attenuation=%c0.4, 1.0, 0.8, 0.1%c;\n", '"', '"');
	fprintf(fADP, "  }\n\n");
  }
  fprintf(fTXT, "\n\n");
}
示例#2
0
INT_PTR CALLBACK BindProc(
		HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
	{
	M3Mat *mp = (M3Mat*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
	if (!mp && msg!=WM_INITDIALOG) return FALSE;

	int id = LOWORD(wParam);
	int notify = HIWORD(wParam);


	switch (msg) {
		case WM_INITDIALOG:{
			mp = (M3Mat*)lParam;
			SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)mp);

			HWND modList = GetDlgItem(hWnd,IDC_MODLIST);

			SendMessage(modList,LB_RESETCONTENT,0,0);

			POINT lpPt; GetCursorPos(&lpPt);
			SetWindowPos(hWnd, NULL, lpPt.x, lpPt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

			Object *pObj = mp->Wnode->GetObjectRef();
			IDerivedObject *pDerObj = NULL;
			Modifier *pMod = NULL;

			if( pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID) 
			{
				pDerObj = (IDerivedObject *) pObj;

				for(int i = 0 ; i < pDerObj->NumModifiers() ; i++ )
				{
					pMod = pDerObj->GetModifier(i);	
					SendMessage(modList,LB_ADDSTRING,0,(LPARAM) (LPCTSTR) pMod->GetName());
				}
			}

			SendMessage(modList,LB_SETCURSEL ,(WPARAM)-1,0);

			break;}


		case WM_COMMAND:

			if (notify==LBN_SELCHANGE){
				if(id==IDC_MODLIST){
					int mkSel = SendMessage(GetDlgItem(hWnd, IDC_MODLIST), LB_GETCURSEL, 0, 0);
					if(mkSel>=0){

						Object *pObj = mp->Wnode->GetObjectRef();
						IDerivedObject *pDerObj = NULL;
						Modifier *pMod = NULL;

						if( pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID) 
						{
							pDerObj = (IDerivedObject *) pObj;
							pMod = pDerObj->GetModifier(mkSel);	
							if(pMod->ClassID() == MR3_CLASS_ID) EnableWindow(GetDlgItem(hWnd,IDOK),TRUE);
							else EnableWindow(GetDlgItem(hWnd,IDOK),FALSE);
						}


					}
				}
			}

			switch (id) {
				case IDOK:
				{
					int mkSel = SendMessage(GetDlgItem(hWnd, IDC_MODLIST), LB_GETCURSEL, 0, 0);
					if(mkSel>=0){

						Object *pObj = mp->Wnode->GetObjectRef();
						IDerivedObject *pDerObj = NULL;
						Modifier *pMod = NULL;

						if( pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID) 
						{
							pDerObj = (IDerivedObject *) pObj;
							pMod = pDerObj->GetModifier(mkSel);	
							
							MorphR3 *mod = (MorphR3*)pMod;
							if(mod->CheckMaterialDependency() ) {
								EndDialog(hWnd,1);return TRUE;
							}

							// Make sure the node does not depend on us
							mod->BeginDependencyTest();
							mp->NotifyDependents(FOREVER,0,REFMSG_TEST_DEPENDENCY);
							if (mod->EndDependencyTest()) { 
								// display cyclic warning
								//
								if (GetCOREInterface()->GetQuietMode()) {
									TSTR cyclic;
									cyclic = GetString(IDS_CANNOT_BIND);
									GetCOREInterface()->Log()->LogEntry(SYSLOG_WARN,NO_DIALOG,GetString(IDS_CLASS_NAME),cyclic);
								}
								else
								{
									TSTR cyclic;
									cyclic = GetString(IDS_CANNOT_BIND);
									MessageBox(hWnd,cyclic,GetString(IDS_CLASS_NAME),MB_OK);
								}
								EndDialog(hWnd,1);
								return TRUE; 
							}

							if(mod) mod->morphmaterial = mp;

							mp->ReplaceReference(102, mod);
							mp->obName = mp->Wnode->GetName();

							mp->morphp = mod;
							if (mp->matDlg ){
								mp->matDlg->UpdateMorphInfo(UD_LINK);
								mp->matDlg->ReloadDialog();
							}
						}


					}
				}
				case IDCANCEL:
					EndDialog(hWnd,1);
				break;
				}
			break;
		
		

		default:
			return FALSE;
		}
	return TRUE;
	}
示例#3
0
void UtilTest::MakeObject()
	{
	// Create a new object through the CreateInstance() API
	Object *obj = (Object*)ip->CreateInstance(
		GEOMOBJECT_CLASS_ID,
		Class_ID(CYLINDER_CLASS_ID,0));
	assert(obj);

	// Get a hold of the parameter block
	IParamArray *iCylParams = obj->GetParamBlock();
	assert(iCylParams);

	// Set the value of radius, height and segs.
	int rad = obj->GetParamBlockIndex(CYLINDER_RADIUS);
	assert(rad>=0);
	iCylParams->SetValue(rad,TimeValue(0),30.0f);
	int height = obj->GetParamBlockIndex(CYLINDER_HEIGHT);
	assert(height>=0);
	iCylParams->SetValue(height,TimeValue(0),100.0f);
	int segs = obj->GetParamBlockIndex(CYLINDER_SEGMENTS);
	assert(segs>=0);
	iCylParams->SetValue(segs,TimeValue(0),10);

	// Create a derived object that references the cylinder
	IDerivedObject *dobj = CreateDerivedObject(obj);

	// Create a bend modifier
	Modifier *bend = (Modifier*)ip->CreateInstance(
		OSM_CLASS_ID,
		Class_ID(BENDOSM_CLASS_ID,0));

	// Set the bend angle - ParamBlock2
	IParamBlock2* iBendBlock = ((Animatable*)bend)->GetParamBlock(0);  //only one pblock2
	assert(iBendBlock);
	iBendBlock->SetValue(BEND_ANGLE,TimeValue(0),90.0f);

	// Add the bend modifier to the derived object.
	dobj->AddModifier(bend);

	// Create a node in the scene that references the derived object
	INode *node = ip->CreateObjectNode(dobj);
	
	// Name the node and make the name unique.
	TSTR name(_T("MyNode"));
	ip->MakeNameUnique(name);
	node->SetName(name);

	// Get ready to add WSMs to this node
	node->CreateWSMDerivedObject();
	IDerivedObject *wsdobj = node->GetWSMDerivedObject();
	if (wsdobj) {
		WSMObject *swobj = (WSMObject*)ip->CreateInstance(
			WSM_OBJECT_CLASS_ID,
			Class_ID(SINEWAVE_OBJECT_CLASS_ID,0));
		int ix;
		IParamArray *iRipParams = swobj->GetParamBlock();
		
		ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE);
		iRipParams->SetValue(ix,TimeValue(0),10.0f);

		ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE2);
		iRipParams->SetValue(ix,TimeValue(0),10.0f);

		ix = swobj->GetParamBlockIndex(RWAVE_WAVELEN);
		iRipParams->SetValue(ix,TimeValue(0),40.0f);

		ix = swobj->GetParamBlockIndex(RWAVE_CIRCLES);
		iRipParams->SetValue(ix,TimeValue(0),10);

		ix = swobj->GetParamBlockIndex(RWAVE_DIVISIONS);
		iRipParams->SetValue(ix,TimeValue(0),4);

		ix = swobj->GetParamBlockIndex(RWAVE_SEGMENTS);
		iRipParams->SetValue(ix,TimeValue(0),16);

		INode *swnode = ip->CreateObjectNode(swobj);
		
		TSTR swname(_T("RippleNode"));
		ip->MakeNameUnique(swname);
		node->SetName(swname);

		// Create a Space Warp Modifier
		Modifier *swmod = swobj->CreateWSMMod(swnode);
		if (swmod) {
			wsdobj->AddModifier(swmod);
			}
		}
	
	// Redraw the views
	ip->RedrawViews(ip->GetTime());
	}
示例#4
0
static INT_PTR CALLBACK UVStripDlgProc(
		HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
		case WM_INITDIALOG:
			theUVStrip.Init(hWnd);
			TCHAR s[50]; _stprintf(s,GetString(IDS_OBJ_SELECTED),theUVStrip.ip->GetSelNodeCount());
			SetWindowText(GetDlgItem(hWnd,IDC_SEL),s);
			break;

		case WM_DESTROY:
			theUVStrip.Destroy(hWnd);
			break;

		case WM_COMMAND:
			switch (LOWORD(wParam)) {
			
			case IDC_R1:
				{
				int cn = theUVStrip.ip->GetSelNodeCount();
				Interval valid=FOREVER;
				if(cn>0)
					{
					for(int x=0;x<cn;x++)
						{
						// then osm stack
						Object* obj = theUVStrip.ip->GetSelNode(x)->GetObjectRef();

//check to make sure no modifiers on the object
						int ct = 0;
						SClass_ID		sc;
						IDerivedObject* dobj;
						if ((sc = obj->SuperClassID()) == GEN_DERIVOB_CLASS_ID)
							{
							dobj = (IDerivedObject*)obj;

							while (sc == GEN_DERIVOB_CLASS_ID)
								{
								ct +=  dobj->NumModifiers();
								dobj = (IDerivedObject*)dobj->GetObjRef();
								sc = dobj->SuperClassID();
								}

							}
						if ((dobj = theUVStrip.ip->GetSelNode(x)->GetWSMDerivedObject()) != NULL)
							{
							ct +=  dobj->NumModifiers();
							}

						
						if (ct != 0)
							{
//error message here
							TSTR buf2 = GetString(IDS_ERROR);
							TSTR buf1 = GetString(IDS_ERROR_MESH);
							MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION);
							}
						else 
							{
							ObjectState os = theUVStrip.ip->GetSelNode(x)->EvalWorldState(theUVStrip.ip->GetTime());
							if (os.obj && os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID && os.obj->IsSubClassOf(triObjectClassID)) 
								{
								Object *bobj = os.obj->FindBaseObject();
								if (bobj->ClassID() ==Class_ID(EDITTRIOBJ_CLASS_ID,0))
									{
									TriObject *T1 = (TriObject *)os.obj;
									T1->GetMesh().setNumTVerts(0);
									T1->GetMesh().setNumTVFaces(0);
									}	
								else
									{
//error message here
									TSTR buf2 = GetString(IDS_ERROR);
									TSTR buf1 = GetString(IDS_ERROR_MESH);
									MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION);
									}
								}
							else
								{
//error message here
								TSTR buf2 = GetString(IDS_ERROR);
								TSTR buf1 = GetString(IDS_ERROR_MESH);
								MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION);
								}
							}
						  theUVStrip.ip->ForceCompleteRedraw();
						}
					}
				
				break;
				}

			case IDC_R2:{
				int cn = theUVStrip.ip->GetSelNodeCount();
				if(cn>0){
					for(int x=0;x<cn;x++){
						INode *tmp=theUVStrip.ip->GetSelNode(x);
						tmp->SetMtl(NULL);
						if(GetCheckBox(hWnd, IDC_BLANK)) tmp->SetWireColor(RGB(160,160,160));
					}
					theUVStrip.ip->ForceCompleteRedraw();
				}
				break;}

			}
			break;

		default:
			return FALSE;
	}
	return TRUE;
}
INode* HavokImport::ImportHCTCapsule(bhkCapsuleShapeRef shape, INode *parent, INode *ragdollParent, Matrix3& tm)
{
	USES_CONVERSION;

	bhkShapeRef retval;
	if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, HK_TAPEREDCAPSULE_CLASS_ID)) {

		if (IParamBlock2* pblock2 = obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK))
		{
			float radius = shape->GetRadius();
			int mtl = GetHavokIndexFromMaterials(ni.IsSkyrim() ? -1 : shape->GetMaterial(), ni.IsSkyrim() ? shape->GetSkyrimMaterial() : -1);
			float radius1 = shape->GetRadius1() * ni.bhkScaleFactor;
			float radius2 = shape->GetRadius2();
			Vector3 pt1 = shape->GetFirstPoint();
			Vector3 pt2 = shape->GetSecondPoint();
			float len = (pt2 - pt1).Magnitude() * ni.bhkScaleFactor;

			Point3 center = (TOPOINT3(pt2 + pt1) / 2.0f) * ni.bhkScaleFactor;
			Point3 norm = Normalize(TOPOINT3(pt2 - pt1));
			Matrix3 mat;
			MatrixFromNormal(norm, mat);

			pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, radius1, 0);
			pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, len, 0);

			if (INode *n = ni.CreateImportRagdollNode(A2T(shape->GetType().GetTypeName().c_str()), obj, ragdollParent)) {

				PosRotScale prs = prsDefault;

				n->SetObjOffsetPos(parent->GetObjOffsetPos() + center);
				n->SetObjOffsetRot(parent->GetObjOffsetRot()*mat);

				Point3 pos = tm.GetTrans();
				Quat rot(tm);
				PosRotScaleNode(n, pos, rot, 1.0, prsDefault);

				Object *pObj = n->GetObjectRef();
				IDerivedObject *dobj = nullptr;
				if (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
					dobj = static_cast<IDerivedObject*>(pObj);
				else {
					dobj = CreateDerivedObject(pObj);
				}

				//Havok shape
				Modifier* shapeMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_SHAPE_MODIFIER_CLASS_ID);
				if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) {
					shapeParameters->SetValue(PA_SHAPE_MOD_SHAPE_TYPE, 0, 2, 0);
				}

				dobj->SetAFlag(A_LOCK_TARGET);
				dobj->AddModifier(shapeMod);
				dobj->ClearAFlag(A_LOCK_TARGET);
				n->SetObjectRef(dobj);

				return n;
			}
		}
	}
	return ragdollParent;
#if 0
	if (SimpleObject *ob = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, SCUBA_CLASS_ID)) {
		float radius = shape->GetRadius();
		float radius1 = shape->GetRadius1();
		float radius2 = shape->GetRadius2();
		Point3 pt1 = TOPOINT3(shape->GetFirstPoint());
		Point3 pt2 = TOPOINT3(shape->GetSecondPoint());
		float height = Length(pt1 - pt2);
		int heighttype = 1;

		RefTargetHandle t = ob->GetReference(0);
		if (IParamBlock2* pblock2 = ob->GetParamBlockByID(0))
		{
			pblock2->SetValue(CAPSULE_RADIUS, 0, radius);
			pblock2->SetValue(CAPSULE_HEIGHT, 0, height);
			pblock2->SetValue(CAPSULE_CENTERS, 0, heighttype);
		}

		if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), ob, parent)) {
			// Need to "Affect Pivot Only" and "Center to Object" first
			//n->CenterPivot(0, FALSE);

			// Need to reposition the Capsule so that caps are rotated correctly for pts given

			int mtlIdx = GetHavokIndexFromMaterial(shape->GetMaterial());
			int lyrIdx = GetHavokIndexFromLayer(OL_UNIDENTIFIED);
			CreatebhkCollisionModifier(n, bv_type_capsule, mtlIdx, lyrIdx, 0);
			ImportBase(body, shape, parent, n, tm);
			AddShape(rbody, n);
			return true;
		}
	}
	return true;
#endif
}
示例#6
0
void Import::ApplyModifiers (dScene& scene, const MaxNodeChache& maxNodeCache)
{
    dScene::Iterator iter (scene);
    for (iter.Begin(); iter; iter ++) {
        dScene::dTreeNode* meshNode = iter.GetNode();
        dNodeInfo* info = scene.GetInfoFromNode(meshNode);
        if (info->IsType(dGeometryNodeInfo::GetRttiType())) {
            dScene::dTreeNode* skinModifierNode = NULL;
            for (void* ptr = scene.GetFirstChild(meshNode); ptr; ptr = scene.GetNextChild(meshNode, ptr)) {
                dScene::dTreeNode* node = scene.GetNodeFromLink(ptr);
                dNodeInfo* info = scene.GetInfoFromNode(node);
                if (info->GetTypeId() == dGeometryNodeSkinModifierInfo::GetRttiType()) {
                    skinModifierNode = node;
                    break;
                }
            }

            if (skinModifierNode) {
                //create a skin modifier and add it
                Modifier* skinMod = (Modifier*) CreateInstance(OSM_CLASS_ID, SKIN_CLASSID);
                ISkinImportData* iskinImport = (ISkinImportData*) skinMod->GetInterface(I_SKINIMPORTDATA);
                INode* maxNode = maxNodeCache.Find(meshNode)->GetInfo();
                _ASSERTE (maxNode);

                IDerivedObject *derob = NULL;
                Object* obj = maxNode->GetObjectRef();
                if(obj->SuperClassID() != GEN_DERIVOB_CLASS_ID)
                {
                    derob = CreateDerivedObject(obj);
                    maxNode->SetObjectRef(derob);
                } else {
                    derob = (IDerivedObject*) obj;
                }
                derob->AddModifier(skinMod);

                dGeometryNodeSkinModifierInfo* skinModifier = (dGeometryNodeSkinModifierInfo*) scene.GetInfoFromNode(skinModifierNode);

                dMatrix matrix (skinModifier->m_shapeBindMatrix);
                Matrix3 bindPoseMatrix;
                bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0]));
                bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1]));
                bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2]));
                bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3]));
                iskinImport->SetSkinTm(maxNode, bindPoseMatrix, bindPoseMatrix);

                int maxNodeCount = 0;
                INode* maxNodes[1024];

                for (void* ptr = scene.GetFirstChild(skinModifierNode); ptr; ptr = scene.GetNextChild(skinModifierNode, ptr)) {
                    dScene::dTreeNode* boneNode = scene.GetNodeFromLink(ptr);
                    INode* skelBone = maxNodeCache.Find(boneNode)->GetInfo();
                    maxNodes[maxNodeCount] = skelBone;
                    maxNodeCount ++;
                    skelBone->SetBoneNodeOnOff(TRUE, 0);
                    skelBone->BoneAsLine(TRUE);
                    skelBone->ShowBone(1);
                    if (iskinImport->AddBoneEx(skelBone, TRUE)) {
                        dSceneNodeInfo* sceneNode = (dSceneNodeInfo*) scene.GetInfoFromNode(boneNode);
                        dMatrix matrix (sceneNode->GetTransform());
                        Matrix3 bindPoseMatrix;
                        bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0]));
                        bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1]));
                        bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2]));
                        bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3]));
                        iskinImport->SetBoneTm(skelBone, bindPoseMatrix, bindPoseMatrix);
                    }
                }

                // must evaluate the node after adding bones
                maxNode->EvalWorldState(0);

                for (int i = 0; i < skinModifier->m_vertexCount; i ++) {
                    Tab<float> weightList;
                    Tab<INode*> boneNodeList;
                    for (int j = 0; j < 4; j ++) {
                        if (skinModifier->m_vertexWeights[i][j] > 1.0e-5f) {
                            int boneIndex = skinModifier->m_boneWeightIndex[i].m_index[j];
                            INode *skelBone = maxNodes[boneIndex];
                            _ASSERTE (skelBone);
                            boneNodeList.Append (1, &skelBone);
                            weightList.Append (1, &skinModifier->m_vertexWeights[i][j]);
                        }
                    }
                    iskinImport->AddWeights(maxNode, i, boneNodeList, weightList);
                }
            }
        }
    }
}
void HavokExport::makeHavokRigidBody(NiNodeRef parent, INode *ragdollParent, float scale) {

	this->scale = scale;

	Object *Obj = ragdollParent->GetObjectRef();

	Modifier* rbMod = nullptr;
	Modifier* shapeMod = nullptr;
	Modifier* constraintMod = nullptr;

	SimpleObject* havokTaperCapsule = nullptr;

	//get modifiers
	

	while (Obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
		IDerivedObject *DerObj = static_cast<IDerivedObject *> (Obj);
		const int nMods = DerObj->NumModifiers(); //it is really the last modifier on the stack, and not the total number of modifiers

		for (int i = 0; i < nMods; i++)
		{
			Modifier *Mod = DerObj->GetModifier(i);
			if (Mod->ClassID() == HK_RIGIDBODY_MODIFIER_CLASS_ID) {
				rbMod = Mod;
			}
			if (Mod->ClassID() == HK_SHAPE_MODIFIER_CLASS_ID) {
				shapeMod = Mod;
			}
			if (Mod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID || Mod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) {
				constraintMod = Mod;
			}
		}
		if (Obj->SuperClassID() == GEOMOBJECT_CLASS_ID) {
			havokTaperCapsule = (SimpleObject*)Obj;
		}
		Obj = DerObj->GetObjRef();
	}

	
	if (!rbMod) {
		throw exception(FormatText("No havok rigid body modifier found on %s", ragdollParent->GetName()));
	}
	if (!shapeMod) {
		throw exception(FormatText("No havok shape modifier found on %s", ragdollParent->GetName()));
	}

//	Object* taper = ragdollParent->GetObjectRef();
	IParamBlock2* taperParameters = Obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK);
	float radius;
	enum
	{
		// GENERAL PROPERTIES ROLLOUT
		PA_TAPEREDCAPSULE_OBJ_RADIUS = 0,
		PA_TAPEREDCAPSULE_OBJ_TAPER,
		PA_TAPEREDCAPSULE_OBJ_HEIGHT,
		PA_TAPEREDCAPSULE_OBJ_VERSION_INTERNAL,
	};
	taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, radius, FOREVER);
	

	int shapeType;
	if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) {
		shapeParameters->GetValue(PA_SHAPE_MOD_SHAPE_TYPE,0,shapeType,FOREVER);
	}

	//Havok Shape
	bhkShapeRef shape;

	if (shapeType == 2) {

		// Capsule
		bhkCapsuleShapeRef capsule = new bhkCapsuleShape();
		capsule->SetRadius(radius/scale);
		capsule->SetRadius1(radius/scale);
		capsule->SetRadius2(radius/scale);
		float length; 
		taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, length, FOREVER);
		//get the normal
		Matrix3 axis(true);
		ragdollParent->GetObjOffsetRot().MakeMatrix(axis);
		Point3 normalAx = axis.GetRow(2);
		//capsule center
		Point3 center = ragdollParent->GetObjOffsetPos();
		//min and max points
		Point3 pt1 = center - normalAx*(length/2);
		Point3 pt2 = center + normalAx*(length/2);

		capsule->SetFirstPoint(TOVECTOR3(pt1)/scale);
		capsule->SetSecondPoint(TOVECTOR3(pt2)/scale);
		capsule->SetMaterial(HAV_MAT_SKIN);

		shape = StaticCast<bhkShape>(capsule);
		
	}
	else {
		// Sphere
		//CalcBoundingSphere(node, tm.GetTrans(), radius, 0);

		bhkSphereShapeRef sphere = new bhkSphereShape();
		sphere->SetRadius(radius/scale);
		sphere->SetMaterial(HAV_MAT_SKIN);
		shape = StaticCast<bhkShape>(sphere);
	}

	bhkRigidBodyRef body;

	if (shape)
	{
		bhkBlendCollisionObjectRef blendObj = new bhkBlendCollisionObject();
		body = new bhkRigidBody();

		Matrix3 tm = ragdollParent->GetObjTMAfterWSM(0);
		
		//Calculate Object Offset Matrix
		Matrix3 otm(1);
		Point3 pos = ragdollParent->GetObjOffsetPos();
		otm.PreTranslate(pos);
		Quat quat = ragdollParent->GetObjOffsetRot();
		PreRotateMatrix(otm, quat);
		Matrix3 otmInvert = otm;
		otmInvert.Invert();

		//correct object tm
		Matrix3 tmbhk = otmInvert * tm;

		//set geometric parameters
		body->SetRotation(TOQUATXYZW(Quat(tmbhk).Invert()));
		body->SetTranslation(TOVECTOR4(tmbhk.GetTrans() / scale));
		body->SetCenter(TOVECTOR4(ragdollParent->GetObjOffsetPos())/scale);

		//set physics
		if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_RB_MOD_PBLOCK)) {
			//These are fundamental parameters

			int lyr = NP_DEFAULT_HVK_LAYER;
			int mtl = NP_DEFAULT_HVK_MATERIAL;
			int msys = NP_DEFAULT_HVK_MOTION_SYSTEM;
			int qtype = NP_DEFAULT_HVK_QUALITY_TYPE;
			float mass = NP_DEFAULT_HVK_MASS;
			float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING;
			float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING;
			float frict = NP_DEFAULT_HVK_FRICTION;
			float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY;
			float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY;
			float resti = NP_DEFAULT_HVK_RESTITUTION;
			float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH;
			Point3 InertiaTensor;


			rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_INERTIA_TENSOR, 0, InertiaTensor, FOREVER);


			rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER);

			rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER);

			rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER);

			body->SetMass(mass);
			body->SetRestitution(resti);
			body->SetFriction(frict);
			body->SetLinearDamping(lindamp);
			body->SetMaxLinearVelocity(maxlinvel);
			body->SetMaxAngularVelocity(maxangvel);
			body->SetPenetrationDepth(pendepth);
			InertiaMatrix im;
			im[0][0] = InertiaTensor[0];
			im[1][1] = InertiaTensor[1];
			im[2][2] = InertiaTensor[2];

			body->SetInertia(im);

			/*switch (qtype) {
			case QT_FIXED:
				body->SetQualityType(MO_QUAL_FIXED);
				break;
			case QT_KEYFRAMED:
				body->SetQualityType(MO_QUAL_KEYFRAMED);
				break;
			case QT_DEBRIS:
				body->SetQualityType(MO_QUAL_DEBRIS);
				break;
			case QT_MOVING:
				body->SetQualityType(MO_QUAL_MOVING);
				break;
			case QT_CRITICAL:
				body->SetQualityType(MO_QUAL_CRITICAL);
				break;
			case QT_BULLET:
				body->SetQualityType(MO_QUAL_BULLET);
				break;
			case QT_KEYFRAMED_REPORTING:
				body->SetQualityType(MO_QUAL_KEYFRAMED_REPORT);
				break;
			}*/

			body->SetSkyrimLayer(SkyrimLayer::SKYL_BIPED);
			body->SetSkyrimLayerCopy(SkyrimLayer::SKYL_BIPED);

			body->SetMotionSystem(MotionSystem::MO_SYS_BOX);
			body->SetDeactivatorType(DeactivatorType::DEACTIVATOR_NEVER);
			body->SetSolverDeactivation(SolverDeactivation::SOLVER_DEACTIVATION_LOW);
			body->SetQualityType(MO_QUAL_FIXED);

		}
		
		if (constraintMod && ragdollParent->GetParentNode() && parent->GetParent()) {
			if (constraintMod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID) {
				bhkRagdollConstraintRef ragdollConstraint = new bhkRagdollConstraint();
				
				//entities
				ragdollConstraint->AddEntity(body);
				NiNodeRef parentRef = parent->GetParent();
				bhkRigidBodyRef nifParentRigidBody;
				while (parentRef) {
					if (parentRef->GetCollisionObject()) {
						nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody());
						break;
					}
					parentRef = parentRef->GetParent();
				}
				if (!nifParentRigidBody)
					throw exception(FormatText("Unable to find NIF constraint parent for ragdoll node %s", ragdollParent->GetName()));
				ragdollConstraint->AddEntity(nifParentRigidBody);

				RagdollDescriptor desc;
				//parameters
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					Point3 pivotA;
					Matrix3 parentRotation;
					Point3 pivotB;
					Matrix3 childRotation;
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, pivotB, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, pivotA, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER);
					
					desc.pivotA = TOVECTOR4(pivotA);
					desc.pivotB = TOVECTOR4(pivotB);
					desc.planeA = TOVECTOR4(parentRotation.GetRow(0));
					desc.motorA = TOVECTOR4(parentRotation.GetRow(1));
					desc.twistA = TOVECTOR4(parentRotation.GetRow(2));
					desc.planeB = TOVECTOR4(childRotation.GetRow(0));
					desc.motorB = TOVECTOR4(childRotation.GetRow(1));
					desc.twistB = TOVECTOR4(childRotation.GetRow(2));
					
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
					float coneMaxAngle;
					float planeMinAngle;
					float planeMaxAngle;
					float coneMinAngle;
					float twistMinAngle;
					float maxFriction;

					constraintParameters->GetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, coneMaxAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, planeMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, planeMaxAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, coneMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, twistMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER);

					desc.coneMaxAngle = TORAD(coneMaxAngle);
					desc.planeMinAngle = TORAD(planeMinAngle);
					desc.planeMaxAngle = TORAD(planeMaxAngle);
					desc.coneMaxAngle = TORAD(coneMinAngle);
					desc.twistMinAngle = TORAD(twistMinAngle);
					desc.maxFriction = maxFriction;


				}
				ragdollConstraint->SetRagdoll(desc);
				body->AddConstraint(ragdollConstraint);
			}
			else if (constraintMod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) {
				bhkLimitedHingeConstraintRef limitedHingeConstraint = new bhkLimitedHingeConstraint();

				//entities
				limitedHingeConstraint->AddEntity(body);
				NiNodeRef parentRef = parent->GetParent();
				bhkRigidBodyRef nifParentRigidBody;
				while (parentRef) {
					if (parentRef->GetCollisionObject()) {
						nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody());
						break;
					}
					parentRef = parentRef->GetParent();
				}
				if (!nifParentRigidBody)
					throw exception(FormatText("Unable to find NIF constraint parent for limited hinge node %s", ragdollParent->GetName()));
				limitedHingeConstraint->AddEntity(nifParentRigidBody);

				LimitedHingeDescriptor lh;

				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					Matrix3 parentRotation;
					Matrix3 childRotation;
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER);

					lh.perp2AxleInA1 = TOVECTOR4(parentRotation.GetRow(0));
					lh.perp2AxleInA2 = TOVECTOR4(parentRotation.GetRow(1));
					lh.axleA = TOVECTOR4(parentRotation.GetRow(2));
					lh.perp2AxleInB1 = TOVECTOR4(childRotation.GetRow(0));
					lh.perp2AxleInB2 = TOVECTOR4(childRotation.GetRow(1));
					lh.axleB = TOVECTOR4(childRotation.GetRow(2));
					
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
					float minAngle;
					float maxAngle;
					float maxFriction;

					constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MIN, 0, minAngle, FOREVER);
					constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MAX, 0, maxAngle, FOREVER);
					constraintParameters->GetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER);
					//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);

					lh.minAngle = TORAD(minAngle);
					lh.maxAngle = TORAD(maxAngle);
					lh.maxAngle = maxFriction;

				}
				limitedHingeConstraint->SetLimitedHinge(lh);
				body->AddConstraint(limitedHingeConstraint);
			}
		}


		//InitializeRigidBody(body, node);
		body->SetShape(shape);
		blendObj->SetBody(StaticCast<NiObject>(body));
		parent->SetCollisionObject(StaticCast<NiCollisionObject>(blendObj));
	}

	////rigid body parameters
	//	// get data from node
	//int lyr = NP_DEFAULT_HVK_LAYER;
	//int mtl = NP_DEFAULT_HVK_MATERIAL;
	//int msys = NP_DEFAULT_HVK_MOTION_SYSTEM;
	//int qtype = NP_DEFAULT_HVK_QUALITY_TYPE;
	//float mass = NP_DEFAULT_HVK_MASS;
	//float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING;
	//float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING;
	//float frict = NP_DEFAULT_HVK_FRICTION;
	//float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY;
	//float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY;
	//float resti = NP_DEFAULT_HVK_RESTITUTION;
	//float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH;
	//BOOL transenable = TRUE;

	//if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK))
	//{
	//	//These are fundamental parameters
	//	rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER);


	//	switch (qtype) {
	//	case MO_QUAL_INVALID:
	//		break;
	//	case QT_FIXED:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, MO_QUAL_FIXED, 0);
	//		break;
	//	case MO_QUAL_KEYFRAMED:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED, 0);
	//		break;
	//	case MO_QUAL_DEBRIS:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_DEBRIS, 0);
	//		break;
	//	case MO_QUAL_MOVING:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_MOVING, 0);
	//		break;
	//	case MO_QUAL_CRITICAL:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_CRITICAL, 0);
	//		break;
	//	case MO_QUAL_BULLET:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_BULLET, 0);
	//		break;
	//	case MO_QUAL_USER:
	//		break;
	//	case MO_QUAL_CHARACTER:
	//		break;
	//	case MO_QUAL_KEYFRAMED_REPORT:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED_REPORTING, 0);
	//		break;
	//	}

	//	// setup body
	//	bhkRigidBodyRef body = transenable ? new bhkRigidBodyT() : new bhkRigidBody();

	//	OblivionLayer obv_layer; SkyrimLayer sky_layer;
	//	GetHavokLayersFromIndex(lyr, (int*)&obv_layer, (int*)&sky_layer);
	//	body->SetLayer(obv_layer);
	//	body->SetLayerCopy(obv_layer);
	//	body->SetSkyrimLayer(sky_layer);

	//	body->SetMotionSystem(MotionSystem(msys));
	//	body->SetQualityType(MotionQuality(qtype));
	//	body->SetMass(mass);
	//	body->SetLinearDamping(lindamp);
	//	body->SetAngularDamping(angdamp);
	//	body->SetFriction(frict);
	//	body->SetRestitution(resti);
	//	body->SetMaxLinearVelocity(maxlinvel);
	//	body->SetMaxAngularVelocity(maxangvel);
	//	body->SetPenetrationDepth(pendepth);
	//	body->SetCenter(center);
	//	QuaternionXYZW q; q.x = q.y = q.z = 0; q.w = 1.0f;
	//	body->SetRotation(q);
	//}
}
void HavokImport::createRagdollRigidBody(INode* n, INode* parent, INode* ragdollParent, bhkRigidBodyRef rbody) {

	const int MaxChar = 512;
	char buffer[MaxChar];

	//TSTR name(A2THelper(buffer, parent->GetName().c_str(), _countof(buffer)));
	n->SetName(FormatText(TEXT("Ragdoll_%s"), parent->GetName()));

	Object *pObj = n->GetObjectRef();
	IDerivedObject *dobj = nullptr;
	if (n->SuperClassID() == GEN_DERIVOB_CLASS_ID)
		dobj = static_cast<IDerivedObject*>(pObj);
	else {
		dobj = CreateDerivedObject(pObj);
	}

	MotionSystem msys = rbody->GetMotionSystem(); //?
	MotionQuality qtype = rbody->GetQualityType();
	float mass = rbody->GetMass();
	float lindamp = rbody->GetLinearDamping();
	float angdamp = rbody->GetAngularDamping();
	float frict = rbody->GetFriction();
	float resti = rbody->GetRestitution();
	float maxlinvel = rbody->GetMaxLinearVelocity();
	float maxangvel = rbody->GetMaxAngularVelocity();
	float pendepth = rbody->GetPenetrationDepth();
	InertiaMatrix im = rbody->GetInertia();

	Modifier* rbMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_RIGIDBODY_MODIFIER_CLASS_ID);
	if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_RB_MOD_PBLOCK)) {
		//These are fundamental parameters
		rbParameters->SetValue(PA_RB_MOD_MASS, 0, mass, 0);
		rbParameters->SetValue(PA_RB_MOD_RESTITUTION, 0, resti, 0);
		rbParameters->SetValue(PA_RB_MOD_FRICTION, 0, frict, 0);
		rbParameters->SetValue(PA_RB_MOD_INERTIA_TENSOR, 0, Point3(im[0][0],im[1][1],im[2][2]), 0);

		rbParameters->SetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, 0);
		rbParameters->SetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, 0);

		rbParameters->SetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, 0);
		rbParameters->SetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, 0);

		rbParameters->SetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, 0);


		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_FIXED, 0);
		rbParameters->SetValue(PA_RB_MOD_SOLVER_DEACTIVATION, 0, SD_LOW, 0);
		rbParameters->SetValue(PA_RB_MOD_DEACTIVATOR_TYPE, 0, DT_LOW, 0);

		/*body->SetMotionSystem(MotionSystem::MO_SYS_BOX);
		body->SetDeactivatorType(DeactivatorType::DEACTIVATOR_NEVER);
		body->SetSolverDeactivation(SolverDeactivation::SOLVER_DEACTIVATION_LOW);
		body->SetQualityType(MO_QUAL_FIXED);*/


		/*switch (qtype) {
		case MO_QUAL_INVALID:
			break;
		case MO_QUAL_FIXED:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_FIXED, 0);
			break;
		case MO_QUAL_KEYFRAMED:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED, 0);
			break;
		case MO_QUAL_DEBRIS:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_DEBRIS, 0);
			break;
		case MO_QUAL_MOVING:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_MOVING, 0);
			break;
		case MO_QUAL_CRITICAL:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_CRITICAL, 0);
			break;
		case MO_QUAL_BULLET:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_BULLET, 0);
			break;
		case MO_QUAL_USER:
			break;
		case MO_QUAL_CHARACTER:
			break;
		case MO_QUAL_KEYFRAMED_REPORT:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED_REPORTING, 0);
			break;
		}*/


	}

	//Link Rigid Body to parent Rigid Body
	ICustAttribContainer* cc = rbMod->GetCustAttribContainer();

	if (!cc)
	{
		rbMod->AllocCustAttribContainer();
		cc = rbMod->GetCustAttribContainer();
	}
	CustAttrib* c = (CustAttrib*)CreateInstance(CUST_ATTRIB_CLASS_ID, Class_ID(0x6e663460, 0x32682c72));
	IParamBlock2* custModParameters = c->GetParamBlock(0);
	custModParameters->SetValue(0, 0, parent, 0);

	cc->InsertCustAttrib(0, c);

	Modifier* constraintMod = nullptr;

	vector< bhkSerializableRef > constraints = rbody->GetConstraints();
	//Rigid Body constraints
	if (ragdollParent) {

		for (vector< bhkSerializableRef >::iterator it = constraints.begin(); it != constraints.end(); ) {
			bhkConstraintRef constraint = bhkConstraintRef(*it);
			if (constraint->IsDerivedType(bhkLimitedHingeConstraint::TYPE)) {
				bhkLimitedHingeConstraintRef limitedHingeConstraint = bhkLimitedHingeConstraintRef(*it);
				LimitedHingeDescriptor lh = limitedHingeConstraint->GetLimitedHinge();
				constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_HINGE_CLASS_ID);
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);

					Point3 origin(0, 0, 0);

					Matrix3 parentRotation(TOPOINT3(lh.perp2AxleInA1), TOPOINT3(lh.perp2AxleInA2), TOPOINT3(lh.axleA), origin);
					Matrix3 childRotation(TOPOINT3(lh.perp2AxleInB1), TOPOINT3(lh.perp2AxleInB2), TOPOINT3(lh.axleB), origin);

					//Matrix3 parentRotation(true);
					//MatrixFromNormal(TOPOINT3(lh.axleA), parentRotation);
					//Matrix3 childRotation(true);
					//MatrixFromNormal(TOPOINT3(lh.axleB), childRotation);

					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
					constraintParameters->SetValue(PA_HINGE_MOD_IS_LIMITED, 0, 1, 0);
					constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MIN, 0, TODEG(lh.minAngle), 0);
					constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MAX, 0, TODEG(lh.maxAngle), 0);
					constraintParameters->SetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, lh.maxFriction, 0);
					//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);
				}
			}
			else if (constraint->IsDerivedType(bhkRagdollConstraint::TYPE)) {
				bhkRagdollConstraintRef ragdollConstraint = bhkRagdollConstraintRef(*it);
				RagdollDescriptor rag = ragdollConstraint->GetRagdoll();
				constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_RAGDOLL_CLASS_ID);
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
					
					//TOVECTOR3(rag.twistA);
					//MatrixFromNormal(TOPOINT3(rag.twistA), parentRotation);
					Point3 origin(0,0,0);
					Matrix3 parentRotation(TOPOINT3(rag.planeA),TOPOINT3(rag.motorA),TOPOINT3(rag.twistA),origin);
					
					//TOVECTOR3(rag.twistB);
					//MatrixFromNormal(TOPOINT3(rag.twistB), childRotation);
					Matrix3 childRotation(TOPOINT3(rag.planeB), TOPOINT3(rag.motorB), TOPOINT3(rag.twistB), origin);

					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotB), 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotA), 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
					constraintParameters->SetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, TODEG(rag.coneMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, TODEG(rag.planeMinAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, TODEG(rag.planeMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, TODEG(rag.twistMinAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, TODEG(rag.twistMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, rag.maxFriction, 0);
				}
			}
			else if (constraint->IsDerivedType(bhkMalleableConstraint::TYPE)) {
				bhkMalleableConstraintRef malleableConstraint = bhkMalleableConstraintRef(*it);
				if (malleableConstraint->GetConstraintType() == (unsigned int)2) {
					LimitedHingeDescriptor lh = malleableConstraint->GetLimitedHinge();
					constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_HINGE_CLASS_ID);
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
						Point3 origin(0, 0, 0);

						Matrix3 parentRotation(TOPOINT3(lh.perp2AxleInA1), TOPOINT3(lh.perp2AxleInA2), TOPOINT3(lh.axleA), origin);
						Matrix3 childRotation(TOPOINT3(lh.perp2AxleInB1), TOPOINT3(lh.perp2AxleInB2), TOPOINT3(lh.axleB), origin);

						//Matrix3 parentRotation(true);
						//MatrixFromNormal(TOPOINT3(lh.axleA), parentRotation);
						//Matrix3 childRotation(true);
						//MatrixFromNormal(TOPOINT3(lh.axleB), childRotation);

						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
					}
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
						constraintParameters->SetValue(PA_HINGE_MOD_IS_LIMITED, 0, 1, 0);
						constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MIN, 0, TODEG(lh.minAngle), 0);
						constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MAX, 0, TODEG(lh.maxAngle), 0);
						constraintParameters->SetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, lh.maxFriction, 0);
						//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);
					}
				}
				else if (malleableConstraint->GetConstraintType() == (unsigned int)7) {
					RagdollDescriptor rag = malleableConstraint->GetRagdoll();
					constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_RAGDOLL_CLASS_ID);
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
						//TOVECTOR3(rag.twistA);
						//MatrixFromNormal(TOPOINT3(rag.twistA), parentRotation);
						Point3 origin(0, 0, 0);
						Matrix3 parentRotation(TOPOINT3(rag.planeA), TOPOINT3(rag.motorA), TOPOINT3(rag.twistA), origin);

						//TOVECTOR3(rag.twistB);
						//MatrixFromNormal(TOPOINT3(rag.twistB), childRotation);
						Matrix3 childRotation(TOPOINT3(rag.planeB), TOPOINT3(rag.motorB), TOPOINT3(rag.twistB), origin);


						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotB), 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotA), 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
					}
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
						constraintParameters->SetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, TODEG(rag.coneMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, TODEG(rag.planeMinAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, TODEG(rag.planeMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, TODEG(rag.twistMinAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, TODEG(rag.twistMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, rag.maxFriction, 0);
					}
				}
			}
			++it;
		}
	}

	dobj->SetAFlag(A_LOCK_TARGET);
	dobj->AddModifier(rbMod);
	if (constraintMod)
		dobj->AddModifier(constraintMod);
	dobj->ClearAFlag(A_LOCK_TARGET);
	n->SetObjectRef(dobj);

}
INode* HavokImport::ImportHCTSphere(bhkSphereShapeRef shape, INode * parent, INode* ragdollParent, Matrix3 & tm)
{
	USES_CONVERSION;
	bhkShapeRef retval;

	if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, HK_TAPEREDCAPSULE_CLASS_ID)) {

		if (IParamBlock2* pblock2 = obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK))
		{
			float radius = shape->GetRadius();
			int mtl = GetHavokIndexFromMaterials(ni.IsSkyrim() ? -1 : shape->GetMaterial(), ni.IsSkyrim() ? shape->GetSkyrimMaterial() : -1);
			//float radius1 = shape->GetRadius1() * ni.bhkScaleFactor;
			//float radius2 = shape->GetRadius2();
			//Vector3 pt1 = shape->GetFirstPoint();
			//Vector3 pt2 = shape->GetSecondPoint();
			float len = radius * ni.bhkScaleFactor;

			//Point3 center = (TOPOINT3(pt2 + pt1) / 2.0f) * ni.bhkScaleFactor;
			//Point3 norm = Normalize(TOPOINT3(len));
			//Matrix3 mat;
			//MatrixFromNormal(norm, mat);
			//Matrix3 newTM = tm * mat * TransMatrix(center);

			pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, len, 0);
			//			pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, 1.0, 0);

			if (INode *n = ni.CreateImportNode(A2T(shape->GetType().GetTypeName().c_str()), obj, ragdollParent)) {
				//				ImportBase(body, shape, parent, n, newTM);
				const int MaxChar = 512;
				char buffer[MaxChar];
				//TSTR name(A2THelper(buffer, parent->GetName().c_str(), _countof(buffer)));
				n->SetName(FormatText(TEXT("Ragdoll_%s"), parent->GetName()));
				PosRotScale prs = prsDefault;

				//n->SetObjOffsetScale(ScaleValue(Point3(1, 1, 1)));

				Point3 pos = tm.GetTrans();
				Quat rot(tm);
				PosRotScaleNode(n, pos, rot, 1.0, prsDefault);

				Object *pObj = n->GetObjectRef();
				IDerivedObject *dobj = nullptr;
				if (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
					dobj = static_cast<IDerivedObject*>(pObj);
				else {
					dobj = CreateDerivedObject(pObj);
				}


				Modifier* shapeMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_SHAPE_MODIFIER_CLASS_ID);
				if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) {
					shapeParameters->SetValue(PA_SHAPE_MOD_SHAPE_TYPE, 0, 1, 0);
				}

				dobj->SetAFlag(A_LOCK_TARGET);
				dobj->AddModifier(shapeMod);
				dobj->ClearAFlag(A_LOCK_TARGET);
				n->SetObjectRef(dobj);

				//AddShape(rbody, n);
				return n;
			}
		}
	}
	return ragdollParent;
}
示例#10
0
CustomAttributes_struct MaxAWDExporter::GetCustomAWDObjectSettings(IDerivedObject * node_der,Animatable *obj)
{
    CustomAttributes_struct returnData;
    returnData.export_this=true;
    returnData.export_this_children=true;
    if(node_der!=NULL){
        int nMods = node_der->NumModifiers();
        for (int m = 0; m<nMods; m++){
            Modifier* node_mod = node_der->GetModifier(m);
            if (node_mod->IsEnabled()){
                MSTR className;
                node_mod->GetClassName(className);
                char * className_ptr=W2A(className);
                if (ATTREQ(className_ptr,"AWDObjectSettings")){
                    IParamBlock2* pb = GetParamBlock2ByIndex((ReferenceMaker*)node_mod, 0);
                    if(pb!=NULL){
                        int numBlockparams=pb->NumParams();
                        int p=0;
                        for (p=0; p<numBlockparams; p++) {
                            ParamID pid = pb->IndextoID(p);
                            ParamDef def = pb->GetParamDef(pid);
                            ParamType2 paramtype = pb->GetParameterType(pid);
                            char * paramName_ptr=W2A(def.int_name);
                            if (ATTREQ(paramName_ptr, "thisAWDID")){
                                //if (paramtype==TYPE_STRING)
                                //    skeletonMod_ptr=W2A(pb->GetStr(pid));
                            }
                            if (ATTREQ(paramName_ptr, "Export")){
                                if (paramtype==TYPE_BOOL)
                                    returnData.export_this=(0 != pb->GetInt(pid));
                            }
                            if (ATTREQ(paramName_ptr, "ExportChildren")){
                                if (paramtype==TYPE_BOOL)
                                    returnData.export_this_children=(0 != pb->GetInt(pid));
                            }
                        }
                    }
                    free (className_ptr);
                    return returnData;
                }
                free (className_ptr);
            }
        }
        Object * thisOBJ=(Object *)node_der->GetObjRef();
        if(thisOBJ!=NULL){
            if((thisOBJ->SuperClassID() == GEN_DERIVOB_CLASS_ID) || (thisOBJ->SuperClassID() == WSM_DERIVOB_CLASS_ID) || (thisOBJ->SuperClassID() == DERIVOB_CLASS_ID )){
                IDerivedObject* thisDerObj=( IDerivedObject* ) thisOBJ;
                if(thisDerObj!=NULL){
                    int nMods = thisDerObj->NumModifiers();
                    for (int m = 0; m<nMods; m++){
                        Modifier* node_mod = thisDerObj->GetModifier(m);
                        if (node_mod->IsEnabled()){
                            MSTR className;
                            node_mod->GetClassName(className);
                            char * className_ptr=W2A(className);
                            if (ATTREQ(className_ptr,"AWDObjectSettings")){
                                IParamBlock2* pb = GetParamBlock2ByIndex((ReferenceMaker*)node_mod, 0);
                                if(pb!=NULL){
                                    int numBlockparams=pb->NumParams();
                                    int p=0;
                                    for (p=0; p<numBlockparams; p++) {
                                        ParamID pid = pb->IndextoID(p);
                                        ParamDef def = pb->GetParamDef(pid);
                                        ParamType2 paramtype = pb->GetParameterType(pid);
                                        char * paramName_ptr=W2A(def.int_name);
                                        if (ATTREQ(paramName_ptr, "thisAWDID")){
                                            //if (paramtype==TYPE_STRING)
                                            //    skeletonMod_ptr=W2A(pb->GetStr(pid));
                                        }
                                        if (ATTREQ(paramName_ptr, "export")){
                                            if (paramtype==TYPE_BOOL)
                                                returnData.export_this=(0 != pb->GetInt(pid));
                                        }
                                        if (ATTREQ(paramName_ptr, "exportChildren")){
                                            if (paramtype==TYPE_BOOL)
                                                returnData.export_this_children=(0 != pb->GetInt(pid));
                                        }
                                    }
                                }
                                free (className_ptr);
                                return returnData;
                            }
                            free (className_ptr);
                        }
                    }
                }
            }
        }
    }

    while(obj->SuperClassID() != BASENODE_CLASS_ID) {
        if (obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
          IDerivedObject *dobj = (IDerivedObject *)obj;
          obj = dobj->GetObjRef();  // Get next object down mod-stack.
        }
        else {
          break;  // Failed.
        }
    }
    ICustAttribContainer *attributes = obj->GetCustAttribContainer();

    if (attributes) {
        int a=0;
        int numAttribs=0;
        numAttribs = attributes->GetNumCustAttribs();
        for (a=0; a<numAttribs; a++) {
            int p=0;
            int t=0;
            CustAttrib *attr = attributes->GetCustAttrib(a);
            for (t=0; t<attr->NumParamBlocks(); t++) {
                IParamBlock2 *block = attr->GetParamBlock(t);
                char * localName_ptr=W2A(block->GetLocalName());
                if (ATTREQ(localName_ptr,"AWD_Export") ){
                    for (p=0; p<block->NumParams(); p++) {
                        ParamID pid = block->IndextoID(p);
                        ParamDef def = block->GetParamDef(pid);
                        char * paramName_ptr=W2A(def.int_name);
                        if (block->GetParameterType(pid)==TYPE_BOOL){
                            if (ATTREQ(paramName_ptr,"Export") )
                                returnData.export_this= (0 != block->GetInt(pid));
                            else if (ATTREQ(paramName_ptr,"ExportChildren") )
                                returnData.export_this_children= (0 != block->GetInt(pid));
                        }
                        free(paramName_ptr);
                    }
                }
                free(localName_ptr);
            }
        }
    }
    return returnData;
}
示例#11
0
void ResetXForm::ResetNodes(const INodeTab& nodesToReset)
{
	Interface *ip = GetCOREInterface();
	for (int i = 0; i < nodesToReset.Count(); i++) {
		INode *node = nodesToReset[i];
		if (!node || node->IsGroupMember() || node->IsGroupHead()) 
			continue;
		if (SelectedAncestor(node)) 
			continue;

		Matrix3 ntm, ptm, rtm(1), piv(1), tm;
		
		// Get Parent and Node TMs
		ntm = node->GetNodeTM(ip->GetTime());
		ptm = node->GetParentTM(ip->GetTime());
		
		// Compute the relative TM
		ntm = ntm * Inverse(ptm);
		
		// The reset TM only inherits position
		rtm.SetTrans(ntm.GetTrans());
		
		// Set the node TM to the reset TM		
		tm = rtm*ptm;
		node->SetNodeTM(ip->GetTime(), tm);

		// Compute the pivot TM
		piv.SetTrans(node->GetObjOffsetPos());
		PreRotateMatrix(piv,node->GetObjOffsetRot());
		ApplyScaling(piv,node->GetObjOffsetScale());
		
		// Reset the offset to 0
		node->SetObjOffsetPos(Point3(0,0,0));
		node->SetObjOffsetRot(IdentQuat());
		node->SetObjOffsetScale(ScaleValue(Point3(1,1,1)));

		// Take the position out of the matrix since we don't reset position
		ntm.NoTrans();

		// Apply the offset to the TM
		ntm = piv * ntm;

		// Apply a derived object to the node's object
		Object *obj = node->GetObjectRef();
		IDerivedObject *dobj = CreateDerivedObject(obj);
		
		// Create an XForm mod
		SimpleMod *mod = (SimpleMod*)ip->CreateInstance(
			OSM_CLASS_ID,
			Class_ID(CLUSTOSM_CLASS_ID,0));

		// Apply the transformation to the mod.
		SetXFormPacket pckt(ntm);
		mod->tmControl->SetValue(ip->GetTime(),&pckt);

		// Add the modifier to the derived object.
		dobj->SetAFlag(A_LOCK_TARGET); // RB 3/11/99: When the macro recorder is on the derived object will get deleted unless it is locked.
		dobj->AddModifier(mod);
		dobj->ClearAFlag(A_LOCK_TARGET);

		// Replace the node's object
		node->SetObjectRef(dobj);
	}
	
//	Why on earth were we clearing the undo stack?
//	GetSystemSetting(SYSSET_CLEAR_UNDO);
	ip->RedrawViews(ip->GetTime());
	SetSaveRequiredFlag(TRUE);
}