Exemplo n.º 1
0
void XModifier::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index)
{
	// We don't allow a stack collapse, to delete us. 
	// We're going to apply ourselves to the collapsed object

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

	derob->AddModifier(this,NULL,derob->NumModifiers());
	bModDisabled = false;
}
Exemplo n.º 2
0
// We want to survive a collapsed stack so we reapply ourselves here
void FaceDataToColorMod::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index) {
	BOOL collapsable;
	mpParams->GetValue (pb_collapsable, TimeValue(0), collapsable, FOREVER);
	if (collapsable) return;

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

	// Add ourselves to the top of the stack
	derob->AddModifier(this,NULL,derob->NumModifiers());

	// Reengage modification:
	mDisabled = false;
}
Exemplo n.º 3
0
// We want to survive a collapsed stack so we reapply ourselves here
void EditFaceDataMod::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index) {
	if (mCollapsable) return;

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

	// Add ourselves to the top of the stack
	derob->AddModifier(this,NULL,derob->NumModifiers());

	// Reinsert our local mod data
	ModContext* mc = derob->GetModContext(derob->NumModifiers()-1);
	mc->localData = mpModDataCollapseCache;
	mpModDataCollapseCache = NULL;

	// Reengage modification:
	mDisabled = false;
}
	//------------------------------
	bool MorphControllerCreator::createMorphController( const COLLADAFW::MorphController* morphController, INode* referencingINode )
	{
		Object* sourceObject = getObjectByUniqueId( morphController->getSource() );

		if ( !sourceObject )
		{
			// TODO handle error
			// morph source object not present
			return true;
		}

		mMorphModifier = (MorphR3*) createMaxObject(OSM_CLASS_ID, MORPHER_CLASS_ID);

		if ( !mMorphModifier )
		{
			// TODO handle error
			// morph controller could not be created
			return true;
		}

		if ( (sourceObject->ClassID() == derivObjClassID) || (sourceObject->ClassID() == WSMDerivObjClassID) )
		{
			// Object is a derived object, just attach ourselves to it
			mDerivedObject = (IDerivedObject*) sourceObject;
		}
		else
		{
			// Create the derived object for the target and the modifier
			mDerivedObject = CreateDerivedObject(sourceObject);
		}

		mDerivedObject->AddModifier(mMorphModifier);
		mMorphModifier->cache.MakeCache(sourceObject);

		const COLLADAFW::FloatOrDoubleArray& morphWeights = morphController->getMorphWeights();
		const COLLADAFW::UniqueIdArray& morphTargets = morphController->getMorphTargets();
		// There is a maximum number of channels supported by the 3dsMax morpher:
		// Calculate the number of channels to process
		size_t colladaTargetCount = morphTargets.getCount();
		int channelCount = (int) min(colladaTargetCount, mMorphModifier->chanBank.size());

		const COLLADAFW::UniqueId& morphWeightsAnimationListId = morphWeights.getAnimationList();
		const COLLADAFW::AnimationList* morphWeightsAnimationList = getAnimationListByUniqueId( morphWeightsAnimationListId );

		for (int i = 0; i < channelCount; ++i)
		{
			const COLLADAFW::UniqueId& targetUniqueId = morphTargets[i];
			Object* targetObject = getObjectByUniqueId( targetUniqueId );
			if ( !targetObject )
			{
				// TODO handle error
				// the target has not been created, might be missing in dae file
				return true;
			}
			INodeList targetINodes;
			getObjectINodesByUniqueId( targetUniqueId, targetINodes );
			INode* targetINode = 0;
			if ( !targetINodes.empty() )
			{
				// it does not seem to make a difference which INode we use, as long as it references the correct geometry
				targetINode = targetINodes[0];
			}
		
			morphChannel* channel = &mMorphModifier->chanBank[i];
			if ( targetINode )
			{
				channel->buildFromNode(targetINode);
				channel->mConnection = targetINode;
			}
			else
			{
				// Manually initializes this channel
				initializeChannelGeometry(channel, targetObject);
			}

			if ( !morphWeightsAnimationList )
			{
				float weight = 0;
				if ( morphWeights.getType() == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT )
				{
					weight = (*morphWeights.getFloatValues())[i];
				}
				else if ( morphWeights.getType() == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
				{
					weight = (float)(*morphWeights.getDoubleValues())[i];
				}
				channel->cblock->SetValue(0, 0, weight * 100);
			}
		}


		if ( morphWeightsAnimationList )
		{
			const COLLADAFW::AnimationList::AnimationBindings& animationBindings = morphWeightsAnimationList->getAnimationBindings();
			for ( size_t i = 0, count = animationBindings.getCount(); i < count; ++i)
			{
				const COLLADAFW::AnimationList::AnimationBinding& animationBinding = animationBindings[i];
				if ( animationBinding.animationClass != COLLADAFW::AnimationList::ARRAY_ELEMENT_1D)
				{
					// this animation does not animate one element of a one dimensional array
					continue;
				}
				const DocumentImporter::MaxControllerList& maxControllerList = getMaxControllerListByAnimationUniqueId( animationBinding.animation );
				assert(maxControllerList.size()==1);
				if ( maxControllerList.size() < 1 )
				{
					// this animation does not animate one element of a one dimensional array
					continue;
				}
				Control* weightController = maxControllerList[0];

				size_t channelNumber = animationBinding.firstIndex;
				if ( (int)channelNumber >= channelCount )
				{
					// invalid channel
					continue;
				}
				morphChannel* channel = &mMorphModifier->chanBank[channelNumber];

				if ( !channel )
				{
					continue;
				}
				Control* scaledWeightController = cloneController( weightController, &ConversionFunctors::toPercent);
				//Control* scaledWeightController = cloneController( weightController);
				//channel->cblock->SetController(0, weightController);
				channel->cblock->SetController(0, scaledWeightController);
			}
		}


		//assign the morph controller to all INodes referencing it
		INodeList referencingINodes;
		getObjectINodesByUniqueId( morphController->getUniqueId(), referencingINodes );

		for ( size_t i = 0, count = referencingINodes.size(); i < count; ++i)
		{
			INode* referencingINode = referencingINodes[i];
			referencingINode->SetObjectRef(mDerivedObject);
		}

		addUniqueIdObjectPair( morphController->getUniqueId(), mDerivedObject );
		return true;
	}
Exemplo n.º 5
0
void UtilTest::MakeObject()
	{
	// Create a new object through the CreateInstance() API
	Object *obj = (Object*)ip->CreateInstance(
		GEOMOBJECT_CLASS_ID,
		Class_ID(CYLINDER_CLASS_ID,0));
	assert(obj);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		// Create a Space Warp Modifier
		Modifier *swmod = swobj->CreateWSMMod(swnode);
		if (swmod) {
			wsdobj->AddModifier(swmod);
			}
		}
	
	// Redraw the views
	ip->RedrawViews(ip->GetTime());
	}
Exemplo n.º 6
0
void Import::ApplyModifiers (dScene& scene, const MaxNodeChache& maxNodeCache)
{
    dScene::Iterator iter (scene);
    for (iter.Begin(); iter; iter ++) {
        dScene::dTreeNode* meshNode = iter.GetNode();
        dNodeInfo* info = scene.GetInfoFromNode(meshNode);
        if (info->IsType(dGeometryNodeInfo::GetRttiType())) {
            dScene::dTreeNode* skinModifierNode = NULL;
            for (void* ptr = scene.GetFirstChild(meshNode); ptr; ptr = scene.GetNextChild(meshNode, ptr)) {
                dScene::dTreeNode* node = scene.GetNodeFromLink(ptr);
                dNodeInfo* info = scene.GetInfoFromNode(node);
                if (info->GetTypeId() == dGeometryNodeSkinModifierInfo::GetRttiType()) {
                    skinModifierNode = node;
                    break;
                }
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

				PosRotScale prs = prsDefault;

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

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

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

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

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

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

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

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

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

			int mtlIdx = GetHavokIndexFromMaterial(shape->GetMaterial());
			int lyrIdx = GetHavokIndexFromLayer(OL_UNIDENTIFIED);
			CreatebhkCollisionModifier(n, bv_type_capsule, mtlIdx, lyrIdx, 0);
			ImportBase(body, shape, parent, n, tm);
			AddShape(rbody, n);
			return true;
		}
	}
	return true;
#endif
}
void HavokImport::createRagdollRigidBody(INode* n, INode* parent, INode* ragdollParent, bhkRigidBodyRef rbody) {

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

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

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

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

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

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

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

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


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

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


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


	}

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

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

	cc->InsertCustAttrib(0, c);

	Modifier* constraintMod = nullptr;

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

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

					Point3 origin(0, 0, 0);

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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


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

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

				//AddShape(rbody, n);
				return n;
			}
		}
	}
	return ragdollParent;
}
Exemplo n.º 10
0
void ResetXForm::ResetNodes(const INodeTab& nodesToReset)
{
	Interface *ip = GetCOREInterface();
	for (int i = 0; i < nodesToReset.Count(); i++) {
		INode *node = nodesToReset[i];
		if (!node || node->IsGroupMember() || node->IsGroupHead()) 
			continue;
		if (SelectedAncestor(node)) 
			continue;

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

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

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

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

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

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

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

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