void UPoseableMeshComponent::SetBoneTransformByName(FName BoneName, const FTransform& InTransform, EBoneSpaces::Type BoneSpace)
{
	if( !SkeletalMesh || !RequiredBones.IsValid() )
	{
		return;
	}

	int32 BoneIndex = GetBoneIndex(BoneName);
	if(BoneIndex >=0 && BoneIndex < LocalAtoms.Num())
	{
		LocalAtoms[BoneIndex] = InTransform;

		// If we haven't requested local space we need to transform the position passed in
		//if(BoneSpace != EBoneSpaces::LocalSpace)
		{
			if(BoneSpace == EBoneSpaces::WorldSpace)
			{
				LocalAtoms[BoneIndex].SetToRelativeTransform(GetComponentToWorld());
			}

			int32 ParentIndex = RequiredBones.GetParentBoneIndex(BoneIndex);
			if(ParentIndex >=0)
			{
				FA2CSPose CSPose;
				CSPose.AllocateLocalPoses(RequiredBones, LocalAtoms);

				LocalAtoms[BoneIndex].SetToRelativeTransform(CSPose.GetComponentSpaceTransform(ParentIndex));
			}

			// Need to send new state to render thread
			MarkRenderDynamicDataDirty();
		}
	}
}
void MorphByBone::fnRemoveBone(INode *node)
{
	int boneIndex = GetBoneIndex(node);
	this->DeleteBone(boneIndex);
	UpdateLocalUI();
	BuildTreeList();
}
FTransform UPoseableMeshComponent::GetBoneTransformByName(FName BoneName, EBoneSpaces::Type BoneSpace)
{
	if( !SkeletalMesh || !RequiredBones.IsValid() )
	{
		return FTransform();
	}

	int32 BoneIndex = GetBoneIndex(BoneName);
	if( BoneIndex == INDEX_NONE)
	{
		FString Message = FString::Printf(TEXT("Invalid Bone Name '%s'"), *BoneName.ToString());
		FFrame::KismetExecutionMessage(*Message, ELogVerbosity::Warning);
		return FTransform();
	}

	/*if(BoneSpace == EBoneSpaces::LocalSpace)
	{
		return LocalAtoms[i];
	}*/

	FA2CSPose CSPose;
	CSPose.AllocateLocalPoses(RequiredBones, LocalAtoms);

	if(BoneSpace == EBoneSpaces::ComponentSpace)
	{
		return CSPose.GetComponentSpaceTransform(BoneIndex);
	}
	else
	{
		return CSPose.GetComponentSpaceTransform(BoneIndex) * ComponentToWorld;
	}
}
示例#4
0
void mCSkin::LimitNumInfluencingBonesPerVert( MIUInt const a_uMax )
{
    mTArray< MIUInt >  arrVertexIndices( m_arrVertexIndices.GetCount() );
    mTArray< MIUInt >  arrBoneIndices( m_arrBoneIndices.GetCount() );
    mTArray< MIFloat > arrWeights( m_arrWeights.GetCount() );
    mTArray< MIUInt >  arrVertWeightIndices( 0, 100 );
    MIUInt * pVertWeightIndices = arrVertWeightIndices.AccessBuffer();
    for ( MIUInt u = 0, ue = GetNumVerts(); u != ue; ++u )
    {
        MIUInt uWeightCount = GetNumInfluencingBones( u );
        MIFloat fWeightSum = 0.0f;
        s_pWeights = &m_arrWeights[ m_arrFirstWeightIndexPerVertex[ u ] ];
        for ( MIUInt v = uWeightCount; v--; pVertWeightIndices[ v ] = v );
        qsort( pVertWeightIndices, uWeightCount, sizeof( *pVertWeightIndices ), &CompareVretWeightIndices );
        uWeightCount = g_min( uWeightCount, a_uMax );
        for ( MIUInt v = 0; v != uWeightCount; ++v )
        {
            arrVertexIndices.Add( u );
            arrBoneIndices.Add( GetBoneIndex( u, pVertWeightIndices[ v ] ) );
            arrWeights.Add( s_pWeights[ pVertWeightIndices[ v ] ] );
            fWeightSum += s_pWeights[ pVertWeightIndices[ v ] ];
        }
        for ( MIFloat * pWeights = &arrWeights.Back(), * pEnd = pWeights - uWeightCount; pWeights != pEnd; *pWeights-- /= fWeightSum );
    }
    arrVertexIndices.UnReserve();
    arrBoneIndices.UnReserve();
    arrWeights.UnReserve();
    mCSkin skinResult;
    skinResult.InitSwapping( GetNumVerts(), m_arrBoneIDs, arrVertexIndices, arrBoneIndices, arrWeights );
    Swap( skinResult );
}
示例#5
0
void UDestructibleComponent::WakeRigidBody(FName BoneName /* = NAME_None */)
{
#if WITH_APEX
	ExecuteOnPhysicsReadWrite([&]
	{
		const int32 ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
		ApexDestructibleActor->setChunkPhysXActorAwakeState(ChunkIdx, true);
	});
#endif
}
void	MorphByBone::fnSelectBone(INode *node,const TCHAR* morphName)
{
	int boneIndex = GetBoneIndex(node);
	int morphIndex = GetMorphIndex(node,morphName);
	this->currentBone = boneIndex;
	this->currentMorph = morphIndex;
	UpdateLocalUI();
	BuildTreeList();
	NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
	GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime());

}
示例#7
0
void UDestructibleComponent::AddForce( FVector Force, FName BoneName /*= NAME_None*/, bool bAccelChange /* = false */ )
{
#if WITH_APEX
	ExecuteOnPhysicsReadWrite([&]
	{
		const int32 ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
		if (PxRigidDynamic* Actor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx))
		{
			Actor->addForce(U2PVector(Force), bAccelChange ? PxForceMode::eACCELERATION : PxForceMode::eFORCE);
		}
	});
#endif
}
示例#8
0
void UDestructibleComponent::AddForceAtLocation( FVector Force, FVector Location, FName BoneName /*= NAME_None*/ )
{
#if WITH_APEX
	ExecuteOnPhysicsReadWrite([&]
	{
		int32 ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
		if (PxRigidDynamic* Actor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx))
		{
			PxRigidBodyExt::addForceAtPos(*Actor, U2PVector(Force), U2PVector(Location), PxForceMode::eFORCE);
		}
	});
#endif
}
void UDestructibleComponent::AddForce( FVector Force, FName BoneName /*= NAME_None*/, bool bAccelChange /* = false */ )
{
#if WITH_APEX
	int32 ChunkIdx = NxModuleDestructibleConst::INVALID_CHUNK_INDEX;
	if (BoneName != NAME_None)
	{
		ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
	}

	PxRigidDynamic* Actor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx);
	Actor->addForce(U2PVector(Force), bAccelChange ? PxForceMode::eACCELERATION : PxForceMode::eFORCE);
#endif
}
示例#10
0
void UDestructibleComponent::AddImpulse( FVector Impulse, FName BoneName /*= NAME_None*/, bool bVelChange /*= false*/ )
{
#if WITH_APEX
	ExecuteOnPhysicsReadWrite([&]
	{
		const int32 ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
		if(PxRigidDynamic* Actor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx))
		{
			Actor->addForce(U2PVector(Impulse), bVelChange ? PxForceMode::eVELOCITY_CHANGE : PxForceMode::eIMPULSE);
		}
	});
#endif
}
示例#11
0
FBodyInstance* UDestructibleComponent::GetBodyInstance( FName BoneName /*= NAME_None*/, bool) const
{
#if WITH_APEX
	if (ApexDestructibleActor != NULL)
	{
		int32 BoneIdx = GetBoneIndex(BoneName);
		PxRigidDynamic* PActor = ApexDestructibleActor->getChunkPhysXActor(BoneIdxToChunkIdx(BoneIdx));

		const_cast<UDestructibleComponent*>(this)->SetupFakeBodyInstance(PActor, BoneIdx);
	}
#endif // WITH_APEX

	return (FBodyInstance*)&BodyInstance;
}
void UDestructibleComponent::AddImpulse( FVector Impulse, FName BoneName /*= NAME_None*/, bool bVelChange /*= false*/ )
{
#if WITH_APEX
	int32 ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
	PxRigidDynamic* PActor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx);

	if (PActor != NULL)
	{
		SCOPED_SCENE_WRITE_LOCK(PActor->getScene());

		PActor->addForce(U2PVector(Impulse), bVelChange ? PxForceMode::eVELOCITY_CHANGE : PxForceMode::eIMPULSE);
	}
#endif
}
示例#13
0
FTransform UDestructibleComponent::GetSocketTransform(FName InSocketName, ERelativeTransformSpace TransformSpace) const
{
	FTransform ST = Super::GetSocketTransform(InSocketName, TransformSpace);

	int32 BoneIdx = GetBoneIndex(InSocketName);

	// As bones in a destructible might be scaled to 0 when hidden, we force a scale of 1 if we want the socket transform
	if (BoneIdx > 0 && IsBoneHidden(BoneIdx))
	{
		ST.SetScale3D(FVector(1.0f, 1.0f, 1.0f));
	}

	return ST;
}
void UDestructibleComponent::AddForceAtLocation( FVector Force, FVector Location, FName BoneName /*= NAME_None*/ )
{
#if WITH_APEX
	if (ApexDestructibleActor)
	{
		int32 ChunkIdx = NxModuleDestructibleConst::INVALID_CHUNK_INDEX;
		if (BoneName != NAME_None)
		{
			ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
		}

		PxRigidDynamic* Actor = ApexDestructibleActor->getChunkPhysXActor(ChunkIdx);
		Actor->addForce(U2PVector(Force), PxForceMode::eFORCE);
	}
#endif
}
void UPoseableMeshComponent::ResetBoneTransformByName(FName BoneName)
{
	if( !SkeletalMesh )
	{
		return;
	}

	const int32 BoneIndex = GetBoneIndex(BoneName);
	if( BoneIndex != INDEX_NONE )
	{
		LocalAtoms[BoneIndex] = SkeletalMesh->RefSkeleton.GetRefBonePose()[BoneIndex];
	}
	else
	{
		FString Message = FString::Printf(TEXT("Invalid Bone Name '%s'"), *BoneName.ToString());
		FFrame::KismetExecutionMessage(*Message, ELogVerbosity::Warning);
	}
}
void UDestructibleComponent::AddForce( FVector Force, FName BoneName /*= NAME_None*/ )
{
#if WITH_APEX
	int32 ChunkIdx = NxModuleDestructibleConst::INVALID_CHUNK_INDEX;
	if (BoneName != NAME_None)
	{
		ChunkIdx = BoneIdxToChunkIdx(GetBoneIndex(BoneName));
	}

	//ApexDestructibleActor->applyDamage(1.0f, Impulse.Size(), U2PVector(Position), U2PVector(Impulse.SafeNormal()), ChunkIdx);
	for (int32 i=0; i < ChunkInfos.Num(); ++i)
	{
		if (ChunkInfos[i].ChunkIndex == ChunkIdx && ChunkInfos[i].Actor)
		{
			ChunkInfos[i].Actor->addForce(U2PVector(Force), PxForceMode::eFORCE);
		}
	}
#endif
}
示例#17
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CStravaganzaMaxTools
//
//  - prototype : int BuildPhysiqueData(INode* pMaxNode,
//										CObject* pObject,
//                                      std::vector<std::string>    &vecBoneNames,
//										std::vector<CBlendedVertex> &vecBlendedVertices)
//
//  - Purpose   : Builds the bone data for a given node. Returns the number
//                of bones processed (0 = failure).
//
// -----------------------------------------------------------------------------
int	CStravaganzaMaxTools::BuildPhysiqueData(INode* pMaxNode,
											CObject* pObject,
											std::vector<std::string>    &vecBoneNames,
											std::vector<CBlendedVertex> &vecBlendedVertices)

{
	int nCount       = 0;
	int nBoneCount   = 0;

	Modifier          *pPhyModifier  = NULL; // Physique modifier
	IPhysiqueExport   *pPhyExport    = NULL; // Physique export interface
	IPhyContextExport *pPhyObjExport = NULL; // Physique object export interface

	vecBoneNames.clear();
	vecBlendedVertices.clear();

	// Build bone list

	std::vector<INode*> vecMaxBones;

	if(!AddNodeBones(vecMaxBones, pMaxNode))
	{
		LOG.Write("\nWARNING - Error building node %s bone list", pMaxNode->GetName());
		return 0;
	}

	// Build bones name list

	for(nBoneCount = 0; nBoneCount < vecMaxBones.size(); nBoneCount++)
	{
		vecBoneNames.push_back(vecMaxBones[nBoneCount]->GetName());
	}

	// Get Physique modifier

	if(pPhyModifier = GetPhysiqueModifier(pMaxNode))
	{
		pPhyExport = (IPhysiqueExport *)pPhyModifier->GetInterface(I_PHYINTERFACE);

		if(pPhyExport == NULL)
		{
			LOG.Write("\nWARNING - Couldn't get Physique export interface.\nFailed with node %s.", pMaxNode->GetName());
			return 0;
		}
	}

	// Get physique object export interface

	pPhyObjExport = pPhyExport->GetContextInterface(pMaxNode);

	if(pPhyObjExport == NULL)
	{
		pPhyModifier->ReleaseInterface(I_PHYINTERFACE, pPhyExport);
		LOG.Write("\nWARNING - Unable to get physique context export.\nFailed with node %s.", pMaxNode->GetName());
		return 0;
	}

	// Convert to rigid for time independent vertex assignment
	// Allow blending to export multi-link assignments

	pPhyObjExport->ConvertToRigid(true);
	pPhyObjExport->AllowBlending(true);

	// Build deformable vertex list

	bool bOK = true;
	int  nBlendedCount = 0, nBlendedRigidCount = 0, nFloatingCount = 0;

	for(nCount = 0; nCount < pPhyObjExport->GetNumberVertices(); nCount++)
	{
		IPhyVertexExport       *pPhyVertExport;
		IPhyBlendedRigidVertex *pPhyBRVertexExport;
		IPhyRigidVertex        *pPhyRigidVertexExport;
		IPhyFloatingVertex	   *pPhyFloatingVertex;

		pPhyVertExport  = pPhyObjExport->GetVertexInterface(nCount);

		CBlendedVertex blendedVertex;
		float fTotalWeight   = 0.0f;
		bool  bFloatingBones = false;

		// Floating Vertex

		pPhyFloatingVertex = pPhyObjExport->GetFloatingVertexInterface(nCount);

		if(pPhyFloatingVertex)
		{
			bFloatingBones = true;

			CVector3 v3OffsetVector;
			float    fWeight;

			// More than one bone

			int nNumVtxBones = pPhyFloatingVertex->GetNumberNodes();

//			LOG.Write("\n%u - Floating, with %u bones", nCount, nNumVtxBones);

			for(nBoneCount = 0; nBoneCount < nNumVtxBones; nBoneCount++)
			{
				int nIndex = GetBoneIndex(vecMaxBones, pPhyFloatingVertex->GetNode(nBoneCount));

				if(nIndex == -1)
				{
					LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyFloatingVertex->GetNode(nBoneCount)->GetName());
					bOK = false;
					break;
				}

				float fTotal;

				v3OffsetVector = Point3ToVector3(pPhyFloatingVertex->GetOffsetVector(nBoneCount));
				fWeight        = pPhyFloatingVertex->GetWeight(nBoneCount, fTotal);
				fTotalWeight  += fWeight;//fTotal;
				//fWeight = fTotal;

//				LOG.Write("\n     Weight = %f (%s)", fWeight, pPhyFloatingVertex->GetNode(nBoneCount)->GetName());

				blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);
			}

//			LOG.Write("\n     Total = %f", fTotalWeight);

			if(!ARE_EQUAL(fTotalWeight, 1.0f))
			{
				LOG.Write("\n WARNING - Vertex %u has total weights %f", nCount, fTotalWeight);
			}

			nFloatingCount++;

			pPhyObjExport->ReleaseVertexInterface(pPhyFloatingVertex);
		}

		if(pPhyVertExport)
		{
			if(pPhyVertExport->GetVertexType() & BLENDED_TYPE)
			{
				CVector3 v3OffsetVector;
				float    fWeight;

				// More than one bone

				pPhyBRVertexExport = (IPhyBlendedRigidVertex *)pPhyVertExport;
				int nNumVtxBones   = pPhyBRVertexExport->GetNumberNodes();

//				LOG.Write("\n%u - Blended, with %u bones", nCount, nNumVtxBones);

				for(nBoneCount = 0; nBoneCount < nNumVtxBones; nBoneCount++)
				{
					int nIndex = GetBoneIndex(vecMaxBones, pPhyBRVertexExport->GetNode(nBoneCount));

					if(nIndex == -1)
					{
						LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyBRVertexExport->GetNode(nBoneCount)->GetName());
						bOK = false;
						break;
					}

					v3OffsetVector = Point3ToVector3(pPhyBRVertexExport->GetOffsetVector(nBoneCount));
					fWeight        = pPhyBRVertexExport->GetWeight(nBoneCount);
					fTotalWeight  += fWeight;

//					LOG.Write("\n     Weight = %f (%s)", fWeight, pPhyBRVertexExport->GetNode(nBoneCount)->GetName());

					blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);
				}

//				LOG.Write("\n     Total = %f", fTotalWeight);

				if(!ARE_EQUAL(fTotalWeight, 1.0f))
				{
					LOG.Write("\n WARNING - Vertex %u has total weights %f", nCount, fTotalWeight);
				}

				nBlendedCount++;
			}
			else
			{
				CVector3 v3OffsetVector;
				float    fWeight;

				// Single bone

				pPhyRigidVertexExport = (IPhyRigidVertex *)pPhyVertExport;

				int nIndex = GetBoneIndex(vecMaxBones, pPhyRigidVertexExport->GetNode());

				if(nIndex == -1)
				{
					LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyRigidVertexExport->GetNode()->GetName());
					bOK = false;
					break;
				}

				v3OffsetVector = Point3ToVector3(pPhyRigidVertexExport->GetOffsetVector());
				fWeight        = 1.0f;
				fTotalWeight   = 1.0f;

//				LOG.Write("\n%u - Rigid (%s)", nCount, pPhyRigidVertexExport->GetNode()->GetName());

				blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);

				nBlendedRigidCount++;
			}

			pPhyObjExport->ReleaseVertexInterface(pPhyVertExport);
		}

		for(int i = 0; i < blendedVertex.GetNumLinks(); i++)
		{
			// Normalize
			blendedVertex.SetWeight(i, blendedVertex.GetWeight(i) / fTotalWeight);
		}

		vecBlendedVertices.push_back(blendedVertex);
	}

	pPhyExport->ReleaseContextInterface(pPhyObjExport);
	pPhyModifier->ReleaseInterface(I_PHYINTERFACE, pPhyExport);

	if(!bOK)
	{
		vecMaxBones.clear();
		vecBoneNames.clear();
		vecBlendedVertices.clear();
	}
	else
	{
		LOG.Write("\nPhysique: %u bones, %u vertices (%u rigid, %u rigidblended, %u floating)",
				  vecBoneNames.size(),
				  vecBlendedVertices.size(),
				  nBlendedRigidCount,
				  nBlendedCount,
				  nFloatingCount);
	}

	return vecMaxBones.size();
}
示例#18
0
void UPhATEdSkeletalMeshComponent::RenderAssetTools(const FSceneView* View, class FPrimitiveDrawInterface* PDI, bool bHitTest)
{
	check(SharedData);

	UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset();
	check(PhysicsAsset);

	bool bHitTestAndBodyMode = bHitTest && SharedData->EditingMode == FPhATSharedData::PEM_BodyEdit;
	bool bHitTestAndConstraintMode = bHitTest && SharedData->EditingMode == FPhATSharedData::PEM_ConstraintEdit;

	FPhATSharedData::EPhATRenderMode CollisionViewMode = SharedData->GetCurrentCollisionViewMode();

#if DEBUG_CLICK_VIEWPORT
	PDI->DrawLine(SharedData->LastClickOrigin, SharedData->LastClickOrigin + SharedData->LastClickDirection * 5000.0f, FLinearColor(1, 1, 0, 1), SDPG_Foreground);
	PDI->DrawPoint(SharedData->LastClickOrigin, FLinearColor(1, 0, 0), 5, SDPG_Foreground);
#endif
	// Draw bodies
	for (int32 i = 0; i <PhysicsAsset->BodySetup.Num(); ++i)
	{
		int32 BoneIndex = GetBoneIndex(PhysicsAsset->BodySetup[i]->BoneName);

		// If we found a bone for it, draw the collision.
		// The logic is as follows; always render in the ViewMode requested when not in hit mode - but if we are in hit mode and the right editing mode, render as solid
		if (BoneIndex != INDEX_NONE)
		{
			FTransform BoneTM = GetBoneTransform(BoneIndex);
			float Scale = BoneTM.GetScale3D().GetAbsMax();
			FVector VectorScale(Scale);
			BoneTM.RemoveScaling();

			FKAggregateGeom* AggGeom = &PhysicsAsset->BodySetup[i]->AggGeom;

			for (int32 j = 0; j <AggGeom->SphereElems.Num(); ++j)
			{
				if (bHitTest)
				{
					PDI->SetHitProxy(new HPhATEdBoneProxy(i, KPT_Sphere, j));
				}

				FTransform ElemTM = GetPrimitiveTransform(BoneTM, i, KPT_Sphere, j, Scale);

				//solids are drawn if it's the ViewMode and we're not doing a hit, or if it's hitAndBodyMode
				if( (CollisionViewMode == FPhATSharedData::PRM_Solid && !bHitTest) || bHitTestAndBodyMode)
				{
					UMaterialInterface*	PrimMaterial = GetPrimitiveMaterial(i, KPT_Sphere, j, bHitTestAndBodyMode);
					AggGeom->SphereElems[j].DrawElemSolid(PDI, ElemTM, VectorScale, PrimMaterial->GetRenderProxy(0));
				}

				//wires are never used during hit
				if(!bHitTest)
				{
					if (CollisionViewMode == FPhATSharedData::PRM_Solid || CollisionViewMode == FPhATSharedData::PRM_Wireframe)
					{
						AggGeom->SphereElems[j].DrawElemWire(PDI, ElemTM, VectorScale, GetPrimitiveColor(i, KPT_Sphere, j));
					}
				}

				if (bHitTest)
				{
					PDI->SetHitProxy(NULL);
				}
				
			}

			for (int32 j = 0; j <AggGeom->BoxElems.Num(); ++j)
			{
				if (bHitTest)
				{
					PDI->SetHitProxy(new HPhATEdBoneProxy(i, KPT_Box, j));
				}

				FTransform ElemTM = GetPrimitiveTransform(BoneTM, i, KPT_Box, j, Scale);

				if ( (CollisionViewMode == FPhATSharedData::PRM_Solid && !bHitTest) || bHitTestAndBodyMode)
				{
					UMaterialInterface*	PrimMaterial = GetPrimitiveMaterial(i, KPT_Box, j, bHitTestAndBodyMode);
					AggGeom->BoxElems[j].DrawElemSolid(PDI, ElemTM, VectorScale, PrimMaterial->GetRenderProxy(0));
				}

				if(!bHitTest)
				{
					if (CollisionViewMode == FPhATSharedData::PRM_Solid || CollisionViewMode == FPhATSharedData::PRM_Wireframe)
					{
						AggGeom->BoxElems[j].DrawElemWire(PDI, ElemTM, VectorScale, GetPrimitiveColor(i, KPT_Box, j));
					}
				}
				

				if (bHitTest) 
				{
					PDI->SetHitProxy(NULL);
				}
			}

			for (int32 j = 0; j <AggGeom->SphylElems.Num(); ++j)
			{
				if (bHitTest) 
				{
					PDI->SetHitProxy(new HPhATEdBoneProxy(i, KPT_Sphyl, j));
				}

				FTransform ElemTM = GetPrimitiveTransform(BoneTM, i, KPT_Sphyl, j, Scale);

				if ( (CollisionViewMode == FPhATSharedData::PRM_Solid && !bHitTest) || bHitTestAndBodyMode)
				{
					UMaterialInterface*	PrimMaterial = GetPrimitiveMaterial(i, KPT_Sphyl, j, bHitTestAndBodyMode);
					AggGeom->SphylElems[j].DrawElemSolid(PDI, ElemTM, VectorScale, PrimMaterial->GetRenderProxy(0));
				}

				if(!bHitTest)
				{
					if (CollisionViewMode == FPhATSharedData::PRM_Solid || CollisionViewMode == FPhATSharedData::PRM_Wireframe)
					{
						AggGeom->SphylElems[j].DrawElemWire(PDI, ElemTM, VectorScale, GetPrimitiveColor(i, KPT_Sphyl, j));
					}
				}

				if (bHitTest) 
				{
					PDI->SetHitProxy(NULL);
				}
			}

			for (int32 j = 0; j <AggGeom->ConvexElems.Num(); ++j)
			{
				if (bHitTest) 
				{
					PDI->SetHitProxy(new HPhATEdBoneProxy(i, KPT_Convex, j));
				}

				FTransform ElemTM = GetPrimitiveTransform(BoneTM, i, KPT_Convex, j, Scale);

				//convex doesn't have solid draw so render lines if we're in hitTestAndBodyMode
				if(!bHitTest || bHitTestAndBodyMode)
				{
					if (CollisionViewMode == FPhATSharedData::PRM_Solid || CollisionViewMode == FPhATSharedData::PRM_Wireframe)
					{
						AggGeom->ConvexElems[j].DrawElemWire(PDI, ElemTM, Scale, GetPrimitiveColor(i, KPT_Convex, j));
					}
				}
				

				if (bHitTest) 
				{
					PDI->SetHitProxy(NULL);
				}
			}

			if (!bHitTest && SharedData->bShowCOM && Bodies.IsValidIndex(i))
			{
				Bodies[i]->DrawCOMPosition(PDI, COMRenderSize, SharedData->COMRenderColor);
			}
		}
	}

	// Draw Constraints
	FPhATSharedData::EPhATConstraintViewMode ConstraintViewMode = SharedData->GetCurrentConstraintViewMode();
	if (ConstraintViewMode != FPhATSharedData::PCV_None)
	{
		for (int32 i = 0; i <PhysicsAsset->ConstraintSetup.Num(); ++i)
		{
			int32 BoneIndex1 = GetBoneIndex(PhysicsAsset->ConstraintSetup[i]->DefaultInstance.ConstraintBone1);
			int32 BoneIndex2 = GetBoneIndex(PhysicsAsset->ConstraintSetup[i]->DefaultInstance.ConstraintBone2);
			// if bone doesn't exist, do not draw it. It crashes in random points when we try to manipulate. 
			if (BoneIndex1 != INDEX_NONE && BoneIndex2 != INDEX_NONE)
			{
				if (bHitTest) 
				{
					PDI->SetHitProxy(new HPhATEdConstraintProxy(i));
				}

				if(bHitTestAndConstraintMode || !bHitTest)
				{
					DrawConstraint(i, View, PDI, SharedData->EditorSimOptions->bShowConstraintsAsPoints);
				}
					
				if (bHitTest) 
				{
					PDI->SetHitProxy(NULL);
				}
			}
		}
	}

	if (!bHitTest && SharedData->EditingMode == FPhATSharedData::PEM_BodyEdit && SharedData->bShowInfluences)
	{
		DrawCurrentInfluences(PDI);
	}

	// If desired, draw bone hierarchy.
	if (!bHitTest && SharedData->bShowHierarchy)
	{
		DrawHierarchy(PDI, false);
	}

	// If desired, draw animation skeleton.
	if (!bHitTest && SharedData->bShowAnimSkel)
	{
		DrawHierarchy(PDI, SharedData->bRunningSimulation);
	}
}
示例#19
0
bool GetBlendData(OutModel& model, aiMesh* mesh, PODVector<unsigned>& boneMappings, Vector<PODVector<unsigned char> >&
    blendIndices, Vector<PODVector<float> >& blendWeights, String& errorMessage, unsigned maxBones)
{
    blendIndices.Resize(mesh->mNumVertices);
    blendWeights.Resize(mesh->mNumVertices);
    boneMappings.Clear();

    // If model has more bones than can fit vertex shader parameters, write the per-geometry mappings
    if (model.bones_.Size() > maxBones)
    {
        if (mesh->mNumBones > maxBones)
        {
            errorMessage = "Geometry (submesh) has over " + String(maxBones) + " bone influences. Try splitting to more submeshes\n"
                "that each stay at " + String(maxBones) + " bones or below.";

            return false;
        }
        boneMappings.Resize(mesh->mNumBones);
        for (unsigned i = 0; i < mesh->mNumBones; ++i)
        {
            aiBone* bone = mesh->mBones[i];
            String boneName = FromAIString(bone->mName);
            unsigned globalIndex = GetBoneIndex(model, boneName);
            if (globalIndex == M_MAX_UNSIGNED)
            {
                errorMessage = "Bone " + boneName + " not found";
                return false;
            }
            boneMappings[i] = globalIndex;
            for (unsigned j = 0; j < bone->mNumWeights; ++j)
            {
                unsigned vertex = bone->mWeights[j].mVertexId;
                blendIndices[vertex].Push(i);
                blendWeights[vertex].Push(bone->mWeights[j].mWeight);
            }
        }
    }
    else
    {
        for (unsigned i = 0; i < mesh->mNumBones; ++i)
        {
            aiBone* bone = mesh->mBones[i];
            String boneName = FromAIString(bone->mName);
            unsigned globalIndex = GetBoneIndex(model, boneName);
            if (globalIndex == M_MAX_UNSIGNED)
            {
                errorMessage = "Bone " + boneName + " not found";
                return false;
            }

            for (unsigned j = 0; j < bone->mNumWeights; ++j)
            {
                unsigned vertex = bone->mWeights[j].mVertexId;
                blendIndices[vertex].Push(globalIndex);
                blendWeights[vertex].Push(bone->mWeights[j].mWeight);
            }
        }
    }

    // Normalize weights now if necessary, also remove too many influences
    for (unsigned i = 0; i < blendWeights.Size(); ++i)
    {
        if (blendWeights[i].Size() > 4)
        {
            PrintLine("Warning: more than 4 bone influences in vertex " + String(i));

            while (blendWeights[i].Size() > 4)
            {
                unsigned lowestIndex = 0;
                float lowest = M_INFINITY;
                for (unsigned j = 0; j < blendWeights[i].Size(); ++j)
                {
                    if (blendWeights[i][j] < lowest)
                    {
                        lowest = blendWeights[i][j];
                        lowestIndex = j;
                    }
                }
                blendWeights[i].Erase(lowestIndex);
                blendIndices[i].Erase(lowestIndex);
            }
        }

        float sum = 0.0f;
        for (unsigned j = 0; j < blendWeights[i].Size(); ++j)
            sum += blendWeights[i][j];
        if (sum != 1.0f && sum != 0.0f)
        {
            for (unsigned j = 0; j < blendWeights[i].Size(); ++j)
                blendWeights[i][j] /= sum;
        }
    }

    return true;
}