Ejemplo n.º 1
0
int	  BonesDefMod::GetMirrorBone(Point3 center, int axis)
	{
	//get current bone
	INode *node = BoneData[ModeBoneIndex].Node;
	if (node)
		{
	//get tm
		Matrix3 iMirrorTM(1);
		iMirrorTM.SetRow(3,center);
		iMirrorTM = Inverse(iMirrorTM);
		TimeValue t = GetCOREInterface()->GetTime();
		Matrix3 tm = node->GetNodeTM(t);
		Point3 mirrorPoint = Point3(0.0f,0.0f,0.0f) * tm;
		mirrorPoint = mirrorPoint * iMirrorTM;
	//mirror its location
		mirrorPoint[axis] *= -1.0f;




	//loop through all the bones
		int closestBone = -1;
		float closestDist= 0.0f;
		Box3 bounds;
		bounds.Init();
		for (int i = 0; i < BoneData.Count(); i++)
			{
			node = BoneData[i].Node;
	//get there tm
			if ((node) && (i!=ModeBoneIndex))
				{	
	//find closest bone
				tm = node->GetNodeTM(t);
				Point3 bonePoint = Point3(0.0f,0.0f,0.0f) * tm;
				bonePoint = bonePoint * iMirrorTM;
				bounds += bonePoint;
				float dist = Length(bonePoint-mirrorPoint);
				if ( (closestBone == -1) || (dist < closestDist) )
					{
					closestDist = dist;
					closestBone = i;
					}
				}
			}
		float threshold = Length(bounds.pmax-bounds.pmin)/100.0f;
		if (closestDist < threshold)
			return closestBone;

		}
	
	return -1;
	}
Ejemplo n.º 2
0
BOOL plDistributor::ISpaceClear(int iRepNode, const Matrix3& l2w, Box3& clearBox, plMeshCacheTab& cache) const
{
    if( !fDistTree )
        return true;

    // If we have high isolation,
    //      clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing));
    // Else if we have medium isolation
    //      clearBox = cache[iRepNode]->getBoundingBox(); // The mesh's bounds
    // Else if we have low isolation or None isolation
    //      clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); // kSmallSpace ~= 0.5f or one or something

    // We want to set up the box (for high, low and none) in Post OTM space. So instead of multiplying
    // by l2w, we want to multiply box = box * invOTM * l2w (because l2w already has OTM folded in). When using
    // the mesh bounds (Medium), l2w is the right transform.
    // objectTM = otm * nodeTM
    // invOTM * objectTM = nodeTM
    // invOTM = nodeTM * invObjectTM
    const float kSmallSpace = 0.5f;
    switch( fIsolation )
    {
    case kIsoHigh:
        {
            INode* repNode = fRepNodes[iRepNode];
            Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
            Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
            Matrix3 invOTM = nodeTM * Inverse(objectTM);
            clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0.f), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing));
            clearBox = clearBox * invOTM;
        }
        break;
    case kIsoMedium:
        clearBox = cache[iRepNode].fMesh->getBoundingBox(); // The mesh's bounds
        break;
    case kIsoLow:
    case kIsoNone:
    default:
        {
            INode* repNode = fRepNodes[iRepNode];
            Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
            Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
            Matrix3 invOTM = nodeTM * Inverse(objectTM);
            clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0.f), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); 
            clearBox = clearBox * invOTM;
        }
        break;
    }

    clearBox = clearBox * l2w;

    return fDistTree->BoxClear(clearBox, fFade);
}
Ejemplo n.º 3
0
void bhkProxyObject::BuildColCapsule()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);	
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	Point3 pt1 = Point3::Origin;
	Point3 pt2 = Point3::Origin;
	float r1 = 0.0;
	float r2 = 0.0;

	if (proxyMesh.getNumVerts() > 3) // Doesn't guarantee that the mesh is not a plane.
	{
		CalcCapsule(proxyMesh, pt1, pt2, r1, r2);
		BuildCapsule(proxyMesh, pt1, pt2, r1, r2);
	}

	proxyPos = Point3::Origin;
	forceRedraw = true;
}
Ejemplo n.º 4
0
void MembraneVertexShader::GetCameraPosition(Point3 &Pos)
{
	Interface *ip = GetCOREInterface();
	INode *pObj;
	Matrix3 objTM;
	Pos.x = 0.0f;
	Pos.y = 0.0f;
	Pos.z = -200.0f;

	INode *pRoot =ip->GetRootNode();
	int numNodes = pRoot->NumberOfChildren();
	for( int ctr = 0; ctr < numNodes; ctr++) {
		pObj = pRoot->GetChildNode(ctr);
		// The ObjectState is a 'thing' that flows down the pipeline containing
		// all information about the object. By calling EvalWorldState() we tell
		// max to eveluate the object at end of the pipeline.
		ObjectState os = pObj->EvalWorldState(ip->GetTime());
		
		// The obj member of ObjectState is the actual object we will export.
		if (os.obj) {
			// We look at the super class ID to determine the type of the object.
			switch(os.obj->SuperClassID()) {
			case CAMERA_CLASS_ID:
				objTM  = pObj->GetNodeTM(ip->GetTime());
				Pos = objTM.GetTrans();
				break;
			}
		}
	}
}
Ejemplo n.º 5
0
void bhkProxyObject::BuildColConvex()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);	
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	compute_convex_hull(proxyMesh, proxyMesh);

	BuildOptimize(proxyMesh);

	proxyPos = Point3::Origin;
	forceRedraw = true;
}
Ejemplo n.º 6
0
void bhkProxyObject::BuildColBox()
{
	Box3 box; box.Init();
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);	
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Box3 box2; box2.Init();
				Mesh& mesh = tri->GetMesh();
				CalcAxisAlignedBox(mesh, box2, &wm);
				box += box2;
			}
		}
	}
	BuildBox(proxyMesh, box.Max().y-box.Min().y, box.Max().x-box.Min().x, box.Max().z-box.Min().z);

	MNMesh mn(proxyMesh);
	Matrix3 tm(true);
	tm.SetTranslate(box.Center());
	mn.Transform(tm);
	mn.OutToTri(proxyMesh);

	//proxyPos = box.Center();
	proxyPos = Point3::Origin;
	forceRedraw = true;
}
Ejemplo n.º 7
0
//=================================================================
// Methods for CollectNodesTEP
//
int CollectNodesTEP::callback(INode *node)
{
	INode *pnode = node; // Hungarian

	ASSERT_MBOX(!(pnode)->IsRootNode(), "Encountered a root node!");

	if (::FNodeMarkedToSkip(pnode))
		return TREE_CONTINUE;

	// Get pre-stored "index"
	int iNode = ::GetIndexOfINode(pnode);
	ASSERT_MBOX(iNode >= 0 && iNode <= m_phec->m_imaxnodeMac-1, "Bogus iNode");
	
	// Get name, store name in array
	TSTR strNodeName(pnode->GetName());
	strcpy(m_phec->m_rgmaxnode[iNode].szNodeName, (char*)strNodeName);

	// Get Node's time-zero Transformation Matrices
	m_phec->m_rgmaxnode[iNode].mat3NodeTM		= pnode->GetNodeTM(0/*TimeValue*/);
	m_phec->m_rgmaxnode[iNode].mat3ObjectTM		= pnode->GetObjectTM(0/*TimeValue*/);

	// I'll calculate this later
	m_phec->m_rgmaxnode[iNode].imaxnodeParent	= SmdExportClass::UNDESIRABLE_NODE_MARKER;

	return TREE_CONTINUE;
}
Ejemplo n.º 8
0
Matrix3 plDistributor::IOTM(int iRepNode) const
{
    // objectTM = otm * nodeTM
    // objectTM * Inverse(nodeTM) = otm
    INode* repNode = fRepNodes[iRepNode];
    Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
    Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
    Matrix3 OTM = objectTM * Inverse(nodeTM);
    return OTM;
}
Ejemplo n.º 9
0
Matrix3 plDistributor::IInvOTM(int iRepNode) const
{
    // objectTM = otm * nodeTM
    // invOTM * objectTM = nodeTM
    // invOTM = nodeTM * invObjectTM
    INode* repNode = fRepNodes[iRepNode];
    Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
    Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
    Matrix3 invOTM = nodeTM * Inverse(objectTM);
    return invOTM;
}
Ejemplo n.º 10
0
//=================================================================
// Methods for DumpFrameRotationsTEP
//
int DumpFrameRotationsTEP::callback(INode *pnode)
{
	ASSERT_MBOX(!(pnode)->IsRootNode(), "Encountered a root node!");

	if (::FNodeMarkedToSkip(pnode))
		return TREE_CONTINUE;

	int iNode = ::GetIndexOfINode(pnode);

	TSTR strNodeName(pnode->GetName());

	// The model's root is a child of the real "scene root"
	INode *pnodeParent = pnode->GetParentNode();
	BOOL fNodeIsRoot = pnodeParent->IsRootNode( );

	// Get Node's "Local" Transformation Matrix
	Matrix3 mat3NodeTM		= pnode->GetNodeTM(m_tvToDump);
	Matrix3 mat3ParentTM	= pnodeParent->GetNodeTM(m_tvToDump);
	mat3NodeTM.NoScale();		// Clear these out because they apparently
	mat3ParentTM.NoScale();		// screw up the following calculation.
	Matrix3 mat3NodeLocalTM	= mat3NodeTM * Inverse(mat3ParentTM);
	Point3 rowTrans = mat3NodeLocalTM.GetTrans();

	// check to see if the parent bone was mirrored.  If so, mirror invert this bones position
	if (m_phec->m_rgmaxnode[iNode].imaxnodeParent >= 0 && m_phec->m_rgmaxnode[m_phec->m_rgmaxnode[iNode].imaxnodeParent].isMirrored)
	{
		rowTrans = rowTrans * -1.0f;
	}

	// Get the rotation (via decomposition into "affine parts", then quaternion-to-Euler)
	// Apparently the order of rotations returned by QuatToEuler() is X, then Y, then Z.
	AffineParts affparts;
	float rgflXYZRotations[3];

	decomp_affine(mat3NodeLocalTM, &affparts);
	QuatToEuler(affparts.q, rgflXYZRotations);

	float xRot = rgflXYZRotations[0];		// in radians
	float yRot = rgflXYZRotations[1];		// in radians
	float zRot = rgflXYZRotations[2];		// in radians

	// Get rotations in the -2pi...2pi range
	xRot = ::FlReduceRotation(xRot);
	yRot = ::FlReduceRotation(yRot);
	zRot = ::FlReduceRotation(zRot);
	
	// Print rotations
	fprintf(m_pfile, "%3d %f %f %f %f %f %f\n", 
		// Node:%-15s Rotation (x,y,z)\n",
		iNode, rowTrans.x, rowTrans.y, rowTrans.z, xRot, yRot, zRot);

	return TREE_CONTINUE;
}
Ejemplo n.º 11
0
BOOL PickControlNode::Pick(IObjParam *ip,ViewExp *vpt)
   {

	 if ( ! vpt || ! vpt->IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return FALSE;
	}

   INode *node = vpt->GetClosestHit();
   if (node) {
      // RB 3/1/99: This should use the node tm not the object TM. See ModifyObject() imp.
      Matrix3 ourTM,ntm = node->GetNodeTM(GetCOREInterface()->GetTime()); //node->GetObjectTM(ip->GetTime());  

      ModContextList mcList;
      INodeTab nodes;
      ip->GetModContexts(mcList,nodes);
      if (nodes.Count())
         {
         ourTM = nodes[0]->GetObjectTM(GetCOREInterface()->GetTime());
         ourTM    = Inverse(ourTM);
         Box3 bounds;
         bounds.Init();
         ObjectState os = node->EvalWorldState(GetCOREInterface()->GetTime());
         ViewExp& vp = GetCOREInterface()->GetActiveViewExp();
         if ( ! vp.IsAlive() )
				 {
				 	// why are we here
				 	DbgAssert(!_T("Invalid viewport!"));
				 	return FALSE;
				 }
				 os.obj->GetWorldBoundBox(GetCOREInterface()->GetTime(), node, vp.ToPointer(), bounds );
         
         Point3 min = bounds.pmin * ourTM;
         Point3 max = bounds.pmax * ourTM;
         theHold.Begin();
         mod->pblock2->SetValue(particlemesher_customboundsa,0,min);
         mod->pblock2->SetValue(particlemesher_customboundsb,0,max);
         theHold.Accept(GetString(IDS_BOUNDS));
         mod->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
         mod->UpdateUI();


         }

      nodes.DisposeTemporary();
      }
   return TRUE;
   }
Ejemplo n.º 12
0
Matrix3 Exporter::getObjectTransform(INode *node, TimeValue t, bool local)
{
   Matrix3 tm = node->GetObjTMAfterWSM(t);
   if (local)
   {
      INode *parent = node->GetParentNode();
      if (parent != NULL) {
         Matrix3 pm = parent->GetNodeTM(t);
         pm.Invert();
         tm *= pm;
      }
   }
   return tm;
}
Ejemplo n.º 13
0
// REAPPLYANIMATION
// Now that we've reparented a node within the hierarchy, re-apply all its animation.
void ReapplyAnimation(INode *node, plSampleVec *samples)
{
    Control *controller = node->GetTMController();

    Control *rotControl = NewDefaultRotationController();   // we set the default rotation controller type above in RemoveBiped()
    Control *posControl = NewDefaultPositionController();   // '' ''
    Control *scaleControl = NewDefaultScaleController();    // '' ''
    
    controller->SetRotationController(rotControl);
    controller->SetPositionController(posControl);
    controller->SetScaleController(scaleControl);

    for(int i = 0; i < samples->size(); i++)
    {
        nodeTMInfo *info = (*samples)[i];
        Matrix3 m = info->fMat3;
        TimeValue t = info->fTime;

#if 1
        node->SetNodeTM(t, m);
#else
        AffineParts parts;

        INode *parent = node->GetParentNode();
        Matrix3 parentTM = parent->GetNodeTM(t);
        Matrix3 invParentTM = Inverse(parentTM);
        m *= invParentTM;

        decomp_affine(m, &parts);

        Quat q(parts.q.x, parts.q.y, parts.q.z, parts.q.w);
        Point3 p(parts.t.x, parts.t.y, parts.t.z);

        rotControl->SetValue(t, q);
        posControl->SetValue(t, p);
#endif
    }

    IKeyControl *posKeyCont = GetKeyControlInterface(posControl);
    IKeyControl *scaleKeyCont = GetKeyControlInterface(scaleControl);

    ReduceKeys<ILinPoint3Key>(node, posKeyCont);
    EliminateScaleKeys(node, scaleKeyCont);
    // grrrr ReduceKeys<ILinScaleKey>(node, scaleKeyCont);
}
Ejemplo n.º 14
0
// Clone the replicant and set its transform appropriately. Should set the plMaxNode property
// that the node's spans are collapseable? No, we'll make a separate component for that.
void plDistributor::IReplicate(Matrix3& l2w, int iRepNode, plDistribInstTab& reps, plMeshCache& mCache) const
{
    INode* repNode = fRepNodes[iRepNode];
    plDistribInstance inst;
    inst.fNode = repNode;
    inst.fNodeTM = l2w;
    inst.fObjectTM = repNode->GetObjectTM(TimeValue(0)) * Inverse(repNode->GetNodeTM(TimeValue(0))) * l2w;

    inst.fMesh = mCache.fMesh;

    inst.fFlex = mCache.fFlex;

    inst.fFade = fFade;

    inst.fBone = fBone;

    inst.fRigid = fRigid;

    reps.Append(1, &inst);
}
Ejemplo n.º 15
0
void bhkProxyObject::BuildColOBB()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);	
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	Matrix3 rtm(true);
	Point3 center = Point3::Origin;;
	float udim = 0.0f, vdim = 0.0f, ndim = 0.0f;

	if (proxyMesh.getNumVerts() > 3) // Doesn't guarantee that the mesh is not a plane.
	{
		// First build a convex mesh to put the box around;
		// the method acts oddly if extra vertices are present.
		BuildColConvex();
		CalcOrientedBox(proxyMesh, udim, vdim, ndim, center, rtm);
		BuildBox(proxyMesh, vdim, udim, ndim);
	}

	MNMesh mn(proxyMesh);
	mn.Transform(rtm);
	mn.OutToTri(proxyMesh);

	proxyPos = Point3::Origin;
	forceRedraw = true;
}
Ejemplo n.º 16
0
Matrix3 Jiggle::GetCurrentTM(TimeValue t)
{
	INode* baseNode = NULL;
	baseNode = selfNode;

	Matrix3 selfTM;
	Point3 pos = Point3(0.0f,0.0f,0.0f);
	Interval for_ever = FOREVER;
	posCtrl->GetValue(t, pos, for_ever, CTRL_ABSOLUTE);
	if (baseNode != NULL )
	{
		selfTM = baseNode->GetNodeTM(t);
		selfTM.SetTrans(selfTM * pos);
	}
	else 
	{	
		selfTM.IdentityMatrix();
		selfTM.SetTrans(pos);
	}
	return selfTM;
}
Ejemplo n.º 17
0
//---------------------------------------------------------------------------
//
// This implementation of NfGetLocalTM removes all scales from the returned
// Matrix3, but also stores them in the parameter pScaleOut (if specified)
// so that they can be pushed down to the geometry level.
//
Matrix3 U2MaxSceneExport::GetLocalTM(INode* pMaxNode, TimeValue t)
{
	Matrix3 localScaleTM;
	INode* pParent = pMaxNode->GetParentNode();


	if(pParent)
	{
		Matrix3 parentTM = pParent->GetNodeTM(t);
		Matrix3 thisTM = pMaxNode->GetNodeTM(t);

		localScaleTM = thisTM * Inverse(parentTM);		
	}
	else 
		localScaleTM.IdentityMatrix();

	Matrix3 localNoScaleTM;
	localNoScaleTM = UniformMatrix(localScaleTM);

	return localNoScaleTM;

}
Ejemplo n.º 18
0
//From SpringSysClient
//*************************************************
Tab<Matrix3> Jiggle::GetForceMatrices(TimeValue t)
{
	Tab<Matrix3> tms;
	INode* node;
	Matrix3 parentTM;
	
	parentTM = GetCurrentTM(t);

	tms.Append(1, &parentTM);
	
	for (int x=1;x<dyn_pb->Count(jig_control_node); x++)
	{
		Interval for_ever = FOREVER;
		dyn_pb->GetValue(jig_control_node, 0, node, for_ever, x);
		if (node)
		{
			Matrix3 mat = node->GetNodeTM(t);
			tms.Append(1, &mat);
		}
	}
	return tms;
}
Ejemplo n.º 19
0
Matrix3 CActionExporter::get_bone_tm(CSkeletonExporter* pSkeleton,int boneIndex,unsigned int iMaxTime)
{
         sMaxBoneNode_t bone = pSkeleton->m_MaxBones[boneIndex];
         Matrix3        boneInitMTInv;
         if(G_MaxEnv().m_bUseBeforeSkeletonPose)
             boneInitMTInv = bone.m_SkinInitMT;
         else
             boneInitMTInv = bone.m_InitNodeTM0;

         boneInitMTInv.Invert();
         INode* pNode = bone.m_pNode;

         Matrix3 BoneTM = boneInitMTInv * pNode->GetNodeTM(iMaxTime); //>GetNodeTM(iMaxTime);
         Point3 Trans = BoneTM.GetTrans();
         BoneTM.NoTrans();
         //对骨骼进行缩放
         Trans.x *= pSkeleton->m_fScale;
         Trans.y *= pSkeleton->m_fScale;
         Trans.z *= pSkeleton->m_fScale;
         BoneTM.SetTrans(Trans);

         return BoneTM;

}
Ejemplo n.º 20
0
int
CMaxAnimationImport::DoImport(
  const TCHAR* name,
  ImpInterface* ii,
  Interface* i,
  BOOL suppressPrompts)
{
  AFX_MANAGE_STATE(AfxGetStaticModuleState());

  HWND window = i->GetMAXHWnd();

  CFileDialog fileDialog(TRUE, "xsf", 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                         0, CWnd::FromHandle(window));
  if (fileDialog.DoModal() != IDOK) {
    return IMPEXP_CANCEL;
  }

  CString skeleton = fileDialog.GetPathName();
  
  CalCoreSkeletonPtr skel = CalLoader::loadCoreSkeleton(std::string(skeleton));
  if (!skel) {
    MessageBox(
      window, "Loading skeleton file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

  CalCoreAnimationPtr anim = CalLoader::loadCoreAnimation(name);
  if (!anim) {
    MessageBox(
      window, "Loading animation file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

  // Get the pose information in the animation
  const std::vector<CalTransform>& poses = anim->getPoses();
  unsigned int num_poses = poses.size() / anim->getTrackCount();

  // Calculate the time_per_frame incorrectly since the duration for animations
  // is stored incorrectly.
  float time_per_frame = anim->getDuration() / num_poses;

  // Import each track
  for (unsigned track_id = 0; track_id < anim->getTrackCount(); ++track_id)
  {
    // Get the core bone mapped to the animation
    int bone_id = anim->getBoneAssignment(track_id);
    CalCoreBone* bone = skel->getCoreBone(bone_id);
    if (!bone) continue;

    // Get the max node for the bone
    INode* node = i->GetINodeByName(bone->getName().c_str());
    if (!node) continue;

    SuspendAnimate();
    AnimateOn();

    // Add each pose keyframe in the track
    float keyframe_time = 0.0f;
    for (unsigned keyframe_index = 0; keyframe_index < num_poses; ++keyframe_index)
    {
      // Get the keyframe data
      const CalTransform& pose_coord_sys = poses[(keyframe_index * anim->getTrackCount()) + track_id];
      const CalVector     &kf_v = pose_coord_sys.getTranslation();
      const CalQuaternion &kf_q = pose_coord_sys.getRotation();
      TimeValue time = SecToTicks(keyframe_time);

      // Convert to Max math
      Matrix3 tm;
      tm.IdentityMatrix();
      Quat(kf_q.x, kf_q.y, kf_q.z, kf_q.w).MakeMatrix(tm);
      tm.SetTrans(Point3(kf_v.x, kf_v.y, kf_v.z));

      // Convert the transform to world space
      INode* parent = node->GetParentNode();
      if (parent)
      {
        tm *= parent->GetNodeTM(time);
      }

      // Set the new transform on the node
      node->SetNodeTM(time, tm);

      keyframe_time += time_per_frame;
    }

    ResumeAnimate();

/*
    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();

    int mapsize = sizeof(keys);

    int size = keys.size();

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      Point3 p;
      CalCoreKeyframe* kf = mi->second;
      p.x = kf->getTranslation().x;
      p.y = kf->getTranslation().y;
      p.z = kf->getTranslation().z;
      pos->SetValue(SecToTicks(mi->first), &p);
    }
*/

/*
    IKeyControl* kc = GetKeyControlInterface(pos);
    if (!kc) continue;

    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();
    kc->SetNumKeys(keys.size());

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      ITCBPoint3Key key;
      key.time = SecToTicks(mi->first);
      key.tens = 0;
      key.cont = 0;
      key.bias = 0;
      key.easeIn = 25.0;
      key.easeOut = 25.0;
      key.val.x = mi->second->getTranslation().x;
      key.val.y = mi->second->getTranslation().y;
      key.val.z = mi->second->getTranslation().z;

      kc->SetKey(idx++, &key);
    }

    kc->SortKeys();
*/
  }
  

  return IMPEXP_SUCCESS;
}
Ejemplo n.º 21
0
void ParticleMesherObject::BuildMesh(TimeValue t)
   {
//check if render time
//get node
//mkae ivalid interesect with the 
   int isRendering = 0;
   ivalid = FOREVER;

   TimeValue offset;
   float foffset;
   Interval iv;
   pblock2->GetValue(particlemesher_time, 0, foffset, iv);
   foffset = -foffset;
   pblock2->GetValue(particlemesher_radius, 0, radius, iv);
   foffset *= GetTicksPerFrame();
   offset = (TimeValue) foffset;

// pblock2->GetValue(particlemesher_time, 0, foffset, iv);
   if ((lastTime == t)  )
      {
      ivalid.Set(t,t);
      return;
      }


   pblock2->GetValue(particlemesher_rendertimeonly, 0, isRendering, ivalid);
   isRendering = !isRendering;
    if ((isRendering) || (TestAFlag(A_RENDER)))
      {
      INode *node=NULL;
      pblock2->GetValue(particlemesher_pick, 0, node, ivalid);

      
      BOOL reevalGroup = FALSE;
      if ((node != NULL) && (node->IsGroupHead()) )
         {  
         for (int ch=0;ch<node->NumberOfChildren();ch++)
            {  
            INode *cnode= node->GetChildNode(ch);
            Interval iv;
            Matrix3 tm=cnode->GetObjectTM(t,&iv);
      

            if (cnode->IsGroupMember())
               {
               reevalGroup = TRUE;
               for (int groupCount = 0; groupCount < pblock2->Count(particlemesher_extranodes); groupCount++)
                  {
                  INode *extraNode = pblock2->GetINode(particlemesher_extranodes,t,ch);
                  if (cnode == extraNode)
                     {
                     reevalGroup = FALSE;
                     groupCount = pblock2->Count(particlemesher_extranodes);
                     }
                  }
               if (reevalGroup)
                  ch=node->NumberOfChildren();

               }
            }

         if (reevalGroup)
            {
            tmList.ZeroCount();
   
            pblock2->ZeroCount(particlemesher_extranodes);
            for (int ch=0;ch<node->NumberOfChildren();ch++)
               {  
               INode *cnode= node->GetChildNode(ch);
               Interval iv;
               Matrix3 tm=cnode->GetObjectTM(t,&iv);
      

               if (cnode->IsGroupMember())
                  {
                  pblock2->Append(particlemesher_extranodes,1,&cnode);
                  tmList.Append(1,&tm);
                  }
               }

            }
         }

      if (node) 
         {

         if ( (node->IsGroupHead()) && (pblock2->Count(particlemesher_extranodes)!=0))
            {

            int ct = 0;
            Matrix3 ident(1), inverseTm(1);
            mesh.setNumVerts(0);
            mesh.setNumFaces(0);
            for (int ch=0;ch<pblock2->Count(particlemesher_extranodes);ch++)
               {  
               INode *cnode = pblock2->GetINode(particlemesher_extranodes,t,ch);
               if (cnode)
                  {
                  Object *pobj = cnode->EvalWorldState(t+offset).obj;
               
                  if ( (pobj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
                      (pobj->SuperClassID() == SHAPE_CLASS_ID) )                    
                     {  


                     BOOL needDel;
                     NullView nullView;
                     Mesh *msh = ((GeomObject*)pobj)->GetRenderMesh(t+offset,cnode,nullView,needDel);

                     Mesh tmsh = *msh;

                     ivalid &= pobj->ObjectValidity(t+offset);

                     Matrix3 tm(1);
                     if (ch < tmList.Count())
                        tm = tmList[ch];
                     for (int v = 0; v < msh->numVerts; v++)
                        {
                        tmsh.verts[v] = tmsh.verts[v] * tm;
                        }
                     if (tmsh.numVerts != 0)
                        {
                        if (ct ==0)
                           {
                           mesh = tmsh;
                           }
                        else 
                           mesh = mesh + tmsh;
                  
                        ct++;
                        }

                     if (needDel) delete msh;
                     }

                     
               
                  }
                  
               }
            mesh.InvalidateTopologyCache();

            }
         else
            {
//          Object *tobj =  node->GetObjectRef();
//          macroRecorder->FunctionCall(_T("time"), 1, 0, mr_int, t);
//          macroRecorder->EmitScript();
            ObjectState os = node->EvalWorldState(t+offset);

            IParticleObjectExt* epobj;
            epobj = (IParticleObjectExt*) os.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE);
            
            if (os.obj->IsParticleSystem() && epobj)
               {
      
               if (epobj) 
                  {
                  BOOL useAllPFEvents;
                  pblock2->GetValue(particlemesher_useallpf,0,useAllPFEvents,FOREVER);
                  
                  pfNodes.ZeroCount();
                  
                  INode *basenode=NULL;
                  pblock2->GetValue(particlemesher_pick, 0, basenode, ivalid);                  

                  tmList.ZeroCount();

                  if (useAllPFEvents)
                     {
                     MyEnumProc dep;              
                     os.obj->DoEnumDependents(&dep);
                     
                     for (int i = 0; i < dep.Nodes.Count(); i++)
                        {
                        Interval valid;
                        INode *node = dep.Nodes[i];

                        Object *obj = node->GetObjectRef();

                        
                        if (ParticleGroupInterface(obj) != nullptr)
                           {
                           pfNodes.Append(1,&node);
                           Matrix3 tm = node->GetNodeTM(t+offset);
                           tmList.Append(1,&tm);
                           }
                        }                 
                     }
                  else
                     {
                     int ct = pblock2->Count(particlemesher_pfeventlist);
                     for (int i = 0; i < ct; i++)
                        {
                        INode *node;
                        pblock2->GetValue(particlemesher_pfeventlist,t,node,FOREVER,i);
                        if (node)
                           {

                           Object *obj = node->GetObjectRef();
                           if (ParticleGroupInterface(obj) != nullptr)
                              {
                              pfNodes.Append(1,&node);
                              Matrix3 tm(1);// = basenode->GetNodeTM(t+offset);
                              Matrix3 ntm = node->GetObjectTM(t+offset);
                              tm = ntm;
                              tmList.Append(1,&ntm);
                              
                              }                          
                           }
                        }
                     }
                     
                  mesh.setNumVerts(0);
                  mesh.setNumFaces(0);
                  int ct = 0;
                  for (int ch=0;ch< pfNodes.Count();ch++)
                     {  
                     INode *cnode = pfNodes[ch];
                     if (cnode)
                        {
                        Object *pobj = cnode->EvalWorldState(t+offset).obj;
                     
                        if ( (pobj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
                           (pobj->SuperClassID() == SHAPE_CLASS_ID) )                     
                           {  


                           BOOL needDel;
                           NullView nullView;
                           Mesh *msh = ((GeomObject*)pobj)->GetRenderMesh(t+offset,cnode,nullView,needDel);

                           Mesh tmsh = *msh;

                           ivalid &= pobj->ObjectValidity(t+offset);

                           Matrix3 tm(1);
                           if (ch < tmList.Count())
                              tm = tmList[ch];
                           for (int v = 0; v < msh->numVerts; v++)
                              {
                              tmsh.verts[v] = tmsh.verts[v] * tm;
                              }
                           if (tmsh.numVerts != 0)
                              {
                              if (ct ==0)
                                 {
                                 mesh = tmsh;
                                 }
                              else 
                                 {
                                 Mesh tempMesh = mesh;
                                 CombineMeshes(mesh, tempMesh, tmsh);
                                 }
                        
                              ct++;
                              }

                           if (needDel) delete msh;
                           }

                           
                     
                        }
                        
                     }
                  mesh.InvalidateTopologyCache();
                     
                     
                                       
                  }
               }
            else if ( (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
             (os.obj->SuperClassID() == SHAPE_CLASS_ID) )
               {

               BOOL needDel;
               NullView nullView;
               Mesh *msh = ((GeomObject*)os.obj)->GetRenderMesh(t+offset,node,nullView,needDel);
               ivalid &= os.obj->ObjectValidity(t);

               if (msh)
                  {
                  mesh = *msh;
                  mesh.InvalidateTopologyCache();
         
                  if (needDel) delete msh;
                  }
               }
            }
         lastTime = t;
         }
      else
         {
//build proxy mesh
         if (node == NULL)
            {
            mesh.setNumVerts(5);
            mesh.setNumFaces(8);

            mesh.setNumMaps(2);
            mesh.setNumMapVerts(0, 0);
            mesh.setNumMapVerts(1, 0);
            mesh.setNumMapFaces(0, 0);
            mesh.setNumMapFaces(1, 0);

            mesh.setVert(0, Point3(-radius,-radius, 0.0f));
            mesh.setVert(1, Point3( radius,-radius, 0.0f));
            mesh.setVert(2, Point3( radius, radius, 0.0f));
            mesh.setVert(3, Point3(-radius, radius, 0.0f));

//          mesh.setVert(4, Point3(0.0f, 0.0f, 0.0f));
            mesh.setVert(4, Point3(0.0f, 0.0f, radius));
   
            mesh.faces[0].setEdgeVisFlags(1,0,1);
            mesh.faces[0].setSmGroup(1);
            mesh.faces[0].setVerts(0,1,3);

            mesh.faces[1].setEdgeVisFlags(1,1,0);
            mesh.faces[1].setSmGroup(1);
            mesh.faces[1].setVerts(1,2,3);   

            mesh.faces[2].setEdgeVisFlags(1,1,1);
            mesh.faces[2].setSmGroup(1);
            mesh.faces[2].setVerts(0,4,1);   

            mesh.faces[3].setEdgeVisFlags(1,1,1);
            mesh.faces[3].setSmGroup(1);
            mesh.faces[3].setVerts(1,4,0);   

            mesh.faces[4].setEdgeVisFlags(1,1,1);
            mesh.faces[4].setSmGroup(1);
            mesh.faces[4].setVerts(2,4,3);   

            mesh.faces[5].setEdgeVisFlags(1,1,1);
            mesh.faces[5].setSmGroup(1);
            mesh.faces[5].setVerts(3,4,2);   

            mesh.faces[6].setEdgeVisFlags(1,0,1);
            mesh.faces[6].setSmGroup(1);
            mesh.faces[6].setVerts(3,1,0);

            mesh.faces[7].setEdgeVisFlags(1,1,0);
            mesh.faces[7].setSmGroup(1);
            mesh.faces[7].setVerts(3,2,1);   


            }

         }
      }  
   else
      {
//build proxy mesh
//build proxy mesh
      INode *node=NULL;
      pblock2->GetValue(particlemesher_pick, 0, node, ivalid);
   // if (node == NULL)
         {
            mesh.setNumVerts(5);
            mesh.setNumFaces(8);

            mesh.setNumMaps(2);
            mesh.setNumMapVerts(0, 0);
            mesh.setNumMapVerts(1, 0);
            mesh.setNumMapFaces(0, 0);
            mesh.setNumMapFaces(1, 0);

            mesh.setVert(0, Point3(-radius,-radius, 0.0f));
            mesh.setVert(1, Point3( radius,-radius, 0.0f));
            mesh.setVert(2, Point3( radius, radius, 0.0f));
            mesh.setVert(3, Point3(-radius, radius, 0.0f));

//          mesh.setVert(4, Point3(0.0f, 0.0f, 0.0f));
            mesh.setVert(4, Point3(0.0f, 0.0f, radius));
   
            mesh.faces[0].setEdgeVisFlags(1,0,1);
            mesh.faces[0].setSmGroup(1);
            mesh.faces[0].setVerts(0,1,3);

            mesh.faces[1].setEdgeVisFlags(1,1,0);
            mesh.faces[1].setSmGroup(1);
            mesh.faces[1].setVerts(1,2,3);   

            mesh.faces[2].setEdgeVisFlags(1,1,1);
            mesh.faces[2].setSmGroup(1);
            mesh.faces[2].setVerts(0,4,1);   

            mesh.faces[3].setEdgeVisFlags(1,1,1);
            mesh.faces[3].setSmGroup(1);
            mesh.faces[3].setVerts(1,4,0);   

            mesh.faces[4].setEdgeVisFlags(1,1,1);
            mesh.faces[4].setSmGroup(1);
            mesh.faces[4].setVerts(2,4,3);   

            mesh.faces[5].setEdgeVisFlags(1,1,1);
            mesh.faces[5].setSmGroup(1);
            mesh.faces[5].setVerts(3,4,2);   

            mesh.faces[6].setEdgeVisFlags(1,0,1);
            mesh.faces[6].setSmGroup(1);
            mesh.faces[6].setVerts(3,1,0);

            mesh.faces[7].setEdgeVisFlags(1,1,0);
            mesh.faces[7].setSmGroup(1);
            mesh.faces[7].setVerts(3,2,1);   

         }
      }

   mesh.InvalidateTopologyCache();
}
Ejemplo n.º 22
0
void Lighting::UpdateLights()
{

	Matrix3			Mat;
	int				i;
	ObjectState		Os;
	LightObject		*LightObj;
	LightState		Ls;
	RenderLight		Light;	
	TimeValue		Time = GetCOREInterface()->GetTime();
	Interval		valid;
	Point3			Pos,Target;

	m_Lights.clear();

	for(i=0;i<sceneLights.Count();i++)
	{

		INode * Node = sceneLights[i];
		Os   = Node->EvalWorldState(Time);
			
		if(Os.obj ) 
		{
			LightObj = (LightObject *)Os.obj;
			LightObj->EvalLightState(Time,valid,&Ls);

			Mat				= Node->GetNodeTM(Time);			
			Pos				= Mat.GetTrans();
			Light.m_Angle   = Ls.hotsize;

			if(Light.m_Angle < 2.0f)
			{
				Light.m_Angle = 2.0f;
			}

			Mat = Node->GetNodeTM(Time);
			Light.m_Dir = Mat.GetRow(2);

			Light.m_Type	= (RenderLightType)Ls.type;
			Light.m_Pos		= Pos;
			Light.m_Dir		= Light.m_Dir.Normalize();
			Light.m_Color	= Ls.color * Ls.intens;

			if(Ls.useAtten)
			{
				Light.m_Atten = true;

				if(Ls.attenStart <= 0.0f)
				{
					Light.m_InnerRange	= 1.0f;
				}
				else
				{
					Light.m_InnerRange	= 1.0f / (Ls.attenStart * 2.0f);
				}

				if(Ls.attenEnd <= 0.0f)
				{
					Light.m_OuterRange	= 0.0f;
				}
				else
				{	
					Light.m_OuterRange	= 1.0f / (Ls.attenEnd * 2.0f);
				}	
			}
			else
			{
				Light.m_Atten		= false;
				Light.m_InnerRange	= 0.1f;
				Light.m_OuterRange	= 0.00001f;
			}
			m_Lights.push_back(Light);
		}	
	}
}
Ejemplo n.º 23
0
CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, vector<INode*>& resultInstanceNode, TimeValue tvTime)
{
	// Extract from the node the name, the transformations and the parent

	CInstanceGroup::TInstanceArray aIGArray;
	uint32 i, nNumIG;
	uint32 j,k,m;

	aIGArray.empty ();
	resultInstanceNode.empty ();
	aIGArray.resize (vectNode.size());
	resultInstanceNode.resize (vectNode.size());

	int nNbInstance = 0;
	for (i = 0; i < vectNode.size(); ++i)
	{
		INode *pNode = vectNode[i];

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			++nNbInstance;
		}
	}

	// Check integrity of the hierarchy and set the parents
	std::vector<INode*>::const_iterator it = vectNode.begin();
	nNumIG = 0;
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone( *pNode, tvTime ))
		if (CExportNel::isMesh( *pNode, tvTime ) || CExportNel::isDummy(*pNode, tvTime))
		{
			aIGArray[nNumIG].DontAddToScene = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONT_ADD_TO_SCENE, 0)?true:false;
			aIGArray[nNumIG].InstanceName = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_INSTANCE_NAME, "");
			resultInstanceNode[nNumIG] = pNode;
			if (aIGArray[nNumIG].InstanceName == "") // no instance name was set, takes the node name instead
			{
				aIGArray[nNumIG].InstanceName = pNode->GetName();
			}

			// Visible? always true, but if special flag for camera collision
			sint	appDataCameraCol= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_CAMERA_COLLISION_MESH_GENERATION, 0);
			aIGArray[nNumIG].Visible= appDataCameraCol!=3;


			INode *pParent = pNode->GetParentNode();

			// Set the DontCastShadow flag.
			aIGArray[nNumIG].DontCastShadow= pNode->CastShadows()==0;

			// Set the Special DontCastShadow flag.
			aIGArray[nNumIG].DontCastShadowForInterior= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_LIGHT_DONT_CAST_SHADOW_INTERIOR, BST_UNCHECKED)?true:false;
			aIGArray[nNumIG].DontCastShadowForExterior= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_LIGHT_DONT_CAST_SHADOW_EXTERIOR, BST_UNCHECKED)?true:false;

			// Is the pNode has the root node for parent ?
			if( pParent->IsRootNode() == 0 )
			{
				// Look if the parent is in the selection
				int nNumIG2 = 0;
				for (j = 0; j < vectNode.size(); ++j)
				{
					INode *pNode2 = vectNode[j];

					int nAccelType2 = CExportNel::getScriptAppData (pNode2, NEL3D_APPDATA_ACCEL, 32);
					if ((nAccelType2&3) == 0) // If not an accelerator
					if (!RPO::isZone( *pNode2, tvTime ))
					if (CExportNel::isMesh( *pNode2, tvTime ))
					{
						if (pNode2 == pParent)
							break;
						++nNumIG2;
					}
				}
				if (nNumIG2 == nNbInstance)
				{
					// The parent is not selected ! link to root
					aIGArray[nNumIG].nParent = -1;
				}
				else
				{
					aIGArray[nNumIG].nParent = nNumIG2;
				}
			}
			else
			{
				aIGArray[nNumIG].nParent = -1;
			}
			++nNumIG;
		}
	}
	aIGArray.resize( nNumIG );
	resultInstanceNode.resize( nNumIG );

	// Build the array of node
	vGlobalPos = CVector(0,0,0);
	nNumIG = 0;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			CVector vScaleTemp;
			CQuat qRotTemp;
			CVector vPosTemp;

			// Get Nel Name for the object.
			aIGArray[nNumIG].Name= CExportNel::getNelObjectName(*pNode);

			//Get the local transformation matrix
			Matrix3 nodeTM = pNode->GetNodeTM(0);
			INode *pParent = pNode->GetParentNode();
			Matrix3 parentTM = pParent->GetNodeTM(0);
			Matrix3 localTM	= nodeTM*Inverse(parentTM);

			// Extract transformations
			CExportNel::decompMatrix (vScaleTemp, qRotTemp, vPosTemp, localTM);
			aIGArray[nNumIG].Rot   = qRotTemp;
			aIGArray[nNumIG].Pos   = vPosTemp;
			aIGArray[nNumIG].Scale = vScaleTemp;
			vGlobalPos += vPosTemp;
			++nNumIG;
		}
	}
	// todo Make this work (precision):
	/*
	vGlobalPos = vGlobalPos / nNumIG;
	for (i = 0; i < nNumIG; ++i)
		aIGArray[i].Pos -= vGlobalPos;
	*/

	vGlobalPos = CVector(0,0,0); // Temporary !!!

	// Accelerator Portal/Cluster part
	//=================

	// Creation of all the clusters
	vector<CCluster> vClusters;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, NEL3D_APPDATA_ACCEL_DEFAULT);
		bool bFatherVisible = nAccelType&NEL3D_APPDATA_ACCEL_FATHER_VISIBLE?true:false;
		bool bVisibleFromFather = nAccelType&NEL3D_APPDATA_ACCEL_VISIBLE_FROM_FATHER?true:false;
		bool bAudibleLikeVisible = (nAccelType&NEL3D_APPDATA_ACCEL_AUDIBLE_NOT_LIKE_VISIBLE)?false:true;
		bool bFatherAudible = bAudibleLikeVisible ? bFatherVisible : nAccelType&NEL3D_APPDATA_ACCEL_FATHER_AUDIBLE?true:false;
		bool bAudibleFromFather = bAudibleLikeVisible ? bVisibleFromFather : nAccelType&NEL3D_APPDATA_ACCEL_AUDIBLE_FROM_FATHER?true:false;

		if ((nAccelType&NEL3D_APPDATA_ACCEL_TYPE) == NEL3D_APPDATA_ACCEL_CLUSTER) // If cluster
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh(*pNode, tvTime))
		{
			CCluster clusterTemp;
			std::string temp;

			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_SOUND_GROUP, "no sound");
			clusterTemp.setSoundGroup(temp != "no sound" ? temp : "");
			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_ENV_FX, "no fx");
			clusterTemp.setEnvironmentFx(temp != "no fx" ? temp : "");

			CMesh::CMeshBuild *pMB;
			CMeshBase::CMeshBaseBuild *pMBB;
			pMB = createMeshBuild (*pNode, tvTime, pMBB);

			convertToWorldCoordinate( pMB, pMBB );

			for (j = 0; j < pMB->Faces.size(); ++j)
			{
				if (!clusterTemp.makeVolume (pMB->Vertices[pMB->Faces[j].Corner[0].Vertex],
											 pMB->Vertices[pMB->Faces[j].Corner[1].Vertex],
											 pMB->Vertices[pMB->Faces[j].Corner[2].Vertex]) )
				{
					// ERROR : The volume is not convex !!!
					char tam[256];
					sprintf(tam,"ERROR: The cluster %s is not convex.",vectNode[i]->GetName());
					//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
					nlwarning(tam);
				}
			}

			clusterTemp.FatherVisible = bFatherVisible;
			clusterTemp.VisibleFromFather = bVisibleFromFather;
			clusterTemp.FatherAudible = bFatherAudible;
			clusterTemp.AudibleFromFather = bAudibleFromFather;
			clusterTemp.Name = pNode->GetName();

			vClusters.push_back (clusterTemp);
			delete pMB;
			delete pMBB;
		}
	}

	// Creation of all the portals
	vector<CPortal> vPortals;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 1) // If Portal
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh(*pNode, tvTime))
		{
			CPortal portalTemp;
			std::string temp;

			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_OCC_MODEL, "no occlusion");
			portalTemp.setOcclusionModel(temp != "no occlusion" ? temp : "");
			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_OPEN_OCC_MODEL, "no occlusion");
			portalTemp.setOpenOcclusionModel(temp != "no occlusion" ? temp : "");

			CMesh::CMeshBuild *pMB;
			CMeshBase::CMeshBaseBuild *pMBB;
			pMB = createMeshBuild (*pNode, tvTime, pMBB);

			convertToWorldCoordinate( pMB, pMBB );

			vector<sint32> poly;
			vector<bool> facechecked;
			facechecked.resize (pMB->Faces.size());
			for (j = 0; j < pMB->Faces.size(); ++j)
				facechecked[j] = false;

			poly.push_back(pMB->Faces[0].Corner[0].Vertex);
			poly.push_back(pMB->Faces[0].Corner[1].Vertex);
			poly.push_back(pMB->Faces[0].Corner[2].Vertex);
			facechecked[0] = true;
			for (j = 0; j < pMB->Faces.size(); ++j)
			if (!facechecked[j])
			{
				bool found = false;

				for(k = 0; k < 3; ++k)
				{
					for(m = 0; m < poly.size(); ++m)
					{
						if ((pMB->Faces[j].Corner[k].Vertex == poly[m]) &&
							(pMB->Faces[j].Corner[(k+1)%3].Vertex == poly[(m+1)%poly.size()]))
						{
							found = true;
							break;
						}
						if ((pMB->Faces[j].Corner[(k+1)%3].Vertex == poly[m]) &&
							(pMB->Faces[j].Corner[k].Vertex == poly[(m+1)%poly.size()]))
						{
							found = true;
							break;
						}
					}
					if (found)
						break;
				}
				if (found)
				{
					// insert an empty space in poly between m and m+1
					poly.resize (poly.size()+1);
					for (uint32 a = poly.size()-2; a > m; --a)
						poly[a+1] = poly[a];
					poly[m+1] = pMB->Faces[j].Corner[(k+2)%3].Vertex;
					facechecked[j] = true;
					j = 0;
				}
			}
			vector<CVector> polyv;
			polyv.resize (poly.size());
			for (j = 0; j < poly.size(); ++j)
				polyv[j] = pMB->Vertices[poly[j]];
			
			if (!portalTemp.setPoly (polyv))
			{
				// ERROR : Poly not convex, or set of vertices not plane
				char tam[256];
				sprintf(tam,"ERROR: The portal %s is not convex.",vectNode[i]->GetName());
				//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
				nlwarning(tam);
			}

			if (nAccelType&16) // is dynamic portal ?
			{
				string InstanceName = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_INSTANCE_NAME, "");
				if (!InstanceName.empty())
					portalTemp.setName (InstanceName);
				else
					portalTemp.setName (string(pNode->GetName()));
			}

			// Check if portal has 2 cluster
			int nNbCluster = 0;
			for (j = 0; j < vClusters.size(); ++j)
			{
				bool bPortalInCluster = true;
				for (k = 0; k < polyv.size(); ++k)
					if (!vClusters[j].isIn (polyv[k]) )
					{
						bPortalInCluster = false;
						break;
					}
				if (bPortalInCluster)
					++nNbCluster;
			}
			if (nNbCluster != 2)
			{
				// ERROR
				char tam[256];
				sprintf(tam,"ERROR: The portal %s has not 2 clusters but %d",vectNode[i]->GetName(), nNbCluster);
				//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
				nlwarning(tam);
			}


			vPortals.push_back (portalTemp);
			delete pMB;
			delete pMBB;
		}
	}

	// Link instance to clusters (an instance has a list of clusters)
	nNumIG = 0;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			if (nAccelType&32) // Is the flag clusterize set ?
			{
				// Test against all clusters

				// The list of vertices used to test against cluster
				std::vector<NLMISC::CVector> *testVertices;
				std::vector<NLMISC::CVector>       FXVertices;  // Used only if the obj is a fx. It contains the corners of the bbox.
				bool  buildMeshBBox = true;

				/** If it is a mesh, we build its bbox and transform in world
				  * If it is a FX, we read its bbox from its shape
				  * If we can't read it, we use the bbox of the fx helper in max
				  */
				Object *obj = pNode->EvalWorldState(tvTime).obj;
				// Check if there is an object
				if (obj)
				{
					Class_ID  clid = obj->ClassID();
					// is the object a particle system ?					
					if (clid.PartA() == NEL_PARTICLE_SYSTEM_CLASS_ID)
					{
						// build the shape from the file name
						std::string objName = CExportNel::getNelObjectName(*pNode); 						
						if (!objName.empty())
						{											
							NL3D::CShapeStream ss;
							NLMISC::CIFile iF;
							if (iF.open(objName.c_str()))
							{
								try
								{								
									iF.serial(ss);
									NL3D::CParticleSystemShape *pss = dynamic_cast<NL3D::CParticleSystemShape *>(ss.getShapePointer());
									if (!pss)
									{
										nlwarning("ERROR: Node %s shape is not a FX", CExportNel::getName(*pNode).c_str());
									}
									else
									{									
										NLMISC::CAABBox bbox;
										pss->getAABBox(bbox);
										// transform in world
										Matrix3 xForm = pNode->GetNodeTM(tvTime);
										NLMISC::CMatrix nelXForm;
										CExportNel::convertMatrix(nelXForm, xForm);									
										bbox = NLMISC::CAABBox::transformAABBox(nelXForm, bbox);
										// store vertices of the bbox in the list
										FXVertices.reserve(8);
										for(uint k = 0; k < 8; ++k)
										{
											FXVertices.push_back(CVector(((k & 1) ? 1 : -1) * bbox.getHalfSize().x + bbox.getCenter().x,
																		 ((k & 2) ? 1 : -1) * bbox.getHalfSize().y + bbox.getCenter().y,
																		 ((k & 4) ? 1 : -1) * bbox.getHalfSize().z + bbox.getCenter().z));
										}
										//
										testVertices = &FXVertices;
										buildMeshBBox = false;
									}
									delete ss.getShapePointer();
								}
								catch (NLMISC::Exception &e)
								{
									nlwarning(e.what());									
								}
							}							
							if (buildMeshBBox)
							{
								nlwarning("ERROR: Can't get bbox of a particle system from its shape, using helper bbox instead");
							}
						}
					}
				}

				CMesh::CMeshBuild *pMB = NULL;
				CMeshBase::CMeshBaseBuild *pMBB = NULL;

				if (buildMeshBBox)
				{				
					pMB = createMeshBuild (*pNode, tvTime, pMBB);
					convertToWorldCoordinate( pMB, pMBB );
					testVertices = &pMB->Vertices;
				}

				for(k = 0; k < vClusters.size(); ++k)
				{
					bool bMeshInCluster = false;

					for(j = 0; j < testVertices->size(); ++j)
					{
						if (vClusters[k].isIn ((*testVertices)[j]))
						{
							bMeshInCluster = true;
							break;
						}
					}

					if (bMeshInCluster)
					{
						aIGArray[nNumIG].Clusters.push_back (k);
					}
				}
				
				// debug purpose : to remove
				if (vClusters.size() > 0)
				if (aIGArray[nNumIG].Clusters.size() == 0)
				{
					char tam[256];
					sprintf(tam,"ERROR: Object %s is not attached to any cluster\nbut his flag clusterize is set", pNode->GetName());
					//MessageBox(NULL, tam, "Warning", MB_OK);
					nlwarning(tam);
				}
				// debug purpose : to remove

				delete pMB;
				delete pMBB;
			}
			
			++nNumIG;
		}
		// debug purpose : to remove
		/*
		if ((nAccelType&3) == 0) // If not an accelerator
		if (!(nAccelType&32))
		{
			char tam[256];
			sprintf(tam,"Object %s is not clusterized", pNode->GetName());
			MessageBox(NULL, tam, "Info", MB_OK);
		}
		*/
		// debug purpose : to remove

	}


	// PointLight part
	//=================
	bool	sunLightEnabled= false;
	sint	nNumPointLight = 0;
	vector<CPointLightNamed>	pointLights;
	pointLights.resize(vectNode.size());
	// For all nodes
	for (i = 0; i < (sint)vectNode.size(); ++i)
	{
		INode *pNode = vectNode[i];

		SLightBuild		sLightBuild;

		// If it is a Max Light.
		if ( sLightBuild.canConvertFromMaxLight(pNode, tvTime) )
		{
			// And if this light is checked to realtime export
			int		nRTExport= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_EXPORT_REALTIME_LIGHT, BST_CHECKED);
			if(nRTExport == BST_CHECKED)
			{
				// get Max Light info.
				sLightBuild.convertFromMaxLight(pNode, tvTime);

				// Skip if LightDir
				if(sLightBuild.Type != SLightBuild::LightDir)
				{
					// Fill PointLight Info.
					NL3D::CPointLightNamed	&plNamed= pointLights[nNumPointLight];

					// Position
					plNamed.setPosition(sLightBuild.Position);
					// Attenuation
					plNamed.setupAttenuation(sLightBuild.rRadiusMin, sLightBuild.rRadiusMax);
					// Colors
					// Ensure A=255 for localAmbient to work.
					NLMISC::CRGBA	ambient= sLightBuild.Ambient;
					ambient.A= 255;
					plNamed.setDefaultAmbient(ambient);
					plNamed.setAmbient(ambient);
					plNamed.setDefaultDiffuse(sLightBuild.Diffuse);
					plNamed.setDiffuse(sLightBuild.Diffuse);
					plNamed.setDefaultSpecular(sLightBuild.Specular);
					plNamed.setSpecular(sLightBuild.Specular);

					// GroupName.
					plNamed.AnimatedLight = sLightBuild.AnimatedLight;
					plNamed.LightGroup = sLightBuild.LightGroup;

					// Which light type??
					if(sLightBuild.bAmbientOnly || sLightBuild.Type== SLightBuild::LightAmbient)
					{
						plNamed.setType(CPointLight::AmbientLight);
						// Special ambient info
						int		nRTAmbAdd= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_REALTIME_AMBIENT_ADD_SUN, BST_UNCHECKED);
						plNamed.setAddAmbientWithSun(nRTAmbAdd==BST_CHECKED);
					}
					else if(sLightBuild.Type== SLightBuild::LightPoint)
					{
						plNamed.setType(CPointLight::PointLight);
					}
					else if(sLightBuild.Type== SLightBuild::LightSpot)
					{
						plNamed.setType(CPointLight::SpotLight);
						// Export Spot infos.
						plNamed.setupSpotDirection(sLightBuild.Direction);
						plNamed.setupSpotAngle(sLightBuild.rHotspot, sLightBuild.rFallof);
					}
					else
					{
						// What???
						nlstop;
					}


					// inc Size
					++nNumPointLight;
				}
			}

			// if this light is a directionnal and checked to export as Sun Light
			int		nExportSun= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_EXPORT_AS_SUN_LIGHT, BST_UNCHECKED);
			if(nExportSun== BST_CHECKED)
			{
				// get Max Light info.
				sLightBuild.convertFromMaxLight(pNode, tvTime);

				// Skip if not dirLight.
				if(sLightBuild.Type == SLightBuild::LightDir)
					sunLightEnabled= true;
			}
		}
	}
	// Good size
	pointLights.resize(nNumPointLight);


	// Build the ig
	//=================

	CInstanceGroup* pIG = new CInstanceGroup;

	// Link portals and clusters and create meta cluster if one
	pIG->build (vGlobalPos,  aIGArray, vClusters, vPortals, pointLights);

	// IG touched by sun ??
	pIG->enableRealTimeSunContribution(sunLightEnabled);

	return pIG;
}
	//---------------------------------------------------------------
	void CameraExporter::exportCamera( ExportNode* exportNode )
	{
		if ( !exportNode->getIsInVisualScene() )
			return;
		
		String cameraId = getCameraId(*exportNode);

		INode* iNode = exportNode->getINode();

		CameraObject* camera = (CameraObject*)iNode->GetObjectRef();

		INode* targetNode =  ( camera->ClassID().PartA() == LOOKAT_CAM_CLASS_ID) ? iNode->GetTarget() : 0;

		if ( camera )
		{
			if (  mDocumentExporter->isExportedObject(ObjectIdentifier(camera)) )
				return;

			mDocumentExporter->insertExportedObject(ObjectIdentifier(camera), exportNode);


			// Retrieve the camera parameters block
			IParamBlock* parameters = (IParamBlock*) camera->GetReference(MaxCamera::PBLOCK_REF);

			COLLADASW::BaseOptic * optics = 0; 
			if ( camera->IsOrtho() )
			{
				optics = new COLLADASW::OrthographicOptic(COLLADASW::LibraryCameras::mSW);

				// Calculate the target distance for FOV calculations
				float targetDistance;
				if ( targetNode )
				{
					Point3 targetTrans = targetNode->GetNodeTM(mDocumentExporter->getOptions().getAnimationStart()).GetTrans();
					Point3 cameraTrans = iNode->GetNodeTM(mDocumentExporter->getOptions().getAnimationStart()).GetTrans();
					targetDistance = (targetTrans - cameraTrans).Length();
				}
				else
				{
					targetDistance = camera->GetTDist(mDocumentExporter->getOptions().getAnimationStart());
				}
				ConversionInverseOrthoFOVFunctor conversionInverseOrthoFOVFunctor(targetDistance);

				if ( AnimationExporter::isAnimated(parameters, MaxCamera::FOV) )
				{
					optics->setXMag(conversionInverseOrthoFOVFunctor(parameters->GetFloat(MaxCamera::FOV)), XMAG_SID);
					mAnimationExporter->addAnimatedParameter(parameters, MaxCamera::FOV, cameraId, XMAG_SID, 0, true, &conversionInverseOrthoFOVFunctor);
				}
				else
				{
					optics->setXMag(conversionInverseOrthoFOVFunctor(parameters->GetFloat(MaxCamera::FOV)));	
				}
			}
			else
			{
				optics = new COLLADASW::PerspectiveOptic(COLLADASW::LibraryCameras::mSW);
				if ( AnimationExporter::isAnimated(parameters, MaxCamera::FOV) )
				{
					optics->setXFov(COLLADASW::MathUtils::radToDegF(parameters->GetFloat(MaxCamera::FOV)), XFOV_SID);
					mAnimationExporter->addAnimatedParameter(parameters, MaxCamera::FOV, cameraId, XFOV_SID, 0, true, &ConversionFunctors::radToDeg);
				}
				else
				{
					optics->setXFov(COLLADASW::MathUtils::radToDegF(parameters->GetFloat(MaxCamera::FOV)));	
				}
			}

			bool hasAnimatedZNear = mAnimationExporter->addAnimatedParameter(parameters, MaxCamera::NEAR_CLIP, cameraId, optics->getZNearDefaultSid(), 0);
			optics->setZNear(parameters->GetFloat(MaxCamera::NEAR_CLIP), hasAnimatedZNear);

			bool hasAnimatedZFar = mAnimationExporter->addAnimatedParameter(parameters, MaxCamera::FAR_CLIP, cameraId, optics->getZFarDefaultSid(), 0);
			optics->setZFar(parameters->GetFloat(MaxCamera::FAR_CLIP), hasAnimatedZFar);


#ifdef UNICODE
			String exportNodeName = COLLADABU::StringUtils::wideString2utf8String(exportNode->getINode()->GetName());
			COLLADASW::Camera colladaCamera(COLLADASW::LibraryCameras::mSW, optics, cameraId, COLLADASW::Utils::checkNCName(exportNodeName));
#else
			COLLADASW::Camera colladaCamera(COLLADASW::LibraryCameras::mSW, optics, cameraId, COLLADASW::Utils::checkNCName(exportNode->getINode()->GetName()));
#endif
			setExtraTechnique(&colladaCamera);


			// Retrieve the camera target
			if ( targetNode )
			{
				ExportNode* targetExportNode = mExportSceneGraph->getExportNode(targetNode);
				addExtraParameter(EXTRA_PARAMETER_TARGET, "#" + targetExportNode->getId());
			}

			if (camera->GetMultiPassEffectEnabled(0, FOREVER))
			{
				IMultiPassCameraEffect *multiPassCameraEffect = camera->GetIMultiPassCameraEffect();
				if (multiPassCameraEffect)
				{
					Class_ID id = multiPassCameraEffect->ClassID();

					// the camera could have both effects, but not in Max
					if (id == FMULTI_PASS_MOTION_BLUR_CLASS_ID)
					{
						IParamBlock2 *parameters = multiPassCameraEffect->GetParamBlock(0);
						if (parameters )
						{
							addParamBlockAnimatedExtraParameters(MOTION_BLUR_ELEMENT, MOTION_BLUR_PARAMETERS, MOTION_BLUR_PARAMETER_COUNT, parameters, cameraId);
						}
					}
					else if (id == FMULTI_PASS_DOF_CLASS_ID)
					{
						IParamBlock2 *parameters = multiPassCameraEffect->GetParamBlock(0);
						if (parameters )
						{
							addParamBlockAnimatedExtraParameters(DEPTH_OF_FIELD_ELEMENT, DEPTH_OF_FIELD_PARAMETERS, DEPTH_OF_FIELD_PARAMETER_COUNT, parameters, cameraId);
							addExtraParameter(TARGETDISTANCE_PARAMETER, camera->GetTDist(0));
						}
					}
				}
			}
			addCamera(colladaCamera);
		
			delete optics;
		}

	}
Ejemplo n.º 25
0
void SkeletonExporter::export_camera(INode *node)
{
  Control *c;
  int size_key;
  float camera_znear, camera_zfar;
  CameraState cs;
//  Interval valid = FOREVER;
  ObjectState os;
  CameraObject *cam;
  GenCamera *gencam;
  float roll0;
  Matrix3 mat;
  Point3 row;

  os = node->EvalWorldState(0);
  cam = (CameraObject *)os.obj;
  gencam = (GenCamera *)os.obj;
  if (gencam->Type() != TARGETED_CAMERA)
  {
	 fprintf(fTXT, "Only targeted camera are supported!\n\n");
	 return;
  }

  fprintf(fTXT, "Targeted camera found\n");
  write_chunk_header(fA3D, TARGETED_CAMERA_ID, node->GetName(), 40);
  if (makeRAY) write_chunk_header(fRAY, TARGETED_CAMERA_ID, node->GetName(), 40);

  INode* target = node->GetTarget();
  fprintf(fTXT, "Name : %s\n", node->GetName());
  cam->EvalCameraState(0, FOREVER, &cs);

  // ------------------  salviamo znear e zfar  ----------------------
  camera_znear=2;
  camera_zfar=2000;
  if (cs.manualClip)
  {
	camera_znear=cs.hither;
	camera_zfar=cs.yon;
  }
  fprintf(fTXT, "Znear = %f \n", camera_znear);
  fwrite(&camera_znear, sizeof(float), 1, fA3D);
  if (makeRAY) fwrite(&camera_znear, sizeof(float), 1, fRAY);
  fprintf(fTXT, "Zfar = %f \n", camera_zfar);
  fwrite(&camera_zfar, sizeof(float), 1, fA3D);
  if (makeRAY) fwrite(&camera_zfar, sizeof(float), 1, fRAY);

  // -----------------  salviamo l'angolo di FOV  --------------------
  fprintf(fTXT, "FOV (rad) = %f \n", cs.fov);
  fwrite(&cs.fov, sizeof(float), 1, fA3D);
  if (makeRAY) fwrite(&cs.fov, sizeof(float), 1, fRAY);

  // ------------------  salviamo l'angolo di roll  ------------------
  c=node->GetTMController()->GetRollController();
  c->GetValue(0, &roll0, FOREVER);	
  fprintf(fTXT, "Roll (rad) = %f \n", roll0);
  fwrite(&roll0, sizeof(float), 1, fA3D);
  if (makeRAY) fwrite(&roll0, sizeof(float), 1, fRAY);

  // salviamo la posizione nel mondo
  mat = node->GetNodeTM(0);
  row = mat.GetRow(3);
  fprintf(fTXT, "Camera world position : x=%f, y=%f, z=%f\n", row.x, row.y, row.z);
  write_point3(&row, fA3D);
  if (makeRAY) write_point3(&row, fRAY);

  // ---------  salviamo la posizione del target nel mondo  ----------
  if (target)
  {
    mat = target->GetNodeTM(0);
    row = mat.GetRow(3);
    fprintf(fTXT, "Target world position : x=%f, y=%f, z=%f\n", row.x, row.y, row.z);
    write_point3(&row, fA3D);
    if (makeRAY) write_point3(&row, fRAY);
  }

  
  // esportiamo l'animazione della posizione della camera
  // se ci sono un numero di key > 0
  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, "Camera position track present.");
     write_chunk_header(fA3D, POSITION_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_point3_track(c, 1, fA3D);
     if (makeRAY) write_chunk_header(fRAY, POSITION_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     if (makeRAY) export_point3_track(c, 1, fRAY);
  }

  // -----  esportiamo l'animazione della posizione del target  ------
  if (target)
  {
    c=target->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, "Target position track present.");
	  write_chunk_header(fA3D, CAMERA_TARGET_TRACK_ID,
		                 node->GetName(), 1+2+4+c->NumKeys()*size_key);
	  export_point3_track(c, 1, fA3D);

	  if (makeRAY) write_chunk_header(fRAY, CAMERA_TARGET_TRACK_ID,
		                 node->GetName(), 1+2+4+c->NumKeys()*size_key);
	  if (makeRAY) export_point3_track(c, 1, fRAY);
	}
  }

  // ---------------  esportiamo le tracce di FOV  -------------------
  c=gencam->GetFOVControl();
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Camera FOV track present.");
     write_chunk_header(fA3D, CAMERA_FOV_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D);  // radianti
     if (makeRAY) write_chunk_header(fRAY, CAMERA_FOV_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     if (makeRAY) export_float_track(c, 1, fRAY);  // radianti
  }


  // ---------------  esportiamo le tracce di roll  ------------------
  c=node->GetTMController()->GetRollController();
  if ((c) && (c->NumKeys()>0))
  {
	 if (IsTCBControl(c)) size_key=28;
	 else
	 if (IsBezierControl(c)) size_key=16;
	 else size_key=8;
	 fprintf(fTXT, "Camera roll track present.");
     write_chunk_header(fA3D, CAMERA_ROLL_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     export_float_track(c, 1, fA3D); // radianti

     if (makeRAY) write_chunk_header(fRAY, CAMERA_ROLL_TRACK_ID,
	                    node->GetName(), 1+2+4+c->NumKeys()*size_key);
     if (makeRAY) export_float_track(c, 1, fRAY); // radianti
  }
  fprintf(fTXT, "\n\n--------------------------------------------------\n");
}
Ejemplo n.º 26
0
int
CMaxAnimationImport::DoImport(
  const TCHAR* name,
  ImpInterface* ii,
  Interface* i,
  BOOL suppressPrompts)
{
  AFX_MANAGE_STATE(AfxGetStaticModuleState());

  HWND window = i->GetMAXHWnd();

  CFileDialog fileDialog(TRUE, "xsf", 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                         0, CWnd::FromHandle(window));
  if (fileDialog.DoModal() != IDOK) {
    return IMPEXP_CANCEL;
  }

  CString skeleton = fileDialog.GetPathName();
  
	cal3d::RefPtr<CalCoreSkeleton> skel = CalLoader::loadCoreSkeleton(std::string(skeleton));
  if (!skel) {
    MessageBox(
      window, "Loading skeleton file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

	cal3d::RefPtr<CalCoreAnimation> anim = CalLoader::loadCoreAnimation(name);
  if (!anim) {
    MessageBox(
      window, "Loading animation file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

  typedef std::list<CalCoreTrack*> CoreTrackList;
  CoreTrackList& trackList = anim->getListCoreTrack();
  for (CoreTrackList::iterator itr = trackList.begin(); itr != trackList.end(); ++itr) {
    CalCoreTrack* track = *itr;

    int boneId = track->getCoreBoneId();
    CalCoreBone* bone = skel->getCoreBone(boneId);
    if (!bone) continue;

    INode* node = i->GetINodeByName(bone->getName().c_str());
    if (!node) continue;

    unsigned kfCount = track->getCoreKeyframeCount();

    SuspendAnimate();
    AnimateOn();
    for (unsigned i = 0; i < kfCount; ++i) {
      CalCoreKeyframe* kf = track->getCoreKeyframe(i);
      CalQuaternion kf_q = kf->getRotation();
      CalVector     kf_v = kf->getTranslation();
      TimeValue     time = SecToTicks(kf->getTime());

      Matrix3 tm;
      tm.IdentityMatrix();
      Quat(kf_q.x, kf_q.y, kf_q.z, kf_q.w).MakeMatrix(tm);
      tm.SetTrans(Point3(kf_v.x, kf_v.y, kf_v.z));

      INode* parent = node->GetParentNode();
      if (parent) {
        tm *= parent->GetNodeTM(time);
      }

      node->SetNodeTM(time, tm);
    }
    ResumeAnimate();

/*
    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();

    int mapsize = sizeof(keys);

    int size = keys.size();

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      Point3 p;
      CalCoreKeyframe* kf = mi->second;
      p.x = kf->getTranslation().x;
      p.y = kf->getTranslation().y;
      p.z = kf->getTranslation().z;
      pos->SetValue(SecToTicks(mi->first), &p);
    }
*/

/*
    IKeyControl* kc = GetKeyControlInterface(pos);
    if (!kc) continue;

    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();
    kc->SetNumKeys(keys.size());

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      ITCBPoint3Key key;
      key.time = SecToTicks(mi->first);
      key.tens = 0;
      key.cont = 0;
      key.bias = 0;
      key.easeIn = 25.0;
      key.easeOut = 25.0;
      key.val.x = mi->second->getTranslation().x;
      key.val.y = mi->second->getTranslation().y;
      key.val.z = mi->second->getTranslation().z;

      kc->SetKey(idx++, &key);
    }

    kc->SortKeys();
*/
  }
 
  return IMPEXP_SUCCESS;
}
Ejemplo n.º 27
0
void RBExport::ProcessCamera( INode* node )
{
    if (m_pConfig->m_bExportCameras == false)
    {
        return;
    }

    ObjectState os = node->EvalWorldState( m_CurTime );
    Object* pCurObject = os.obj;
    if (!pCurObject) return;

    CameraObject* camObj = (CameraObject*)pCurObject;
    Interval validIvl;
    CameraState cs;

    RefResult res = camObj->EvalCameraState( m_CurTime, validIvl, &cs );
    if ( res != REF_SUCCEED)
    {
        Err( "Error processing camera <%s>", node->GetName() );
        return;
    }

    Info( "Processing camera <%s>", node->GetName() );

    Matrix3 camTM = c_CamFlipTM*node->GetNodeTM( m_CurTime );

    Matrix3 parentTM;
    INode* pParent = node->GetParentNode();
    if (pParent && !pParent->IsRootNode())
    {
        parentTM = pParent->GetNodeTM( m_CurTime );
    }
    else
    {
        parentTM = c_IdentityTM;
    }
    parentTM = c_FlipTM*parentTM;
    camTM = camTM*Inverse( parentTM );

    JCamera* pCamera = new JCamera();
    pCamera->SetWorldTM( Convert( camTM ) );

    float aspect = ((float)m_pInterface->GetRendWidth())/((float)m_pInterface->GetRendHeight());
    float zn     = cs.nearRange;
    float zf     = cs.farRange;
    float fov    = cs.fov;
    if (zn < c_FltEpsilon) zn = 1.0f;

    pCamera->SetOrtho  ( cs.isOrtho == TRUE );
    pCamera->SetZNear  ( zn );
    pCamera->SetZFar   ( zf );
    pCamera->SetAspect ( aspect ); 

    if (cs.isOrtho)
    {
        float vVol = 2.0f * cs.tdist * tan( cs.fov * 0.5f );
        pCamera->SetFOVx( vVol );
    }
    else
    {
        pCamera->SetFOVx( RadToDeg( fov ) );
    }

    pCamera->SetName( node->GetName() );

    //  insert camera as the first node in the model
    m_pModel->AddChild( pCamera, 0 );
} // RBExport::ProcessCamera
Ejemplo n.º 28
0
bool MeshExpUtility::SaveSkinKeys(const char* n){
	CFS_Memory F;

	int FramesPerSecond = GetFrameRate();
	int TicksPerFrame	= GetTicksPerFrame();
	int FirstTick		= ip->GetAnimRange().Start();
	int LastTick		= ip->GetAnimRange().End();

	Point3 v;
	Matrix3 tm;

	// Write signature and version
	char S[MAX_PATH];
	sprintf(S, "KEYEXP 3.0");
	F.Wstring(S);

	INode *node;
	ObjectEntry *Current;

	//-----------------------------------------------------------------------
	// Count bones and report

	int NumBones = 0;
	Current = theObjects->head;
	while(Current)
	{
		/*
		if(Current->entry->type != OBTYPE_BONE)
		{
			Current = Current->next;
			continue;
		}
		*/

		NumBones++;

		Current = Current->next;
	}

	sprintf(S, "Number of Bones = %d", NumBones);
	F.Wstring(S);
	ELog.Msg(mtInformation,S);

	//-----------------------------------------------------------------------
	// Write out necessary data for motion keys

	sprintf(S, "Key Data");
	F.Wstring(S);

	TimeValue t;
	Quat qq;
	Point3 tp, sp;
	INode* parent;
	Matrix3 tmp;

	sprintf(S, "%d %d %d", FirstTick / TicksPerFrame, LastTick / TicksPerFrame, FramesPerSecond);
	F.Wstring(S);

	Current = theObjects->head;
	while(Current){
		/*
		if(Current->entry->type != OBTYPE_BONE)
		{
			Current = Current->next;
			continue;
		}
		*/

		Matrix3 tm;

		node = Current->entry->node;

		sprintf(S, "Node: %s", node->GetName());
		F.Wstring(S);
		ELog.Msg(mtInformation,S);

		// Print notetrack info
		{
			int NumNT, n, i, j, NumNotes;
			NoteTrack* pNT;
			DefNoteTrack* pDNT;
			NoteKey* pNK;

			NumNT = node->NumNoteTracks();

			// count all of the notes on all of the notetracks
			NumNotes = 0;
			for(n=0;n<NumNT;n++){
				pNT = node->GetNoteTrack(n);
				if(pNT->ClassID() == Class_ID(NOTETRACK_CLASS_ID, 0)){
					pDNT = (DefNoteTrack*)pNT;
					j = pDNT->NumKeys();
					for(i=0;i<j;i++){
						pNK = pDNT->keys[i];
						if( (pNK->time >= FirstTick) && (pNK->time <= LastTick) )
							NumNotes++;
					}
				}
			}

			sprintf(S, "Number of Notes = %d", NumNotes);
			F.Wstring(S);

			for(n=0;n<NumNT;n++){
				pNT = node->GetNoteTrack(n);
				if(pNT->ClassID() == Class_ID(NOTETRACK_CLASS_ID, 0)){
					pDNT = (DefNoteTrack*)pNT;
					j = pDNT->NumKeys();
					for(i=0;i<j;i++){
						pNK = pDNT->keys[i];
						if( (pNK->time >= FirstTick) && (pNK->time <= LastTick) ){
							sprintf(S, "%d: %s", (pNK->time - FirstTick) / TicksPerFrame, pNK->note);
							F.Wstring(S);
						}
					}
				}
			}
		}

		for(t=FirstTick;t<=LastTick;t+=TicksPerFrame){
			tm = node->GetNodeTM(t);
			DecomposeMatrix(tm, tp, qq, sp);
			qq.MakeMatrix	(tm);
			tm.SetTrans		(tp);

			parent = node->GetParentNode();
			if(parent){
				tmp = parent->GetNodeTM(t);
				DecomposeMatrix(tmp, tp, qq, sp);
				qq.MakeMatrix(tmp);
				tmp.SetTrans(tp);
				tmp = Inverse(tmp);
				tm *= tmp;
			}

			DecomposeMatrix(tm, tp, qq, sp);
			sprintf(S,"%f %f %f %f",qq.x, qq.y, qq.z, qq.w);
			F.Wstring(S);
			sprintf(S,"%f %f %f",tp.x,tp.y,tp.z);
			F.Wstring(S);

			/*
			// Euler angles
			Point3			E;
			QuatToEuler		(Quat(tm), E);
			fprintf			(f,"%f %f %f",E.x,E.y,E.z);

			// Translate
			DecomposeMatrix	(tm, tp, qq, sp);
			fprintf			(f,"%f %f %f",tp.x,tp.y,tp.z);
			*/

//			Matrix3fprint(f, tm);
		}
		Current = Current->next;
	}

	sprintf(S, "Key Data Complete");
	F.Wstring(S);
	ELog.Msg(mtInformation,S);

	F.SaveTo(n,0);

	return true;
}
Ejemplo n.º 29
0
bool LuxMaxCamera::exportCamera(float lensRadius, luxcore::Scene &scene)
{
	INode* camNode = GetCOREInterface9()->GetActiveViewExp().GetViewCamera();

	if (camNode == NULL)
	{
		MessageBox(0, L"Set active view to a target camera and render again.", L"Error!", MB_OK);
		return false;
	}
	else
	{
		CameraObject*   cameraPtr = (CameraObject *)camNode->EvalWorldState(GetCOREInterface()->GetTime()).obj;

		float v = 0.0f;
		float FOV = 0;
		float focaldistance = 0;
		Interval      ivalid = FOREVER;
		IParamBlock2 *pBlock = camNode->GetParamBlock(0);
		IParamBlock2* pblock2;

		if (v > 0.0f)
		{
			MessageBox(0, L"LuxCam modifier selected.", L"Error!", MB_OK);
			return false;
		}

		if (cameraPtr->ClassID() == MAX2016_PHYSICAL_CAMERA)
		{
			IPhysicalCamera* physicalCamera = dynamic_cast<IPhysicalCamera*>(camNode->EvalWorldState(GetCOREInterface()->GetTime()).obj);

			FOV = physicalCamera->GetFOV(GetCOREInterface()->GetTime(), FOREVER) * 180 / PI;
			focaldistance = physicalCamera->GetTDist(GetCOREInterface()->GetTime(), FOREVER);
		}
		else
		{
			FOV = cameraPtr->GetFOV(GetCOREInterface()->GetTime(), FOREVER) * 180 / PI;
			focaldistance = cameraPtr->GetTDist(GetCOREInterface()->GetTime(), FOREVER);
		}

		::Point3 camTrans = camNode->GetNodeTM(GetCOREInterface()->GetTime()).GetTrans();
		INode* NewCam = camNode;
		::Matrix3 targetPos;
		NewCam->GetTargetTM(GetCOREInterface()->GetTime(), targetPos);

		float aspectratio = GetCOREInterface11()->GetImageAspRatio();
		if (aspectratio < 1)
			FOV = 2.0f * ((180 / PI) *(atan(tan((PI / 180)*(FOV / 2.0f)) / aspectratio)));

		mprintf(L"Rendering with camera: : %s\n", camNode->GetName());
		scene.Parse(
			Property("scene.camera.lookat.orig")(camTrans.x, camTrans.y, camTrans.z) <<
			Property("scene.camera.lookat.target")(targetPos.GetTrans().x, targetPos.GetTrans().y, targetPos.GetTrans().z) <<
			Property("scene.camera.fieldofview")(FOV) <<
			Property("scene.camera.lensradius")(lensRadius) <<
			//Property("scene.camera.focaldistance")(cameraPtr->GetTDist(GetCOREInterface()->GetTime(), FOREVER)) <<
			Property("scene.camera.focaldistance")(focaldistance) <<
			Property("scene.camera.shutteropen")(0.0f) <<
			Property("scene.camera.shutterclose")(1.615f)
			);
		return true;
	}

	
}
Ejemplo n.º 30
0
void NifImporter::AlignBiped(IBipMaster* master, NiNodeRef node)
{
#ifdef USE_BIPED
   NiNodeRef parent = node->GetParent();
   string name = node->GetName();
   vector<NiAVObjectRef> children = node->GetChildren();
   vector<NiNodeRef> childNodes = DynamicCast<NiNode>(children);

   TSTR s1 = FormatText("Processing %s:", name.c_str());
   TSTR s2 = FormatText("Processing %s:", name.c_str());
   INode *bone = GetNode(node);
   if (bone != NULL) 
   {
      if (uncontrolledDummies)
         BuildControllerRefList(node, ctrlCount);

      Matrix44 m4 = node->GetWorldTransform();
      Vector3 pos; Matrix33 rot; float scale;
      m4.Decompose(pos, rot, scale);
      Matrix3 m = TOMATRIX3(m4);
      Point3 p = m.GetTrans();
      Quat q(m);

      s1 += FormatText(" ( %s)", PrintMatrix3(m).data());
      if (strmatch(name, master->GetRootName()))
      {
         // Align COM
         //PosRotScaleNode(bone, p, q, 1.0f, prsPos);
         PosRotScaleBiped(master, bone, p, q, 1.0f, prsPos);
      }
      else if (INode *pnode = bone->GetParentNode())
      {
         // Reparent if necessary
         if (!strmatch(parent->GetName(), pnode->GetName())) {
            if (pnode = FindNode(parent)) {
               bone->Detach(0);
               pnode->AttachChild(bone);
            }
         }

         // Hack to scale the object until it fits
         for (int i=0; i<10; ++i) {
            float s = CalcScale(bone, node, childNodes);
            if (fabs(s-1.0f) < (FLT_EPSILON*100.0f))
               break;
            s1 += FormatText(" (%g)", s);
            master->SetBipedScale(TRUE, ScaleValue(Point3(s,s,s)), 0, bone);
         }
         PosRotScale prs = prsDefault;
         PosRotScaleBiped(master, bone, p, q, scale, prs);

         // Rotation with Clavicle is useless in Figure Mode using the standard interface
         //   I was tring unsuccessfully to correct for it
         //if (wildcmpi("Bip?? ? Clavicle", name.c_str())) {
         //   AngAxis a1 = CalcTransform(bone, node, childNodes);
         //   Matrix3 tm1 = GenerateRotMatrix(a1);
         //   Quat nq = TransformQuat(tm1, q);
         //   PosRotScaleNode(bone, p, nq, scale, prsRot);
         //}
      }
      s2 += FormatText(" ( %s)", PrintMatrix3(bone->GetNodeTM(0)).data());
   }
   else
   {
      ImportBones(node, false);
   }
   for (char *p = s1; *p != 0; ++p) if (isspace(*p)) *p = ' ';
   for (char *p = s2; *p != 0; ++p) if (isspace(*p)) *p = ' ';
   OutputDebugString(s1 + "\n");
   OutputDebugString(s2 + "\n");

   for (vector<NiNodeRef>::iterator itr = childNodes.begin(), end = childNodes.end(); itr != end; ++itr){
      AlignBiped(master, *itr);
   }
#endif
}