Exemplo n.º 1
0
        /**
         *	Cast a ray (in model space) against a mesh.
         */
        public static bool MeshRaycast(Ray InRay, Vector3[] vertices, int[] triangles, out z_RaycastHit hit, float distance = Mathf.Infinity, Culling cullingMode = Culling.Front)
        {
            // float dot;       // vars used in loop
            float   hitDistance = Mathf.Infinity;
            Vector3 hitNormal = new Vector3(0f, 0f, 0f);                // vars used in loop
            Vector3 a, b, c;
            int     hitFace = -1;
            Vector3 o = InRay.origin, d = InRay.direction;

            /**
             * Iterate faces, testing for nearest hit to ray origin.
             */
            for (int CurTri = 0; CurTri < triangles.Length; CurTri += 3)
            {
                a = vertices[triangles[CurTri + 0]];
                b = vertices[triangles[CurTri + 1]];
                c = vertices[triangles[CurTri + 2]];

                if (z_Math.RayIntersectsTriangle2(o, d, a, b, c, ref distance, ref hitNormal))
                {
                    hitFace     = CurTri / 3;
                    hitDistance = distance;
                    break;
                }
            }

            hit = new z_RaycastHit(hitDistance,
                                   InRay.GetPoint(hitDistance),
                                   hitNormal,
                                   hitFace);

            return(hitFace > -1);
        }
Exemplo n.º 2
0
        private void PlaceGameObject(z_RaycastHit hit, GameObject prefab, z_BrushTarget target, z_BrushSettings settings)
        {
            if (prefab == null)
            {
                return;
            }

            Ray ray = RandomRay(hit.position, hit.normal, settings.radius, settings.falloff, settings.falloffCurve);

            z_RaycastHit rand_hit;

            Vector3[] vertices  = target.editableObject.editMesh.vertices;
            int[]     triangles = target.editableObject.editMesh.GetTriangles();

            if (z_SceneUtility.MeshRaycast(ray, vertices, triangles, out rand_hit))
            {
                float pivotOffset = placeWithPivot ? 0f : GetPivotOffset(prefab);

                Quaternion rotation = Quaternion.FromToRotation(Vector3.up, target.transform.TransformDirection(rand_hit.normal));
                Quaternion random   = Quaternion.AngleAxis(Random.Range(0f, 360f), Vector3.up);

#pragma warning disable 0618
                GameObject inst = PrefabUtility.ConnectGameObjectToPrefab(Instantiate(prefab), prefab);
#pragma warning restore 0618

                inst.transform.localPosition = target.transform.TransformPoint(rand_hit.position);
                inst.transform.localRotation = rotation * random;
                inst.name = FormatInstanceName(prefab);
                inst.transform.position = inst.transform.position + inst.transform.up * pivotOffset;

                if (avoidOverlappingGameObjects && TestIntersection(inst))
                {
                    Object.DestroyImmediate(inst);
                    return;
                }

                if (hitSurfaceIsParent)
                {
                    inst.transform.SetParent(target.transform);
                }

                PrefabUtility.RecordPrefabInstancePropertyModifications(inst);

                instances.Add(inst);

                Undo.RegisterCreatedObjectUndo(inst, UndoMessage);
            }
        }
Exemplo n.º 3
0
        private void RemoveGameObjects(z_RaycastHit hit, z_BrushTarget target, z_BrushSettings settings)
        {
            Vector3 worldHitPosition = target.editableObject.transform.TransformPoint(hit.position);

            int count = instances.Count;

            for (int i = 0; i < count; i++)
            {
                if (instances[i] != null && Vector3.Distance(worldHitPosition, instances[i].transform.position) < settings.radius)
                {
                    GameObject go = instances[i];
                    instances.RemoveAt(i);
                    count--;
                    Undo.DestroyObjectImmediate(go);
                }
            }
        }
Exemplo n.º 4
0
        /**
         * Find the nearest triangle intersected by InWorldRay on this mesh.  InWorldRay is in world space.
         * @hit contains information about the hit point.  @distance limits how far from @InWorldRay.origin the hit
         * point may be.  @cullingMode determines what face orientations are tested (Culling.Front only tests front
         * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both).
         * Ray origin and position values are in local space.
         */
        public static bool WorldRaycast(Ray InWorldRay, Transform transform, Vector3[] vertices, int[] triangles, out z_RaycastHit hit, float distance = Mathf.Infinity, Culling cullingMode = Culling.Front)
        {
            Ray ray = transform.InverseTransformRay(InWorldRay);
//commented out code was ommited here
        }
Exemplo n.º 5
0
        public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
        {
            int rayCount = target.raycastHits.Count;

            if (rayCount < 1)
            {
                return;
            }

            Vector3 n = direction.ToVector3();

            float scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
            float sign  = Event.current.shift ? -1f : 1f;

            float maxMoveDistance = settings.strength * STRENGTH_MODIFIER * sign * brushStrength;
            int   vertexCount     = target.editableObject.vertexCount;

            z_Mesh mesh = target.editableObject.editMesh;

            for (int ri = 0; ri < rayCount; ri++)
            {
                z_RaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                if (direction == z_Direction.BrushNormal)
                {
                    if (brushNormalIsSticky)
                    {
                        n = brushNormalOnBeginApply[ri];
                    }
                    else
                    {
                        n = target.raycastHits[ri].normal;
                    }

                    scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
                }

                for (int i = 0; i < commonVertexCount; i++)
                {
                    int index = commonVertices[i][0];

                    if (hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
                    {
                        continue;
                    }

                    if (direction == z_Direction.VertexNormal)
                    {
                        n     = normalLookup[index];
                        scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
                    }

                    Vector3 pos = vertices[index] + n * (hit.weights[index] * maxMoveDistance * scale);

                    List <int> indices = commonVertices[i];

                    for (int it = 0; it < indices.Count; it++)
                    {
                        vertices[indices[it]] = pos;
                    }
                }
            }

            mesh.vertices = vertices;

            // different than setting weights on temp component,
            // which is what z_BrushModeMesh.OnBrushApply does.
            if (tempComponent != null)
            {
                tempComponent.OnVerticesMoved(mesh);
            }

            base.OnBrushApply(target, settings);
        }
Exemplo n.º 6
0
        /**
         * Find the nearest triangle intersected by InWorldRay on this mesh.  InWorldRay is in world space.
         * @hit contains information about the hit point.  @distance limits how far from @InWorldRay.origin the hit
         * point may be.  @cullingMode determines what face orientations are tested (Culling.Front only tests front
         * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both).
         * Ray origin and position values are in local space.
         */
        public static bool WorldRaycast(Ray InWorldRay, Transform transform, Vector3[] vertices, int[] triangles, out z_RaycastHit hit, float distance = Mathf.Infinity, Culling cullingMode = Culling.Front)
        {
            Ray ray = transform.InverseTransformRay(InWorldRay);

            return(MeshRaycast(ray, vertices, triangles, out hit, distance, cullingMode));
        }
Exemplo n.º 7
0
		/**
		 *	Cast a ray (in model space) against a mesh.
		 */
		public static bool MeshRaycast(Ray InRay, MeshFilter meshFilter, out z_RaycastHit hit, float distance, Culling cullingMode)
		{
			Mesh mesh = meshFilter.sharedMesh;

			float dist = 0f;
			Vector3 point = Vector3.zero;

			float OutHitPoint = Mathf.Infinity;
			float dot; 		// vars used in loop
			Vector3 nrm;	// vars used in loop
			int OutHitFace = -1;
			Vector3 OutNrm = Vector3.zero;

			/**
			 * Iterate faces, testing for nearest hit to ray origin.  Optionally ignores backfaces.
			 */

			Vector3[] vertices = mesh.vertices;
			int[] triangles = mesh.triangles;

			for(int CurTri = 0; CurTri < triangles.Length; CurTri += 3)
			{
				Vector3 a = vertices[triangles[CurTri+0]];
				Vector3 b = vertices[triangles[CurTri+1]];
				Vector3 c = vertices[triangles[CurTri+2]];

				nrm = Vector3.Cross(b-a, c-a);
				dot = Vector3.Dot(InRay.direction, nrm);

				bool ignore = false;

				switch(cullingMode)
				{
					case Culling.Front:
						if(dot > 0f) ignore = true;
						break;

					case Culling.Back:
						if(dot < 0f) ignore = true;
						break;
				}

				if(!ignore && z_Math.RayIntersectsTriangle(InRay, a, b, c, out dist, out point))
				{
					if(dist > OutHitPoint || dist > distance)
						continue;

					OutNrm = nrm;
					OutHitFace = CurTri / 3;
					OutHitPoint = dist;

					continue;
				}
			}

			hit = new z_RaycastHit( OutHitPoint,
									InRay.GetPoint(OutHitPoint),
									OutNrm,
									OutHitFace);

			return OutHitFace > -1;
		}
Exemplo n.º 8
0
		/**
		 * Find the nearest triangle intersected by InWorldRay on this mesh.  InWorldRay is in world space.
		 * @hit contains information about the hit point.  @distance limits how far from @InWorldRay.origin the hit
		 * point may be.  @cullingMode determines what face orientations are tested (Culling.Front only tests front 
		 * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both).
		 * Ray origin and position values are in local space.
		 */
		public static bool WorldRaycast(Ray InWorldRay, MeshFilter meshFilter, out z_RaycastHit hit, float distance, Culling cullingMode)
		{
			Ray ray = meshFilter.transform.InverseTransformRay(InWorldRay);
			return MeshRaycast(ray, meshFilter, out hit, distance, cullingMode);
		}
Exemplo n.º 9
0
		/**
		 * Find a triangle intersected by InRay on InMesh.  InRay is in world space.
		 * Returns the index in mesh.faces of the hit face, or -1.  Optionally can ignore
		 * backfaces.
		 */
		public static bool WorldRaycast(Ray InWorldRay, MeshFilter meshFilter, out z_RaycastHit hit)
		{
			return WorldRaycast(InWorldRay, meshFilter, out hit, Mathf.Infinity, Culling.Front);
		}
Exemplo n.º 10
0
		private void PlaceGameObject(z_RaycastHit hit, GameObject prefab, z_BrushTarget target, z_BrushSettings settings)
		{
			if(prefab == null)
				return;

			Ray ray = RandomRay(hit.position, hit.normal, settings.radius, settings.falloff, settings.falloffCurve);

			Debug.DrawRay(
				target.transform.TransformPoint(ray.origin), 
				target.transform.TransformDirection(ray.direction),
				Color.red);

			z_RaycastHit rand_hit;

			if( z_SceneUtility.MeshRaycast(ray, target.editableObject.meshFilter, out rand_hit) )
			{
				float pivotOffset = placeWithPivot ? 0f : GetPivotOffset(prefab);

				Quaternion rotation = Quaternion.FromToRotation(Vector3.up, target.transform.TransformDirection(rand_hit.normal));
				Quaternion random = Quaternion.AngleAxis(Random.Range(0f, 360f), Vector3.up);
 
				GameObject inst = (GameObject) GameObject.Instantiate(
					prefab, 
					target.transform.TransformPoint(rand_hit.position),
					rotation * random);

				inst.transform.position = inst.transform.position + inst.transform.up * pivotOffset;

				if(hitTransformIsParent)
					inst.transform.SetParent(target.transform);

				Undo.RegisterCreatedObjectUndo(inst, UndoMessage);
			}
		}
Exemplo n.º 11
0
        public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
        {
            int rayCount = target.raycastHits.Count;

            Vector3[] normals = (direction == z_Direction.BrushNormal) ? target.editableObject.editMesh.normals : null;

            Vector3 v, t, avg, dirVec = direction.ToVector3();
            Plane   plane       = new Plane(Vector3.up, Vector3.zero);
            z_Mesh  mesh        = target.editableObject.editMesh;
            int     vertexCount = mesh.vertexCount;

            // don't use target.GetAllWeights because brush normal needs
            // to know which ray to use for normal
            for (int ri = 0; ri < rayCount; ri++)
            {
                z_RaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                for (int i = 0; i < commonVertexCount; i++)
                {
                    int index = commonVertices[i][0];

                    if (hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
                    {
                        continue;
                    }

                    v = vertices[index];

                    if (direction == z_Direction.VertexNormal)
                    {
                        avg = z_Math.Average(vertices, neighborLookup[index]);
                    }
                    else
                    {
                        avg = z_Math.WeightedAverage(vertices, neighborLookup[index], hit.weights);

                        if (direction == z_Direction.BrushNormal)
                        {
                            if (brushNormalIsSticky)
                            {
                                dirVec = brushNormalOnBeginApply[ri];
                            }
                            else
                            {
                                dirVec = z_Math.WeightedAverage(normals, neighborLookup[index], hit.weights).normalized;
                            }
                        }

                        plane.SetNormalAndPosition(dirVec, avg);
                        avg = v - dirVec * plane.GetDistanceToPoint(v);
                    }

                    t = Vector3.Lerp(v, avg, hit.weights[index]);
                    List <int> indices = commonVertices[i];

                    Vector3 pos = v + (t - v) * settings.strength * SMOOTH_STRENGTH_MODIFIER;

                    for (int n = 0; n < indices.Count; n++)
                    {
                        vertices[indices[n]] = pos;
                    }
                }
            }

            mesh.vertices = vertices;

            if (tempComponent != null)
            {
                tempComponent.OnVerticesMoved(mesh);
            }

            base.OnBrushApply(target, settings);
        }