void UDebugSkelMeshComponent::SetShowBoneWeight(bool bNewShowBoneWeight) { // Check we are actually changing it! if(bNewShowBoneWeight == bDrawBoneInfluences) { return; } // if turning on this mode if(bNewShowBoneWeight) { SkelMaterials.Empty(); int32 NumMaterials = GetNumMaterials(); for (int32 i=0; i<NumMaterials; i++) { // Back up old material SkelMaterials.Add(GetMaterial(i)); // Set special bone weight material SetMaterial(i, GEngine->BoneWeightMaterial); } } // if turning it off else { int32 NumMaterials = GetNumMaterials(); check(NumMaterials == SkelMaterials.Num()); for (int32 i=0; i<NumMaterials; i++) { // restore original material SetMaterial(i, SkelMaterials[i]); } } bDrawBoneInfluences = bNewShowBoneWeight; }
void UMeshComponent::GetUsedMaterials(TArray<UMaterialInterface*>& OutMaterials) const { for (int32 ElementIndex = 0; ElementIndex < GetNumMaterials(); ElementIndex++) { if (UMaterialInterface* MaterialInterface = GetMaterial(ElementIndex)) { OutMaterials.Add(MaterialInterface); } } }
bool FComponentEditorUtils::AttemptApplyMaterialToComponent(USceneComponent* SceneComponent, UMaterialInterface* MaterialToApply, int32 OptionalMaterialSlot) { bool bResult = false; auto MeshComponent = Cast<UMeshComponent>(SceneComponent); auto DecalComponent = Cast<UDecalComponent>(SceneComponent); UMaterial* BaseMaterial = MaterialToApply->GetBaseMaterial(); bool bCanApplyToComponent = DecalComponent || ( MeshComponent && BaseMaterial && BaseMaterial->MaterialDomain != MD_DeferredDecal && BaseMaterial->MaterialDomain != MD_UI ); // We can only apply a material to a mesh or a decal if (bCanApplyToComponent && (MeshComponent || DecalComponent) ) { bResult = true; const FScopedTransaction Transaction(LOCTEXT("DropTarget_UndoSetComponentMaterial", "Assign Material to Component (Drag and Drop)")); SceneComponent->Modify(); if (MeshComponent) { // OK, we need to figure out how many material slots this mesh component/static mesh has. // Start with the actor's material count, then drill into the static/skeletal mesh to make sure // we have the right total. int32 MaterialCount = FMath::Max(MeshComponent->OverrideMaterials.Num(), MeshComponent->GetNumMaterials()); // Do we have an overridable material at the appropriate slot? if (MaterialCount > 0 && OptionalMaterialSlot < MaterialCount) { if (OptionalMaterialSlot == -1) { // Apply the material to every slot. for (int32 CurMaterialIndex = 0; CurMaterialIndex < MaterialCount; ++CurMaterialIndex) { MeshComponent->SetMaterial(CurMaterialIndex, MaterialToApply); } } else { // Apply only to the indicated slot. MeshComponent->SetMaterial(OptionalMaterialSlot, MaterialToApply); } } } else { DecalComponent->SetMaterial(0, MaterialToApply); } SceneComponent->MarkRenderStateDirty(); } return bResult; }
FMaterialRelevance UMeshComponent::GetMaterialRelevance(ERHIFeatureLevel::Type InFeatureLevel) const { // Combine the material relevance for all materials. FMaterialRelevance Result; for(int32 ElementIndex = 0;ElementIndex < GetNumMaterials();ElementIndex++) { UMaterialInterface const* MaterialInterface = GetMaterial(ElementIndex); if(!MaterialInterface) { MaterialInterface = UMaterial::GetDefaultMaterial(MD_Surface); } Result |= MaterialInterface->GetRelevance_Concurrent(InFeatureLevel); } return Result; }
/// \brief /// Creates a new material and returns a reference to it (same as implicitly adding a new material) /// /// \return /// Reference to newly added material inline VGMaterial& CreateMaterial() { m_materials.Add(new VGMaterial()); return GetMaterial(GetNumMaterials()-1); }
size_t CToy::GetNumSceneAreas() { if (!m_pBase) return 0; size_t iSceneTable = TOY_HEADER_SIZE+BASE_AABB_SIZE+BASE_AABB_SIZE+BASE_MATERIAL_TABLE_SIZE+GetNumMaterials()*BASE_MATERIAL_TABLE_STRIDE; return (int)*((uint32_t*)(m_pBase+iSceneTable)); }
char* CToy::GetSceneArea(size_t i) { TAssert(m_pArea); if (!m_pArea) return nullptr; size_t iSceneTable = TOY_HEADER_SIZE+BASE_AABB_SIZE+BASE_AABB_SIZE+BASE_MATERIAL_TABLE_SIZE+GetNumMaterials()*BASE_MATERIAL_TABLE_STRIDE+BASE_SCENE_TABLE_SIZE; size_t iSceneTableEntry = iSceneTable+i*AREA_VISIBLE_AREAS_STRIDE; size_t iSceneOffset = (size_t)*((uint32_t*)(m_pBase+iSceneTableEntry)); return m_pArea+iSceneOffset; }
void USkeletalMeshComponent::TickAnimation(float DeltaTime) { SCOPE_CYCLE_COUNTER(STAT_AnimTickTime); if (SkeletalMesh != NULL) { if (AnimScriptInstance != NULL) { // Tick the animation AnimScriptInstance->UpdateAnimation(DeltaTime * GlobalAnimRateScale); // TODO @LinaH - I've hit access violations due to AnimScriptInstance being NULL after this, probably due to // AnimNotifies? Please take a look and fix as we discussed. Temporary fix: if (AnimScriptInstance != NULL) { // now all tick/trigger/kismet is done // add MorphTarget Curves from Kismet driven or any other source // and overwrite if it exists // Tick always should maintain this list, not Evaluate for( auto Iter = MorphTargetCurves.CreateConstIterator(); Iter; ++Iter ) { float *CurveValPtr = AnimScriptInstance->MorphTargetCurves.Find(Iter.Key()); if ( CurveValPtr ) { // override the value if Kismet request was made *CurveValPtr = Iter.Value(); } else { AnimScriptInstance->MorphTargetCurves.Add(Iter.Key(), Iter.Value()); } } //Update material parameters if(AnimScriptInstance->MaterialParameterCurves.Num() > 0) { for( auto Iter = AnimScriptInstance->MaterialParameterCurves.CreateConstIterator(); Iter; ++Iter ) { FName ParameterName = Iter.Key(); float ParameterValue = Iter.Value(); for(int32 MaterialIndex = 0; MaterialIndex < GetNumMaterials(); ++MaterialIndex) { UMaterialInterface* MaterialInterface = GetMaterial(MaterialIndex); if (MaterialInterface) { float TestValue; //not used but needed for GetScalarParameterValue call if(MaterialInterface->GetScalarParameterValue(ParameterName,TestValue)) { UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface); if(!DynamicMaterial) //Is it already a UMaterialInstanceDynamic (ie we used it last tick) { DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex); } DynamicMaterial->SetScalarParameterValue(ParameterName, ParameterValue); //Assume that we only set the parameter on one of the materials, remove this break //if that is no longer desired break; } } } } } } } } }