示例#1
0
void AddSceneLights(SContext* sc, MtlBaseLib* mtls)
{
	INode* scene = GetCOREInterface()->GetRootNode();
	for (int i=0; i<scene->NumberOfChildren(); i++) {
		sceneLightEnum(scene->GetChildNode(i), sc, mtls);
	}
}
BOOL PFOperatorInstanceShapeMXSValidator::Validate(PB2Value& v)
{
	INode* iNode = (INode*)v.r;
	if (iNode == NULL) return NULL;
	TimeValue t = GetCOREInterface()->GetTime();
	Tab<INode*> stack;

	stack.Append(1, &iNode, 10);
	while (stack.Count())
	{
		INode *node = stack[stack.Count()-1];
		stack.Delete(stack.Count()-1, 1);

		Object *obj = node->EvalWorldState(t).obj;
		if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
			return TRUE;

		// add children to the stack
		for (int i = 0; i < node->NumberOfChildren(); i++) {
			INode *childNode = node->GetChildNode(i);
			if (childNode)	stack.Append(1, &childNode, 10);
		}
	}
	return FALSE;
}
示例#3
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;
			}
		}
	}
}
示例#4
0
static void GetSceneLights(Tab<INode*> & lights)
{
	Interface *ip	  = GetCOREInterface();
	TimeValue t  = ip->GetTime();
	INode * Root  = ip->GetRootNode();
	int Count = Root->NumberOfChildren();
	int i=0;

	for( i=0; i < Count; i++) 
	{
		INode * node = Root->GetChildNode(i);
		ObjectState Os   = node->EvalWorldState(t);

		if(Os.obj && Os.obj->SuperClassID() == LIGHT_CLASS_ID) 
		{
			lights.Append(1, &node);
		}
	}
}
示例#5
0
int Blockporter::DoExport(const TCHAR* name, ExpInterface* ei, Interface* i, BOOL supressPrompts, DWORD options)
{
	INode* root;
	//caption and message for MessagesBoxes
	TCHAR msg[MB_BUFFER_LENGTH];
	TCHAR cap[MB_BUFFER_LENGTH];

	//Get the root node
	root = i->GetRootNode();

	//the node of our object should be a groupnode, which contains every object
	//we want to export
	i->PushPrompt(_T("Searching for Group..."));
	bool found = false;
	for(int idx = 0; idx < root->NumberOfChildren(); idx++)
	{
		if(root->GetChildNode(idx)->IsGroupHead())
		{
			//we found our group
			//next step is to make the group node our new root, because every object
			//we want is part of this group

			found = true;
			root = root->GetChildNode(idx);
			break;
		}
	}

	if(!found)
	{
		MessageBox(nullptr, GetString(IDS_ERROR_NO_GROUP, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR);
		return 0;
	}

	//Now that we have the groupnode let's compare the fileversions
	if(!IsNewModelVersion(name, root->GetName()))
	{
		if(MessageBox(nullptr, GetString(IDS_VER_TO_LOW_MSG, msg), GetString(IDS_VER_TO_LOW_CAP, cap), MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
			return 1;
	}

	i->PushPrompt(_T("Opening File"));
	Interface14* iface = GetCOREInterface14();
	UINT code = iface->DefaultTextSaveCodePage(true);
	MaxSDK::Util::Path storageNamePath(name);
	storageNamePath.SaveBaseFile();
	switch (code & MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_MASK)
	{
	case CP_UTF8:
		mStream = _tfopen(name, _T("wt, ccs=UFT-8"));
		break;
	case MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_UTF16:
		mStream = _tfopen(name, _T("wt, ccs=UTF-16BE"));
		break;
	default:
		mStream = _tfopen(name, _T("wt"));
	}
	if(!mStream)
		return 0;

	//now we have our file stream, so let's write the header
	i->PushPrompt(_T("Writing Header"));
	WriteHeader(root->GetName(), root->NumberOfChildren());

	//now that we have the header written, let's iterate through the objects in the
	//group and export the meshes and lights

	INode* child;
    Point3 pMin(0,0,0), pMax(0,0,0);

	for(int idx = 0; idx < root->NumberOfChildren(); idx++)
	{
		child = root->GetChildNode(idx);
		i->PushPrompt(_T("Processing Object %s", child->GetName()));
		if(child->IsGroupHead())
		{
			MessageBox(nullptr, GetString(IDS_ERROR_TO_MANY_GROUPS, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR);
			continue;
		}

		ObjectState os = child->EvalWorldState(0);

		//let's take a look at the SuperClassID of the object
		//so we find out if it's a mesh or a light
		if(!os.obj)
			continue; //somehow this node doesn't have an object

        Box3 boundBox;

		switch(os.obj->SuperClassID())
		{
		case GEOMOBJECT_CLASS_ID:
			_ftprintf(mStream, _T("<ObjectID=%i>\n"), idx);
			i->PushPrompt(_T("Writing MeshData for Object %s", child->GetName()));
			boundBox = WriteMeshData(child, idx);
            pMin.x = (boundBox.Min().x < pMin.x) ? boundBox.Min().x : pMin.x;
            pMin.y = (boundBox.Min().y < pMin.y) ? boundBox.Min().y : pMin.y;
            pMax.x = (boundBox.Max().x > pMax.x) ? boundBox.Max().x : pMax.x;
            pMax.y = (boundBox.Max().y > pMax.y) ? boundBox.Max().y : pMax.y;
			i->PushPrompt(_T("Writing MaterialData for Object %s", child->GetName()));
			WriteMaterialData(child);
			_ftprintf(mStream, _T("</Object>\n"));
			break;
		//case LIGHT_CLASS_ID:
		//	WriteLightData(child, idx);
		//	break;
		}
	}

    //Write the Bounding Box
    _ftprintf(mStream, _T("<BoundingBox>\n"));
    _ftprintf(mStream, _T("\t<Min=%f,%f>\n"), pMin.x, pMin.y);
    _ftprintf(mStream, _T("\t<Max=%f,%f>\n"), pMax.x, pMax.y);
    _ftprintf(mStream, _T("</BoundingBox>\n"));
	//we are done exporting, so close the stream
	i->PushPrompt(_T("Closing file..."));
	fclose(mStream);

	MessageBox(nullptr, GetString(IDS_FINISH_MSG, msg), GetString(IDS_FINISH_CAP, cap), MB_OK | MB_ICONINFORMATION);

	return 1;
}
示例#6
0
void Lighting::GetLightsFromScene()
{
	Interface		*Ip;
//	INode			*Node,*Root;
	Matrix3			Mat;
	int				i,Count;
	ObjectState		Os;
//	LightObject		*LightObj;
//	LightState		Ls;
//	RenderLight		Light;	
	TimeValue		Time;
	Interval		valid;
//	Point3			Pos,Target;

	Ip	  = GetCOREInterface();
	Time  = Ip->GetTime();
	INode * Root  = Ip->GetRootNode();
	Count = Root->NumberOfChildren();

	sceneLights.SetCount(0);
	
	for(i=0; i < Count; i++) 
	{
		INode * Node = Root->GetChildNode(i);
		Os   = Node->EvalWorldState(Time);
		
		if(Os.obj && Os.obj->SuperClassID() == LIGHT_CLASS_ID) 
		{
			sceneLights.Append(1,&Node);
/*			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);
*/
		}
	}
	m_forceUpdate = false;

}
示例#7
0
NxActor* MxActor::createNxActor()
{
	if (m_bulletBody)
	{
		MaxMsgBox(NULL, _T("Error: body was already added to the dynamics world"), _T("Error"), MB_OK);
		return 0;
	}

	// find proxy node
	m_proxyNode = NULL;
	TSTR str = MxUserPropUtils::GetUserPropStr(m_node, "Proxy_Geometry");
	char* proxyName = str.data();
	if(proxyName && strlen(proxyName) > 0 && (stricmp(proxyName, "<None>") != 0))
	{
		m_proxyNode = GetCOREInterface()->GetINodeByName(proxyName);
	}

	//
	
	ccMaxNode* pActorNode = ccMaxWorld::FindNode(m_node);
	assert(pActorNode);
	maxNodeActor = pActorNode;

	maxNodeProxy = NULL;
	if(m_proxyNode)
	{
		maxNodeProxy       = ccMaxWorld::FindNode(m_proxyNode);
		assert(maxNodeProxy);
		//Point3 p1 = maxNodeActor->PhysicsNodePoseTM.GetRow(3), p2 = maxNodeProxy->PhysicsNodePoseTM.GetRow(3);
		Point3 p1 = maxNodeActor->NodePosInPhysics, p2 = maxNodeProxy->NodePosInPhysics;
		ProxyDistance = p1 - p2;
	}

	NxActorDesc&  actorDesc  = m_desc;
	NxBodyDesc&   bodyDesc   = m_bodyDesc;
	//LoadParameters(actorDesc, bodyDesc);
	actorDesc.globalPose = pActorNode->PhysicsNodePoseTM;//MxMathUtils::MaxMatrixToNx(pActorNode->PhysicsNodePoseTM);
	SaveLastPose(pActorNode->PhysicsNodePoseTM);

	//m_bodydesc.solverIterationCount = (NxU32)mSetting_solveriterationcount;   // support it in future?

	std::vector<INode*> stack;
	std::vector<INode*> shapes;

	//Check if the object is using a proxy, in that case only those shapes should be added
	INode* current = m_node;
	if(m_proxyNode)
		current = m_proxyNode;
	stack.push_back(current);
	//DEBUG_S("List collision shapes");
	while (stack.size() > 0)
	{
		current = stack[0];
		if(stack.size() > 1)
		{
			stack[0] = stack.back();
		}
		stack.pop_back();

		if(current->EvalWorldState(0).obj->SuperClassID()==GEOMOBJECT_CLASS_ID)
		{
			shapes.push_back(current);
		}

		//go through grouped objects
		for(int i = 0; i < current->NumberOfChildren(); i++)
		{
			INode *c = current->GetChildNode(i);
			if (c->IsGroupMember()) 
			{
				stack.push_back(c);
			}
		}
	}

	if (shapes.size() == 0)
	{
		if (gCurrentstream) gCurrentstream->printf("Unable to add %s as an actor, it has no shapes.\n", m_node->GetName());
		return 0;
	}

	ccMaxNode* baseNode = pActorNode;
	if(maxNodeProxy)
	{
		baseNode = maxNodeProxy;
	}

	btAlignedObjectArray<btCollisionShape*> collisionShapes;
	btAlignedObjectArray<btTransform> localTransforms;



	for (int i = 0; i < shapes.size(); i++) 
	{
		INode* current = shapes[i];
		//DEBUG_F(" Debug adding shape node: %s\n", current->GetName());
		ccMaxNode* pn = ccMaxWorld::FindNode(current);
		assert(pn);
		btCollisionShape* collisionShape = createShape(actorDesc, pn, pActorNode);
		collisionShapes.push_back(collisionShape);

		btTransform localTrans;
		max2Bullet(actorDesc.localPose,localTrans);
		localTransforms.push_back(localTrans);
	}

	//create a rigid body and add it to the world
	if (collisionShapes.size())
	{
		btCollisionShape* collisionShape = 0;
		if (collisionShapes.size()==1)
		{
			collisionShape = collisionShapes[0];

		} else
		{
			btCompoundShape* compound = new btCompoundShape();
			for (int i=0;i<collisionShapes.size();i++)
			{
				compound->addChildShape(localTransforms[i],collisionShapes[i]);
			}
			//clear local pose
			actorDesc.localPose.IdentityMatrix();
			collisionShape = compound;
		}

		if (collisionShape)
		{
			btVector3 localInertia(0,0,0);
			if (actorDesc.mass)
			{
				collisionShape->calculateLocalInertia(actorDesc.mass,localInertia);
			}

			m_bulletBody = new btRigidBody(actorDesc.mass,0,collisionShape,localInertia);
			m_bulletBody->setUserPointer(this);

			btScalar restitution;
			if (MxUserPropUtils::GetUserPropFloat(m_node, "Restitution", restitution))
			{
				m_bulletBody->setRestitution(restitution);
			}
			btScalar staticFriction = 0.f;

			//take the maximum for now
			MxUserPropUtils::GetUserPropFloat(m_node, "StaticFriction", staticFriction);
			
			btScalar friction = 0.f;
			if (MxUserPropUtils::GetUserPropFloat(m_node, "Friction", friction))
			{
				if (staticFriction>friction)
					friction = staticFriction;

				m_bulletBody->setFriction(friction);
			}


//			char bla[1024];
//			sprintf(bla,"restitution=%f",restitution);
//			MaxMsgBox(NULL, _T(bla), _T("Error"), MB_OK);

			syncGlobalPose();
			

			gDynamicsWorld->addRigidBody(m_bulletBody);
//			MaxMsgBox(NULL, _T("adding rigid body"), _T("Error"), MB_OK);

		}
	}
	
	
	bool isvalid = actorDesc.isValid();
	actorDesc.name = m_node->GetName();
	//NxMat34 pose0 = actorDesc.globalPose;
	
	//m_actor = gPluginData->getScene()->createActor(actorDesc);
	//if(! m_actor) return 0;

	//NxMat34 pose1 = m_actor->getGlobalPose();
	// sometimes pose1 != pose0; it is strange
	//m_actor->userData = this;

	if(MxUserPropUtils::GetUserPropBool(m_node, "PutToSleep", false))
	{
		//m_actor->putToSleep();
	}
	// for collision force when contact happens
	/*
	NxU32 num = m_actor->getNbShapes();
	NxShape*const* ps = m_actor->getShapes();
	for(NxU32 i = 0; i < num; ++i)
	{
		NxShape* nxShape = ps[i];
		nxShape->setFlag(NX_SF_POINT_CONTACT_FORCE, true);
	}
	*/


	//save last pose
	Matrix3 poseTM = maxNodeActor->GetCurrentTM();
	SaveLastPose(poseTM);


	//return m_actor;
	return 0;
}
示例#8
0
void CExportNel::buildSkeleton (std::vector<CBoneBase>& bonesArray, INode& node, mapBoneBindPos* mapBindPos, TInodePtrInt& mapId, 
								std::set<std::string> &nameSet, TimeValue time, sint32& idCount, sint32 father)
{
	// **** Save the current the id
	int id=idCount;

	// **** Create a bone
	CBoneBase bone;

	// ** Set Name and id

	// Bone name
	bone.Name=getName (node);

	// Inserted ?
	if (!nameSet.insert (bone.Name).second)
		bone.Name+="_Second";

	// Id of the father
	bone.FatherId=father;

	// Insert id with name
	mapId.insert (TInodePtrInt::value_type(&node, id));

	// ** Set inherit flags

	// Must remove Scale from my father??
	bone.UnheritScale= getNELUnHeritFatherScale(node);


	// **** Set default tracks

	// Get the Nel Local TM
	NLMISC::CVector		nelScale;
	NLMISC::CQuat		nelRot;
	NLMISC::CVector		nelPos;
	getNELBoneLocalTM(node, time, nelScale, nelRot, nelPos);

	// Root must be exported with Identity because path are setuped interactively in the root of the skeleton
	if(id==0)
	{
		// Keep only the scale, because this last is not animated.
		nelPos= CVector::Null;
		nelRot= CQuat::Identity;
	}

	// Set the default tracks
	bone.DefaultScale=nelScale;
	bone.DefaultRotQuat=nelRot;
	bone.DefaultRotEuler=CVector (0,0,0);
	bone.DefaultPos=nelPos;


	// **** Get node bindpos matrix
	Matrix3 worldTM;
	bool matrixComputed=false;
	if (mapBindPos)
	{
		// Look for an entry in the map
		mapBoneBindPos::iterator bindPos=mapBindPos->find (&node);

		// Found ?
		if (bindPos!=mapBindPos->end())
		{
			// Get bind pos
			worldTM=bindPos->second;

			// Computed
			matrixComputed=true;
		}
	}

	// Compute the matrix the normal way ?
	if (!matrixComputed)
	{
		// if we have a reference node, ie the one with the good original pos/rot/scale used for bindPos, must use it.
		INode	*referenceNode= getNELScaleReferenceNode(node);
		if (referenceNode)
		{
			worldTM= referenceNode->GetNodeTM (time);
		}
		// else use mine.
		else
		{
			worldTM= node.GetNodeTM (time);
		}
	}

	// Set the bind pos of the bone, it is invNodeTM;
	convertMatrix (bone.InvBindPos, worldTM);
	bone.InvBindPos.invert();

	// **** Get bone Lod disactivation
	bone.LodDisableDistance= getScriptAppData (&node, NEL3D_APPDATA_BONE_LOD_DISTANCE, 0.f);
	bone.LodDisableDistance= std::max(0.f, bone.LodDisableDistance);

	// **** Add the bone
	bonesArray.push_back (bone);

	// **** Call on child
	for (int children=0; children<node.NumberOfChildren(); children++)
		buildSkeleton (bonesArray, *node.GetChildNode(children), mapBindPos, mapId, nameSet, time, ++idCount, id);
}