示例#1
0
        private void FreeTextures()
        {
            if (boneIndexTextureResource != null)
            {
                VertexProcessorCache.ReleaseResource(boneIndexTextureResource);
                boneIndexTextureResource = null;
            }
            if (boneWeightTextureResource != null)
            {
                VertexProcessorCache.ReleaseResource(boneWeightTextureResource);
                boneWeightTextureResource = null;
            }
            if (boneMatrixTexture)
            {
                Object.DestroyImmediate(boneMatrixTexture);
            }

            if (bakedFurMorphResources != null)
            {
                for (int i = 0; i < bakedFurMorphResources.Length; ++i)
                {
                    VertexProcessorCache.ReleaseResource(bakedFurMorphResources[i]);
                }
                bakedFurMorphResources = null;
            }
        }
示例#2
0
 private void DestroyResources()
 {
     if (positionTexture)
     {
         Object.DestroyImmediate(positionTexture);
     }
     if (velocityTexture)
     {
         Object.DestroyImmediate(velocityTexture);
     }
     if (guideTextureResource != null)
     {
         VertexProcessorCache.ReleaseResource(guideTextureResource);
         guideTextureResource = null;
     }
 }
示例#3
0
        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();
                    }
                }
            }
        }
示例#4
0
        private void RebuildBoneWeightTextures()
        {
            bones = processor.neoFurAsset.skinnedMeshRenderer.bones;

            // remake bone matrix texture
            bindPoses = processor.unpackedMeshResource.value.bindposes;
            boneMaterial.SetFloat("_NumBindPoses", bindPoses.Length);

            boneMatrixTexture            = new Texture2D(4, bindPoses.Length, VertexProcessorUtility.float4TextureFormat, false);
            boneMatrixTexture.filterMode = FilterMode.Point;

            // remake bone weights textures
            BoneWeight[] boneWeights = processor.unpackedMeshResource.value.boneWeights;

            int width  = processor.positionTexture.width;
            int height = processor.positionTexture.height;

            boneWeightTextureResource = VertexProcessorCache.GetResource <Texture2D>(processor.baseResourceKey + "_BoneWeightTexture");
            if (boneWeightTextureResource.value == null)
            {
                boneWeightTextureResource.value            = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false);
                boneWeightTextureResource.value.filterMode = FilterMode.Point;
            }

            boneIndexTextureResource = VertexProcessorCache.GetResource <Texture2D>(processor.baseResourceKey + "_BoneIndexTexture");
            if (boneIndexTextureResource.value == null)
            {
                boneIndexTextureResource.value            = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false);
                boneIndexTextureResource.value.filterMode = FilterMode.Point;
            }

            if (boneWeights == null || boneWeights.Length <= 0)
            {
                Debug.LogError("NeoFur: Using a (Growth) Mesh that does not have any bind poses or bone weights. Please use a MeshRenderer instead or import a (Growth) Mesh with bind poses/bone weights (using the same rig as the display skinned mesh renderer)." +
                               processor.neoFurAsset.gameObject.name,
                               processor.neoFurAsset.gameObject);
            }
            else
            {
                if (boneIndexColors == null || boneIndexColors.Length != boneWeights.Length)
                {
                    boneIndexColors = new Color[boneIndexTextureResource.value.width * boneIndexTextureResource.value.height];
                }

                if (boneWeightColors == null || boneWeightColors.Length != boneWeights.Length)
                {
                    boneWeightColors = new Color[boneWeightTextureResource.value.width * boneWeightTextureResource.value.height];
                }

                // rebuild bone weight textures (indices + weights)
                for (int i = 0; i < boneWeights.Length; ++i)
                {
                    int y = i / width;
                    int x = i % width;

                    BoneWeight bw = boneWeights[i];

                    boneIndexColors[boneIndexTextureResource.value.width * y + x]   = new Color(bw.boneIndex0, bw.boneIndex1, bw.boneIndex2, bw.boneIndex3);
                    boneWeightColors[boneWeightTextureResource.value.width * y + x] = new Color(bw.weight0, bw.weight1, bw.weight2, bw.weight3);
                }

                boneIndexTextureResource.value.SetPixels(boneIndexColors);
                boneWeightTextureResource.value.SetPixels(boneWeightColors);

                boneIndexTextureResource.value.Apply();
                boneWeightTextureResource.value.Apply();
            }

            // set material bone textures
            boneMaterial.SetTexture("_NeoFur_BoneIndexTexture", boneIndexTextureResource.value);
            boneMaterial.SetTexture("_NeoFur_BoneWeightTexture", boneWeightTextureResource.value);
        }
示例#5
0
        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();
                    }
                }
            }
        }