protected override void OnRebuild() { base.OnRebuild(); DestroyResources(); int width = processor.positionTexture.width; int height = processor.positionTexture.height; positionTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); positionTexture.filterMode = FilterMode.Point; positionTexture.Create(); velocityTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); velocityTexture.filterMode = FilterMode.Point; velocityTexture.Create(); float[] weights = processor.neoFurAsset.morphWeights; StringBuilder guideTextureKeySB = new StringBuilder(); guideTextureKeySB.Append(processor.baseResourceKey); guideTextureKeySB.Append("_"); guideTextureKeySB.Append(processor.neoFurAsset.data.guideMethod); guideTextureKeySB.Append("_"); if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Morphs) { for (int i = 0; i < weights.Length; i++) { guideTextureKeySB.Append(weights[i].ToString(CultureInfo.InvariantCulture)); if (i < weights.Length - 1) { guideTextureKeySB.Append("_"); } } } else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Splines) { if (processor.neoFurAsset.SplineGuideData == null) { guideTextureKeySB.Append("null"); } else { guideTextureKeySB.Append(processor.neoFurAsset.SplineGuideData.GetInstanceID().ToString()); } } guideTextureKeySB.Append("_PhysicsGuideTexture"); guideTextureResource = VertexProcessorCache.GetResource <Texture2D>(guideTextureKeySB.ToString()); if (guideTextureResource.value == null) { if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Normals) { DefaultToNormalGuides(); } else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Morphs) { UnpackedMesh mesh = processor.unpackedMeshResource.value; if (mesh.blendShapes.Count != weights.Length) { Debug.LogError("mesh.blendShapes.Count != weights.Length", processor.neoFurAsset.gameObject); DefaultToNormalGuides(); } else if (weights.Length > 0) { Color[] guideVectorColors = new Color[width * height]; for (int i = 0; i < weights.Length; i++) { float weight = weights[i] / 100.0f; if (weight == 0) { continue; } UnpackedMesh.BlendShape blendShape = mesh.blendShapes[i]; for (int j = 0; j < mesh.vertices.Length; j++) { Vector3 guideVector = blendShape.deltaVertices[j] * weight; guideVectorColors[j] += new Color(guideVector.x, guideVector.y, guideVector.z, 0); } } for (int i = 0; i < mesh.tangents.Length; i++) { Vector3 normal = mesh.normals[i]; Vector4 tangent = mesh.tangents[i]; Color guideVectorColor = guideVectorColors[i]; Vector3 guideVector = new Vector3(guideVectorColor.r, guideVectorColor.g, guideVectorColor.b); Vector3 binormal = Vector3.Cross(normal, tangent); Vector3 tangentSpaceGuide = VertexProcessorUtility.ToTangentSpace(guideVector, normal, binormal, tangent); guideVectorColors[i] = new Color(tangentSpaceGuide.x, tangentSpaceGuide.y, tangentSpaceGuide.z, 0); } guideTextureResource.value = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false); guideTextureResource.value.filterMode = FilterMode.Point; guideTextureResource.value.SetPixels(guideVectorColors); guideTextureResource.value.Apply(); } else { DefaultToNormalGuides(); } } else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Splines) { NeoFur.Data.PreComputedGuideData splineData = processor.neoFurAsset.SplineGuideData; if (splineData == null) { Debug.LogWarning("Guide mode set to Splines but no spline data file is loaded", processor.neoFurAsset.gameObject); DefaultToNormalGuides(); } else if (splineData.guides.Length == 0 || splineData.guides.Length != processor.unpackedMeshResource.value.vertices.Length) { Debug.Log("num guides = " + splineData.guides.Length + " num verts: " + width * height, processor.neoFurAsset.gameObject); Debug.LogError("Submesh for NFA does not match submesh for Spline Data Asset", processor.neoFurAsset.gameObject); DefaultToNormalGuides(); } else { UnpackedMesh mesh = processor.unpackedMeshResource.value; Color[] guideVectorColors = new Color[width * height]; for (int i = 0; i < splineData.guides.Length; i++) { Vector3 normal = mesh.normals[i]; Vector4 tangent = mesh.tangents[i]; int remappedIndex = processor.optimizedVertexMapResource.value[i]; Vector3 guideVector = splineData.guides[remappedIndex]; Vector3 binormal = Vector3.Cross(normal, tangent); Vector3 tangentSpaceGuide = VertexProcessorUtility.ToTangentSpace(guideVector, normal, binormal, tangent); guideVectorColors[i] = new Color(tangentSpaceGuide.x, tangentSpaceGuide.y, tangentSpaceGuide.z, 0); } guideTextureResource.value = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false); guideTextureResource.value.filterMode = FilterMode.Point; guideTextureResource.value.SetPixels(guideVectorColors); guideTextureResource.value.Apply(); } } } }
private void RebuildMorphTextures() { int blendShapeCount = processor.unpackedMeshResource.value.blendShapes.Count; if (blendShapeCount > 0) { if (bakedFurMorphResources == null || bakedFurMorphResources.Length != blendShapeCount) { bakedFurMorphResources = new VertexProcessorResource <BakedMorph> [blendShapeCount]; } int width = processor.positionTexture.width; int height = processor.positionTexture.height; int arrayLen = width * height; for (int i = 0; i < blendShapeCount; ++i) { VertexProcessorResource <BakedMorph> morphResource = bakedFurMorphResources[i]; if (morphResource == null) { morphResource = VertexProcessorCache.GetResource <BakedMorph>(processor.baseResourceKey + "_BakedMorph_" + i); bakedFurMorphResources[i] = morphResource; } if (morphResource.value == null) { morphResource.value = new BakedMorph(); UnpackedMesh.BlendShape blendShape = processor.unpackedMeshResource.value.blendShapes[i]; if (_tempMorphPosColors == null || _tempMorphPosColors.Length != arrayLen) { _tempMorphPosColors = new Color[arrayLen]; _tempMorphNormColors = new Color[arrayLen]; _tempMorphTanColors = new Color[arrayLen]; } // initialize the baked blend shapes morphResource.value.Init(width, height, VertexProcessorUtility.float4TextureFormat); // bake the data for (int j = 0; j < blendShape.deltaVertices.Length; ++j) { Vector3 pos = blendShape.deltaVertices[j]; Vector3 norm = blendShape.deltaNormals[j]; Vector3 tan = blendShape.deltaTangents[j]; int y = j / width; int x = j % width; _tempMorphPosColors[morphResource.value.positionOffsetTexture.width * y + x] = new Color(pos.x, pos.y, pos.z, 1); _tempMorphNormColors[morphResource.value.normalOffsetTexture.width * y + x] = new Color(norm.x, norm.y, norm.z, 1); _tempMorphTanColors[morphResource.value.tangentOffsetTexture.width * y + x] = new Color(tan.x, tan.y, tan.z, 1); } morphResource.value.positionOffsetTexture.SetPixels(_tempMorphPosColors); morphResource.value.normalOffsetTexture.SetPixels(_tempMorphNormColors); morphResource.value.tangentOffsetTexture.SetPixels(_tempMorphTanColors); // apply changes to the textures morphResource.value.positionOffsetTexture.Apply(); morphResource.value.normalOffsetTexture.Apply(); morphResource.value.tangentOffsetTexture.Apply(); } } } }