Ejemplo n.º 1
0
    /**
     *  Generates a morph that moves each vertex from the surface of the parent to its base position. Intended to be used to "turn on" grafts.
     */
    public MorphRecipe GenerateGraftControlMorph(string channel, int childVertexOffset, GeometryRecipe childGeometry)
    {
        var childVertexPositions = childGeometry.VertexPositions;

        MorphDelta[] deltas = new MorphDelta[childVertexPositions.Length];
        for (int childVertexIdx = 0; childVertexIdx < childVertexPositions.Length; ++childVertexIdx)
        {
            var positionDelta = childVertexPositions[childVertexIdx] - ParentSurfacePositions[childVertexIdx];
            deltas[childVertexIdx] = new MorphDelta(childVertexIdx + childVertexOffset, positionDelta);
        }

        return(new MorphRecipe {
            Channel = channel,
            Deltas = deltas
        });
    }
Ejemplo n.º 2
0
    public void ImportFrom(DsonTypes.Modifier modifier)
    {
        DsonTypes.Morph dsonMorph = modifier.morph;
        if (dsonMorph == null)
        {
            return;
        }

        float[][] dsonDeltas = dsonMorph.deltas?.values;
        if (dsonDeltas == null || dsonDeltas.Length == 0)
        {
            return;
        }

        if (modifier.channel.id != "value")
        {
            throw new InvalidOperationException("expected channel id to be 'value'");
        }
        string channel = modifier.name + "?value";

        int deltaCount = dsonDeltas.Length;

        MorphDelta[] deltas = new MorphDelta[deltaCount];
        for (int i = 0; i < deltaCount; ++i)
        {
            float[] dsonDelta      = dsonDeltas[i];
            int     vertexIdx      = (int)dsonDelta[0];
            Vector3 positionOffset = new Vector3(dsonDelta[1], dsonDelta[2], dsonDelta[3]);
            deltas[i] = new MorphDelta(vertexIdx, positionOffset);
        }

        var hdUrl = ExtractHdUrl(dsonMorph.hd_url);

        MorphRecipe recipe = new MorphRecipe {
            Channel = channel,
            Deltas  = deltas,
            HdUrl   = hdUrl
        };

        morphRecipes.Add(recipe);
    }
Ejemplo n.º 3
0
    void GrabMeshFromSkinnedMeshRenderer()
    {
        this.ReleaseBuffers();

        this.mf.mesh   = this.smr.sharedMesh;
        this.bindPoses = this.mf.mesh.bindposes;

        this.arrBufMorphDeltas = new ComputeBuffer[this.mf.mesh.blendShapeCount];

        this.morphWeights = new float[this.mf.mesh.blendShapeCount];

        var deltaVertices = new Vector3[this.mf.mesh.vertexCount];
        var deltaNormals  = new Vector3[this.mf.mesh.vertexCount];
        var deltaTangents = new Vector3[this.mf.mesh.vertexCount];

        var deltaVertInfos = new MorphDelta[this.mf.mesh.vertexCount];

        for (int i = 0; i < this.mf.mesh.blendShapeCount; i++)
        {
            this.mf.mesh.GetBlendShapeFrameVertices(i, 0, deltaVertices, deltaNormals, deltaTangents);

            this.arrBufMorphDeltas[i] = new ComputeBuffer(this.mf.mesh.vertexCount, sizeof(float) * 12);

            for (int k = 0; k < this.mf.mesh.vertexCount; k++)
            {
                deltaVertInfos[k].position = deltaVertices != null ? deltaVertices[k]      : Vector3.zero;
                deltaVertInfos[k].normal   = deltaNormals != null ? deltaNormals[k]       : Vector3.zero;
                deltaVertInfos[k].tangent  = deltaTangents != null ? deltaTangents[k]      : Vector3.zero;
            }

            this.arrBufMorphDeltas[i].SetData(deltaVertInfos);
        }

        Material[] materials = this.smr.sharedMaterials;
        for (int i = 0; i < materials.Length; i++)
        {
            materials[i].SetInt("_DoSkinning", 1);
        }
        this.mr.materials = materials;

        this.shaderDQBlend.SetInt("textureWidth", textureWidth);

        this.poseMatrices = new Matrix4x4[this.mf.mesh.bindposes.Length];

        // initiate textures and buffers

        int textureHeight = this.mf.mesh.vertexCount / textureWidth;

        if (this.mf.mesh.vertexCount % textureWidth != 0)
        {
            textureHeight++;
        }

        this.rtSkinnedData_1 = new RenderTexture(textureWidth, textureHeight, 0, RenderTextureFormat.ARGBFloat)
        {
            filterMode        = FilterMode.Point,
            enableRandomWrite = true
        };
        this.rtSkinnedData_1.Create();
        this.shaderDQBlend.SetTexture(this.kernelHandleDQBlend, "skinned_data_1", this.rtSkinnedData_1);

        this.rtSkinnedData_2 = new RenderTexture(textureWidth, textureHeight, 0, RenderTextureFormat.ARGBFloat)
        {
            filterMode        = FilterMode.Point,
            enableRandomWrite = true
        };
        this.rtSkinnedData_2.Create();
        this.shaderDQBlend.SetTexture(this.kernelHandleDQBlend, "skinned_data_2", this.rtSkinnedData_2);

        this.rtSkinnedData_3 = new RenderTexture(textureWidth, textureHeight, 0, RenderTextureFormat.RGFloat)
        {
            filterMode        = FilterMode.Point,
            enableRandomWrite = true
        };
        this.rtSkinnedData_3.Create();
        this.shaderDQBlend.SetTexture(this.kernelHandleDQBlend, "skinned_data_3", this.rtSkinnedData_3);

        this.bufPoseMatrices = new ComputeBuffer(this.mf.mesh.bindposes.Length, sizeof(float) * 16);
        this.shaderComputeBoneDQ.SetBuffer(this.kernelHandleComputeBoneDQ, "pose_matrices", this.bufPoseMatrices);

        this.bufSkinnedDq = new ComputeBuffer(this.mf.mesh.bindposes.Length, sizeof(float) * 8);
        this.shaderComputeBoneDQ.SetBuffer(this.kernelHandleComputeBoneDQ, "skinned_dual_quaternions", this.bufSkinnedDq);
        this.shaderDQBlend.SetBuffer(this.kernelHandleDQBlend, "skinned_dual_quaternions", this.bufSkinnedDq);

        this.bufBoneDirections = new ComputeBuffer(this.mf.mesh.bindposes.Length, sizeof(float) * 4);
        this.shaderComputeBoneDQ.SetBuffer(this.kernelHandleComputeBoneDQ, "bone_directions", this.bufBoneDirections);
        this.shaderDQBlend.SetBuffer(this.kernelHandleDQBlend, "bone_directions", this.bufBoneDirections);

        this.bufVertInfo = new ComputeBuffer(this.mf.mesh.vertexCount, sizeof(float) * 16 + sizeof(int) * 4 + sizeof(float));
        var vertInfos = new VertexInfo[this.mf.mesh.vertexCount];

        Vector3[]    vertices    = this.mf.mesh.vertices;
        Vector3[]    normals     = this.mf.mesh.normals;
        Vector4[]    tangents    = this.mf.mesh.tangents;
        BoneWeight[] boneWeights = this.mf.mesh.boneWeights;
        for (int i = 0; i < vertInfos.Length; i++)
        {
            vertInfos[i].position = vertices[i];

            vertInfos[i].boneIndex0 = boneWeights[i].boneIndex0;
            vertInfos[i].boneIndex1 = boneWeights[i].boneIndex1;
            vertInfos[i].boneIndex2 = boneWeights[i].boneIndex2;
            vertInfos[i].boneIndex3 = boneWeights[i].boneIndex3;

            vertInfos[i].weight0 = boneWeights[i].weight0;
            vertInfos[i].weight1 = boneWeights[i].weight1;
            vertInfos[i].weight2 = boneWeights[i].weight2;
            vertInfos[i].weight3 = boneWeights[i].weight3;

            // determine per-vertex compensation coef

            Matrix4x4  bindPose         = this.bindPoses[vertInfos[i].boneIndex0].inverse;
            Quaternion boneBindRotation = bindPose.ExtractRotation();
            Vector3    boneDirection    = boneBindRotation * this.boneOrientationVector;        // ToDo figure out bone orientation
            Vector3    bonePosition     = bindPose.ExtractPosition();
            Vector3    toBone           = bonePosition - (Vector3)vertInfos[i].position;

            vertInfos[i].compensation_coef = Vector3.Cross(toBone, boneDirection).magnitude;
        }

        if (normals.Length > 0)
        {
            for (int i = 0; i < vertInfos.Length; i++)
            {
                vertInfos[i].normal = normals[i];
            }
        }

        if (tangents.Length > 0)
        {
            for (int i = 0; i < vertInfos.Length; i++)
            {
                vertInfos[i].tangent = tangents[i];
            }
        }

        this.bufVertInfo.SetData(vertInfos);
        this.shaderDQBlend.SetBuffer(this.kernelHandleDQBlend, "vertex_infos", this.bufVertInfo);

        this.bufMorphTemp_1 = new ComputeBuffer(this.mf.mesh.vertexCount, sizeof(float) * 16 + sizeof(int) * 4);
        this.bufMorphTemp_2 = new ComputeBuffer(this.mf.mesh.vertexCount, sizeof(float) * 16 + sizeof(int) * 4);

        // bind DQ buffer

        Matrix4x4[] bindPoses = this.mf.mesh.bindposes;
        var         bindDqs   = new DualQuaternion[bindPoses.Length];

        for (int i = 0; i < bindPoses.Length; i++)
        {
            bindDqs[i].rotationQuaternion = bindPoses[i].ExtractRotation();
            bindDqs[i].position           = bindPoses[i].ExtractPosition();
        }

        this.bufBindDq = new ComputeBuffer(bindDqs.Length, sizeof(float) * 8);
        this.bufBindDq.SetData(bindDqs);
        this.shaderComputeBoneDQ.SetBuffer(this.kernelHandleComputeBoneDQ, "bind_dual_quaternions", this.bufBindDq);

        this.UpdateViewFrustrumCulling();
        this.ApplyMorphs();
    }