Beispiel #1
0
        public static void DuplicateSelected()
        {
            IEnumerable <GameObject> selectedObjs = Selection.GetFiltered(typeof(GameObject),
                                                                          SelectionMode.Editable |
                                                                          SelectionMode.TopLevel |
                                                                          SelectionMode.ExcludePrefab).Cast <GameObject>();

            List <GameObject> newObjs = new List <GameObject>();

            foreach (GameObject go in selectedObjs)
            {
                TreeCurve tc = go.GetComponent <TreeCurve>();
                if (tc == null)
                {
                    Debug.LogWarning("Selected object \"" + go.name + "\" isn't a tree and was ignored.");
                    continue;
                }

                Transform tr = go.transform;

                GameObject go2 = GameObject.Instantiate <GameObject>(go);
                go2.name = go.name + " 2";
                newObjs.Add(go2);

                Transform tr2 = go2.transform;
                tr2.position   = tr.position;
                tr2.rotation   = tr.rotation;
                tr2.localScale = tr.localScale;

                //Remove the reference to the original object's trunk/foliage meshes.
                foreach (TreeCurve tc2 in go2.GetComponentsInChildren <TreeCurve>().ToArray())
                {
                    tc2.GetComponent <MeshFilter>().sharedMesh = null;
                    tc2.OnValidate();
                }
                foreach (CurveFoliage cf in go2.GetComponentsInChildren <CurveFoliage>().ToArray())
                {
                    cf.GetComponent <MeshFilter>().sharedMesh = null;
                    cf.OnValidate();
                }
            }

            //Select the duplicates.
            Selection.objects = newObjs.ToArray();
        }
Beispiel #2
0
        /// <summary>
        /// Re-generates the foliage mesh.
        /// </summary>
        public void OnValidate()
        {
            //Make sure inputs are sane.
            VerticalAngle         = Mathf.Clamp01(VerticalAngle);
            VerticalAngleVariance = Mathf.Max(0.0f, VerticalAngleVariance);
            MinPieces             = Mathf.Max(MinPieces, 0);
            MaxPieces             = Mathf.Max(MaxPieces, MinPieces);
            SpawnDistribution     = Mathf.Max(0.00001f, SpawnDistribution);
            MinSpawnLength        = Mathf.Clamp01(MinSpawnLength);
            MinSize = Mathf.Max(0.0f, MinSize);
            MaxSize = Mathf.Max(MinSize, MaxSize);


            if (myMF == null)
            {
                myMF = GetComponent <MeshFilter>();
            }

            TreeCurve tc = transform.parent.GetComponent <TreeCurve>();

            Vector3[] preC = tc.Curve.PreCalculateValues();

            Rand.seed = Seed;


            //Calculate the position, normal/tangent, and size of each foliage quad.

            List <Piece> pieces = new List <Piece>();

            int nPieces = Rand.Range(MinPieces, MaxPieces);

            pieces.Capacity = nPieces;

            for (int i = 0; i < nPieces; ++i)
            {
                float t = Mathf.Lerp(MinSpawnLength, 1.0f,
                                     Mathf.Pow(Rand.value, SpawnDistribution));
                var posAndDerivative = tc.Curve.GetValueAndDerivative(t, preC);
                posAndDerivative.Derivative.Normalize();
                Vector3 perp = posAndDerivative.Perpendicular.normalized;

                float   sizeF = Rand.Range(MinSize, MaxSize);
                Vector2 size  = new Vector2(sizeF, sizeF);

                Vector3 curveNormal = Quaternion.AngleAxis(Rand.Range(5.0f, 355.0f),
                                                           posAndDerivative.Derivative) * perp;
                curveNormal = new Vector3(curveNormal.x, 0.0f, curveNormal.z).normalized;

                Piece p = new Piece();
                p.Pos    = posAndDerivative.Value + (size.y * 0.5f * curveNormal);
                p.Normal = Vector3.Cross(curveNormal, new Vector3(0.0f, 1.0f, 0.0f)).normalized;
                float angle = Mathf.Lerp(-90.0f, 90.0f,
                                         VerticalAngle + Rand.Range(-VerticalAngleVariance,
                                                                    VerticalAngleVariance));
                p.Normal  = Quaternion.AngleAxis(angle, curveNormal) * p.Normal;
                p.Tangent = curveNormal;
                p.Size    = size;

                pieces.Add(p);
            }


            //Convert the "pieces" list into a mesh.

            if (MyMesh == null)
            {
                MyMesh = new Mesh();
            }
            else
            {
                MyMesh.Clear();
            }

            switch (Mode)
            {
            case MeshModes.Point:
                MyMesh.vertices = pieces.Select(p => p.Pos).ToArray();
                MyMesh.normals  = pieces.Select(p => p.Normal).ToArray();
                MyMesh.tangents = pieces.Select(p =>
                {
                    return(new Vector4(p.Tangent.x, p.Tangent.y, p.Tangent.z, 1.0f));
                }).ToArray();
                MyMesh.uv = pieces.Select(p => p.Size).ToArray();

                int i = -1;
                MyMesh.SetIndices(pieces.Select(p => { i += 1; return(i); }).ToArray(),
                                  MeshTopology.Points, 0);
                break;

            case MeshModes.Quad:

                Vector3[] poses = new Vector3[pieces.Count * 4],
                normals = new Vector3[pieces.Count * 4];
                Vector4[] tangents = new Vector4[pieces.Count * 4];
                Vector2[] uvs      = new Vector2[pieces.Count * 4];
                int[]     indices  = new int[pieces.Count * 6];

                for (int j = 0; j < pieces.Count; ++j)
                {
                    Piece p = pieces[j];

                    Vector3 bitangent = Vector3.Cross(p.Normal, p.Tangent).normalized;

                    Vector3 deltaX = 0.5f * p.Tangent * p.Size.y,
                            deltaY = 0.5f * bitangent * p.Size.x;

                    int vIndex = j * 4,
                        iIndex = j * 6;

                    poses[vIndex]     = p.Pos + (-deltaX + -deltaY);
                    uvs[vIndex]       = new Vector2(0.0f, 0.0f);
                    poses[vIndex + 1] = p.Pos + (deltaX + -deltaY);
                    uvs[vIndex + 1]   = new Vector2(1.0f, 0.0f);
                    poses[vIndex + 2] = p.Pos + (-deltaX + deltaY);
                    uvs[vIndex + 2]   = new Vector2(0.0f, 1.0f);
                    poses[vIndex + 3] = p.Pos + (deltaX + deltaY);
                    uvs[vIndex + 3]   = new Vector2(1.0f, 1.0f);

                    normals[vIndex]     = p.Normal;
                    normals[vIndex + 1] = p.Normal;
                    normals[vIndex + 2] = p.Normal;
                    normals[vIndex + 3] = p.Normal;

                    Vector4 tang = new Vector4(p.Tangent.x, p.Tangent.y, p.Tangent.z, 1.0f);
                    tangents[vIndex]     = tang;
                    tangents[vIndex + 1] = tang;
                    tangents[vIndex + 2] = tang;
                    tangents[vIndex + 3] = tang;

                    indices[iIndex]     = vIndex;
                    indices[iIndex + 1] = vIndex + 1;
                    indices[iIndex + 2] = vIndex + 3;
                    indices[iIndex + 3] = vIndex;
                    indices[iIndex + 4] = vIndex + 3;
                    indices[iIndex + 5] = vIndex + 2;
                }

                MyMesh.vertices = poses;
                MyMesh.normals  = normals;
                MyMesh.tangents = tangents;
                MyMesh.uv       = uvs;
                MyMesh.SetIndices(indices, MeshTopology.Triangles, 0);
                break;

            default: throw new NotImplementedException(Mode.ToString());
            }

            MyMesh.UploadMeshData(false);
        }
Beispiel #3
0
	private static void AddBranchTo(TreeCurve root, TreeCurve toCopy)
	{
		GameObject go = new GameObject("Branch");

		TreeCurve tc = go.AddComponent<TreeCurve>();
		tc.DrawCurveGizmo = false;
		tc.Curve = new Curve(toCopy.Curve.Points.ToList());

		tc.RadiusAlongCurve = new AnimationCurve(toCopy.RadiusAlongCurve.keys.ToArray());
		tc.RadiusAroundCurve = new AnimationCurve(toCopy.RadiusAroundCurve.keys.ToArray());
		tc.RadiusVarianceAlongCurve = new AnimationCurve(toCopy.RadiusVarianceAlongCurve.keys.ToArray());
		if (root == toCopy)
		{
			tc.RadiusScale = toCopy.RadiusScale * 0.5f;
		}
		else
		{
			tc.RadiusScale = toCopy.RadiusScale;
		}
		tc.CurveDivisionsAlong = toCopy.CurveDivisionsAlong;
		tc.CurveDivisionsAround = toCopy.CurveDivisionsAround;
		tc.OnValidate();

		MeshRenderer mrOld = toCopy.GetComponent<MeshRenderer>();
		if (mrOld != null)
		{
			MeshRenderer mr = go.AddComponent<MeshRenderer>();
			mr.sharedMaterial = mrOld.sharedMaterial;
		}

		//Add a mesh collider for ray-casting.
		myMC = root.GetComponent<MeshCollider>();
		if (myMC == null)
		{
			myMC = root.gameObject.AddComponent<MeshCollider>();
		}

		//Set the scale to be equal to the copy, or half of the copy if the copy is also the root.
		NewBranch = go.transform;
		NewBranch.localScale = toCopy.transform.localScale;
		NewBranch.parent = root.transform;
	}