예제 #1
0
    // Generate the terrain vertices and their respective biomes
    void GenerateTerrain()
    {
        // Determine number of tiles in a row
        int numTiles = chunkSize / tileSize;

        // Initialize a position vector
        Vector3 pos = new Vector3();

        // Loop through all grid tiles plus 3 extra. 2 on the borders (which overlap with other chunk) to calculate normals from.
        // And one extra to get the desired number of tiles from vertices. (numTiles = numVertex + 1)
        for (int i = 0; i < numTiles + 3; i++)
        {
            for (int k = 0; k < numTiles + 3; k++)
            {
                // Set the position vector to the the position of the current vertex
                pos.Set((i - 1) * tileSize, 0, (k - 1) * tileSize);
                float r = Vector3.Magnitude(pos + transform.position - terrain.middlePoint);

                // In case the flat area surrounded by mountains options is activated
                if (terrain.isSourroundedByMountains)
                {
                    if (Mathf.Abs(r) > terrain.flatRadius || Mathf.Abs(r) > terrain.flatRadius)
                    {
                        map[i, k] = GenerateTerrainMap(i, k, pos);

                        map[i, k].y *= (-(Mathf.Cos(Mathf.PI / (terrain.width / 2f) * (r - terrain.flatRadius))) + 1) / 2;
                    }
                    else
                    {
                        map[i, k] = pos;
                    }
                }
                // In other cases
                else
                {
                    // Generate the height and biome of the vertex, depending on its horizontal position.
                    map[i, k] = GenerateTerrainMap(i, k, pos);

                    if (terrain.isIsland)
                    {
                        map[i, k] += new Vector3(0, -terrain.islandSteepness * r * r + terrain.baseHeight + terrain.waterLevel, 0);
                    }

                    else if (terrain.isCoastLine)
                    {
                        map[i, k].y -= Mathf.Sin(Mathf.PI / (terrain.width * 2) * (pos.x + transform.position.x)) * (pos.x + transform.position.x) * terrain.coastSteepness - terrain.coastBaseHeight;
                    }
                }

                biomeMap[i, k] = GenerateBiomes(i, k, pos);
                if (terrain.isCoastLine)
                {
                    biomeMap[i, k] *= Mathf.Pow(Mathf.Cos(Mathf.PI / (terrain.width * 2) * (pos.x + transform.position.x)), 5) * 2;
                    biomeMap[i, k]  = Mathf.Clamp(biomeMap[i, k], 0.1f, terrain.biomes.Length - 0.5f);
                }
            }
        }
        tempMap = (Vector3[, ])map.Clone();
    }
예제 #2
0
 public PoseDataFrame(Vector3[,] ufp, Vector3[] ugp, FingerShape[,] ufs, HandShape[] uhs, Vector3[] vel, Vector3[] accel)
 {
     FingerPosition   = ufp.Clone() as Vector3[, ];
     GripPosition     = ugp.Clone() as Vector3[];
     FingerShape      = ufs.Clone() as FingerShape[, ];
     HandShape        = uhs.Clone() as HandShape[];
     HandVelocity     = vel.Clone() as Vector3[];
     HandAcceleration = accel.Clone() as Vector3[];
 }
예제 #3
0
    ///<summary>
    /// Modifie la mesh de l'objet courant. Cette mesh correspond à une déformation d'impact autour d'un epicentre.
    /// La nouvelle mesh est constitués des points fourni par la fonction appelante et connecte ces derniers avec des triangles générés itérativement.
    /// Les normales a ses triangles sont par ailleurs calculée pour que l'objet reste compatible avec l'éclairage de la scène.
    ///</summary>
    private void DeformSurface(Vector3 worldSpaceEpiCenter_, Vector3[,] impactSideVertices_, Vector3[,] oppositeSideVertices_, int currentMeshID_, MeshFilter mf_)
    {
        Vector3[,] impactSideVertices   = impactSideVertices_.Clone() as Vector3[, ];
        Vector3[,] oppositeSideVertices = oppositeSideVertices_.Clone() as Vector3[, ];

        Vector3 localCollision = this.transform.worldToLocalMatrix.MultiplyPoint3x4(worldSpaceEpiCenter_);

        (Vector3 localisedEpicenter, Vector3 oppositeSideEpicenter, bool areImpactPointsReversed) = this.getOppositeSideVertex(localCollision, impactSideVertices[0, this.addedTangentSplit], oppositeSideVertices[0, this.addedTangentSplit]);

        Vector3 impactDirection = this.transform.InverseTransformDirection(Vector3.Normalize(this.transform.TransformPoint(oppositeSideEpicenter) - this.transform.TransformPoint(localisedEpicenter)));

        Vector3 getOffset(float distanceFromImpact_)
        {
            if (distanceFromImpact_ < this.deformRadius)
            {
                float   deformationFactor = 1 - (distanceFromImpact_ / this.deformRadius) * this.deformFalloff;
                Vector3 deformation;
                if (areImpactPointsReversed)
                {
                    deformation = deformationFactor * oppositeSideEpicenter;
                }
                else
                {
                    deformation = deformationFactor * localisedEpicenter;
                }
                return(Vector3.Scale(impactDirection, deformation) * this.deformMultiplier);
            }
            else
            {
                return(new Vector3(0, 0, 0));
            }
        }

        for (int obliqueIndex = 0; obliqueIndex < impactSideVertices.GetLength(0); obliqueIndex++)
        {
            for (int tangentIndex = 0; tangentIndex < impactSideVertices.GetLength(1); tangentIndex++)
            {
                float distanceFromImpact = Vector3.Distance(impactSideVertices[obliqueIndex, tangentIndex], localisedEpicenter);

                impactSideVertices[obliqueIndex, tangentIndex]   -= getOffset(distanceFromImpact);
                oppositeSideVertices[obliqueIndex, tangentIndex] -= getOffset(distanceFromImpact);
            }
        }

        IEnumerable <int> getFrontTopRightBottomLeft()
        {
            int o = impactSideVertices.GetLength(0);
            int t = impactSideVertices.GetLength(1);

            //sens normal
            for (int obliqueIndex = 0; obliqueIndex < o; obliqueIndex++)
            {
                for (int tangentIndex = 0; tangentIndex < t; tangentIndex++)
                {
                    int index = (obliqueIndex * t) + tangentIndex;
                    if (tangentIndex == t - 1)
                    {
                        //extremité face avant ==> face avant à 4 côtés + face lattérale
                        yield return(index);

                        yield return((index + t) % (t * o));

                        yield return(((index + t) % (t * o)) + (t * o));

                        yield return(((index + t) % (t * o)) + (t * o));

                        yield return(((index) % (t * o)) + (t * o));

                        yield return(index);

                        if (tangentIndex == 0 && obliqueIndex % (o / 2) == 0)
                        {
                            foreach (var item in new int[] { t *(o / 2), t *(o / 4), 0 })
                            {
                                yield return((index + item) % (t * o));
                            }
                        }
                        else
                        {
                            foreach (var item in new int[] { 0, -1, t - 1, t - 1, t, 0 })
                            {
                                yield return((index + item) % (t * o));
                            }
                        }
                    }
                    else if (tangentIndex == 0)
                    {
                        //Intérieur face avant à trois coté, autour de l'épicentre avant
                        yield return(t * o * 2);

                        yield return((index + t) % (t * o));

                        yield return(index);
                    }
                    else
                    {
                        //milieu face avant à 4 côtés
                        foreach (var item in new int[] { 0, -1, t - 1, t - 1, t, 0 })
                        {
                            yield return((index + item) % (t * o));
                        }
                    }
                }
            }
        }

        IEnumerable <int> getBack()
        {
            int o = impactSideVertices.GetLength(0);
            int t = impactSideVertices.GetLength(1);

            //sens inverse
            for (int obliqueIndex = 0; obliqueIndex < o; obliqueIndex++)
            {
                for (int tangentIndex = 0; tangentIndex < t; tangentIndex++)
                {
                    int index = (t * o) + (obliqueIndex * t) + tangentIndex;
                    if (tangentIndex == 0)
                    {
                        //Intérieur face avant à trois coté, autour de l'épicentre arrière
                        yield return(index);

                        yield return(((index + t) % (t * o)) + (t * o));

                        yield return((t * o * 2) + 1);
                    }
                    else
                    {
                        //milieu face avant à 4 côtés
                        foreach (var item in new int[] { 0, t, t - 1, t - 1, -1, 0 })
                        {
                            yield return(((index + item) % (t * o)) + (t * o));
                        }
                    }
                }
            }
        }

        Mesh newMesh = new Mesh();

        //localisedEpicenter et oppositeSideEpicenter sont ajouté dans le newMesh.vertices mais pas dans impactSideVertices et oppositeSideVertices pour simplifier la logique des index
        newMesh.vertices = this.Flatten(impactSideVertices)
                           .Concat(this.Flatten(oppositeSideVertices))
                           .Append(localisedEpicenter - getOffset(0))
                           .Append(oppositeSideEpicenter - getOffset(0))
                           .ToArray();

        newMesh.triangles = getFrontTopRightBottomLeft().Concat(getBack()).ToArray();
        newMesh.RecalculateNormals();
        mf_.mesh = newMesh;
    }