static void GenerateVoxelGrids(GameObject prefabRoot, PlaneVoxelGenerationParams voxelGenerationParams, VoxelPlaneFindingParams planeFindingParams) { // Rather than modifying collider properties and risking corrupting the scene, for each object with a mesh // we create a game object with a collider that uses that mesh and add that object to a preview scene. var tempPreviewScene = EditorSceneManager.NewPreviewScene(); var tempPhysicsScene = tempPreviewScene.GetPhysicsScene(); // k_MeshFilters is cleared by GetComponentsInChildren prefabRoot.GetComponentsInChildren(k_MeshFilters); var meshesRoot = new GameObject("Meshes").transform; k_MeshColliders.Clear(); foreach (var meshFilter in k_MeshFilters) { // Ignore synth planes if (meshFilter.GetComponent <SynthesizedPlane>()) { continue; } var meshCopyTrans = new GameObject(string.Format("{0} (Mesh)", meshFilter.gameObject.name)).transform; var meshCopyCollider = meshCopyTrans.gameObject.AddComponent <MeshCollider>(); k_MeshColliders.Add(meshCopyCollider); meshCopyCollider.sharedMesh = meshFilter.sharedMesh; meshCopyTrans.SetParent(meshesRoot); var meshFilterTrans = meshFilter.transform; meshCopyTrans.position = meshFilterTrans.position; meshCopyTrans.rotation = meshFilterTrans.rotation; meshCopyTrans.localScale = meshFilterTrans.lossyScale; } SceneManager.MoveGameObjectToScene(meshesRoot.gameObject, tempPreviewScene); var sceneBounds = BoundsUtils.GetBounds(k_MeshColliders); var sceneBoundsMin = sceneBounds.min; var sceneBoundsMax = sceneBounds.max; // Make mesh colliders convex so that we can use CheckSphere to make sure our // raycasts don't originate within meshes. foreach (var meshCollider in k_MeshColliders) { meshCollider.convex = true; } // Seed the random number generator so that results are deterministic Random.InitState(voxelGenerationParams.raycastSeed); // Setup all ray origins before raycasting since we need mesh colliders to be convex for this step // but concave for the raycasting. var raycastCount = voxelGenerationParams.raycastCount; k_RayOrigins.Clear(); k_RayOrigins.Capacity = raycastCount; for (var i = 0; i < raycastCount; i++) { var rayGenerationAttempts = 0; Vector3 origin; while (true) { origin = new Vector3( Random.Range(sceneBoundsMin.x, sceneBoundsMax.x), Random.Range(sceneBoundsMin.y, sceneBoundsMax.y), Random.Range(sceneBoundsMin.z, sceneBoundsMax.z)); // If the randomly generated ray origin lies inside a mesh, try again if (tempPhysicsScene.OverlapSphere(origin, k_CheckSphereRadius, k_Colliders, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Collide) == 0) { break; } rayGenerationAttempts++; if (rayGenerationAttempts >= k_MaxRayGenerationRetries) { break; } } k_RayOrigins.Add(origin); } foreach (var meshCollider in k_MeshColliders) { // Make mesh colliders concave for more useful raycast results meshCollider.convex = false; } k_UpGridPoints.Clear(); k_DownGridPoints.Clear(); k_ForwardGridPoints.Clear(); k_BackGridPoints.Clear(); k_RightGridPoints.Clear(); k_LeftGridPoints.Clear(); var outerPointsThreshold = voxelGenerationParams.outerPointsThreshold; var upGridBounds = sceneBounds; var upGridMax = upGridBounds.max; upGridMax.y -= Mathf.Min(outerPointsThreshold, upGridBounds.size.y); upGridBounds.max = upGridMax; var downGridBounds = sceneBounds; var downGridMin = downGridBounds.min; downGridMin.y += Mathf.Min(outerPointsThreshold, downGridBounds.size.y); downGridBounds.min = downGridMin; var forwardGridBounds = sceneBounds; var forwardGridMax = forwardGridBounds.max; forwardGridMax.z -= Mathf.Min(outerPointsThreshold, forwardGridBounds.size.z); forwardGridBounds.max = forwardGridMax; var backGridBounds = sceneBounds; var backGridMin = backGridBounds.min; backGridMin.z += Mathf.Min(outerPointsThreshold, backGridBounds.size.z); backGridBounds.min = backGridMin; var rightGridBounds = sceneBounds; var rightGridMax = rightGridBounds.max; rightGridMax.x -= Mathf.Min(outerPointsThreshold, rightGridBounds.size.x); rightGridBounds.max = rightGridMax; var leftGridBounds = sceneBounds; var leftGridMin = leftGridBounds.min; leftGridMin.x += Mathf.Min(outerPointsThreshold, leftGridBounds.size.x); leftGridBounds.min = leftGridMin; // Start raycasting. We run raycasts synchronously so the user can't switch scenes or make scene changes while they are running. var maxHitDistance = voxelGenerationParams.maxHitDistance; var normalToleranceAngle = voxelGenerationParams.normalToleranceAngle; var rayIndex = 0; var up = Vector3.up; var down = Vector3.down; var back = Vector3.back; var right = Vector3.right; var left = Vector3.left; while (rayIndex < raycastCount) { if (EditorUtility.DisplayCancelableProgressBar( "Generating Point Cloud", string.Format("{0}/{1} raycasts completed", rayIndex, raycastCount), (float)rayIndex / raycastCount)) { EditorUtility.ClearProgressBar(); GUIUtility.ExitGUI(); break; } for (var i = 0; i < k_RaycastProgressBatchSize && rayIndex < raycastCount; i++, rayIndex++) { var origin = k_RayOrigins[rayIndex]; var direction = RandomRayDirection(); RaycastHit raycastHit; if (!tempPhysicsScene.Raycast(origin, direction, out raycastHit, maxHitDistance)) { continue; } var point = raycastHit.point; var normal = raycastHit.normal; if (Vector3.Angle(normal, up) <= normalToleranceAngle && upGridBounds.Contains(point)) { k_UpGridPoints.Add(point); } if (Vector3.Angle(normal, down) <= normalToleranceAngle && downGridBounds.Contains(point)) { k_DownGridPoints.Add(point); } if (Vector3.Angle(normal, k_Forward) <= normalToleranceAngle && forwardGridBounds.Contains(point)) { k_ForwardGridPoints.Add(point); } if (Vector3.Angle(normal, back) <= normalToleranceAngle && backGridBounds.Contains(point)) { k_BackGridPoints.Add(point); } if (Vector3.Angle(normal, right) <= normalToleranceAngle && rightGridBounds.Contains(point)) { k_RightGridPoints.Add(point); } if (Vector3.Angle(normal, left) <= normalToleranceAngle && leftGridBounds.Contains(point)) { k_LeftGridPoints.Add(point); } } } EditorUtility.ClearProgressBar(); EditorSceneManager.ClosePreviewScene(tempPreviewScene); // Reset the seed so other uses of Random are not deterministic Random.InitState((int)DateTime.Now.Ticks); // Generate voxel grids from point cloud var voxelSize = voxelGenerationParams.voxelSize; s_UpVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Up, upGridBounds, voxelSize, planeFindingParams); s_DownVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Down, downGridBounds, voxelSize, planeFindingParams); s_ForwardVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Forward, forwardGridBounds, voxelSize, planeFindingParams); s_BackVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Back, backGridBounds, voxelSize, planeFindingParams); s_RightVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Right, rightGridBounds, voxelSize, planeFindingParams); s_LeftVoxelGrid = new PlaneExtractionVoxelGrid(VoxelGridOrientation.Left, leftGridBounds, voxelSize, planeFindingParams); s_UpVoxelGrid.AddPoints(k_UpGridPoints); s_DownVoxelGrid.AddPoints(k_DownGridPoints); s_ForwardVoxelGrid.AddPoints(k_ForwardGridPoints); s_BackVoxelGrid.AddPoints(k_BackGridPoints); s_RightVoxelGrid.AddPoints(k_RightGridPoints); s_LeftVoxelGrid.AddPoints(k_LeftGridPoints); }
private void Update() { BeforeForwardOpaque.Clear(); Renderer[] renderers = FindObjectsOfType <Renderer>(); BeforeForwardOpaque.BeginSample("DepthOnly"); BeforeForwardOpaque.SetViewMatrix(camera.worldToCameraMatrix); BeforeForwardOpaque.SetProjectionMatrix(camera.projectionMatrix); BeforeForwardOpaque.SetRenderTarget(_DepthTex); BeforeForwardOpaque.ClearRenderTarget(true, true, Color.black); for (int i = 0, imax = renderers.Length; i < imax; i++) { Renderer rend = renderers[i]; if (rend.shadowCastingMode != ShadowCastingMode.Off) { //casterAABBs.Add(rend.bounds); if (BoundsUtils.IntersectFrustum(rend.bounds, rend.localToWorldMatrix, Camera.main.cullingMatrix)) { for (int m = 0, mmax = rend.sharedMaterials.Length; m < mmax; m++) { var mat = rend.sharedMaterial; // "sharedMaterials" cases bugs; int pass = mat.FindPass("DepthOnly"); if (pass < 0) { BeforeForwardOpaque.DrawRenderer(rend, DepthMaterial, m, 0); } else { BeforeForwardOpaque.DrawRenderer(rend, mat, m, pass); } mat.SetShaderPassEnabled("DepthOnly", false); } } } } BeforeForwardOpaque.EndSample("DepthOnly"); BeforeForwardOpaque.SetRenderTarget(BuiltinRenderTextureType.None); BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); Matrix4x4 lightMatrix = DirectionalLight.transform.worldToLocalMatrix; //if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore // || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3) { Vector4 forward = lightMatrix.GetRow(2); lightMatrix.SetRow(2, -forward); } BeforeForwardOpaque.SetViewMatrix(lightMatrix); Matrix4x4 projMatrix = Matrix4x4.Ortho(-0.5f, 0.5f, -0.5f, 0.5f, 0.1f, 10); BeforeForwardOpaque.SetProjectionMatrix(projMatrix); BeforeForwardOpaque.SetViewport(new Rect(0, 0, dimension, dimension)); /*if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) * { * Matrix4x4 mAdj = Matrix4x4.identity; * mAdj.m22 = -0.5f; * mAdj.m23 = 0.5f; * projMatrix = mAdj * projMatrix; * }*/ BeforeForwardOpaque.SetGlobalMatrix("_LightVP", projMatrix * lightMatrix); BeforeForwardOpaque.SetGlobalFloat("_HairAlpha", HairAlpha); BeforeForwardOpaque.BeginSample("ShadowMapMaterial"); for (int i = 0, imax = renderers.Length; i < imax; i++) { Renderer rend = renderers[i]; if (rend.shadowCastingMode != ShadowCastingMode.Off) { //casterAABBs.Add(rend.bounds); if (BoundsUtils.IntersectFrustum(rend.bounds, rend.localToWorldMatrix, Camera.main.cullingMatrix)) { for (int m = 0, mmax = rend.sharedMaterials.Length; m < mmax; m++) { var mat = rend.sharedMaterial; // "sharedMaterials" cases bugs; int pass = mat.FindPass("DeepShadowCaster"); if (pass < 0) { BeforeForwardOpaque.DrawRenderer(rend, ShadowMapMaterial, m, 0); } else { BeforeForwardOpaque.DrawRenderer(rend, mat, m, pass); } mat.SetShaderPassEnabled("DeepShadowCaster", false); } } } } BeforeForwardOpaque.ClearRenderTarget(true, true, Color.black); BeforeForwardOpaque.EndSample("ShadowMapMaterial"); BeforeForwardOpaque.SetRenderTarget(_ShadowTex); BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_ScreenWidth", Screen.width); BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_ScreenHeight", Screen.height); BeforeForwardOpaque.SetComputeMatrixParam(ResolveCompute, "_CameraInvVP", camera.cullingMatrix.inverse); BeforeForwardOpaque.SetComputeMatrixParam(ResolveCompute, "_LightVP", projMatrix * lightMatrix); BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_AsDefaultShadowmap", _AsDefaultShadowmap ? 1 : 0); BeforeForwardOpaque.DispatchCompute(ResolveCompute, KernelScreenSpaceDeepShadowmap, (7 + Screen.width) / 8, (7 + Screen.height) / 8, 1); BeforeForwardOpaque.SetRenderTarget(_BlurTex); BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_BlurStep", 1); BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_SourceShadowTexture", _ShadowTex); BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_BlurShadowTexture", _BlurTex); BeforeForwardOpaque.DispatchCompute(ResolveCompute, KernelGaussianBlurShadow, (7 + Screen.width) / 8, (7 + Screen.height) / 8, 1); //BeforeForwardOpaque.SetRenderTarget(_ShadowTex); //BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); //BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_BlurStep", 2); //BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_SourceShadowTexture", _BlurTex); //BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_BlurShadowTexture", _ShadowTex); //BeforeForwardOpaque.DispatchCompute(ResolveCompute, KernelGaussianBlurShadow, (7 + Screen.width) / 8, (7 + Screen.height) / 8, 1); //BeforeForwardOpaque.SetRenderTarget(_BlurTex); //BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); //BeforeForwardOpaque.SetComputeIntParam(ResolveCompute, "_BlurStep", 4); //BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_SourceShadowTexture", _ShadowTex); //BeforeForwardOpaque.SetComputeTextureParam(ResolveCompute, KernelGaussianBlurShadow, "_BlurShadowTexture", _BlurTex); //BeforeForwardOpaque.DispatchCompute(ResolveCompute, KernelGaussianBlurShadow, (7 + Screen.width) / 8, (7 + Screen.height) / 8, 1); BeforeForwardOpaque.SetGlobalTexture("_BlurShadowTexture", _BlurTex); BeforeForwardOpaque.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); BeforeForwardOpaque.SetViewMatrix(camera.worldToCameraMatrix); BeforeForwardOpaque.SetProjectionMatrix(camera.projectionMatrix); BeforeForwardOpaque.SetGlobalVector("CameraPos", camera.transform.position); BeforeForwardOpaque.SetGlobalVector("LightDir", DirectionalLight.transform.forward); BeforeForwardOpaque.SetGlobalColor("_HairColor", HairColor); #if UNITY_EDITOR && DEBUG_DSM BeforeForwardOpaque.DispatchCompute(TestCompute, KernelResetTestResult, dimension / 8, dimension / 8, 1); BeforeForwardOpaque.SetComputeIntParam(TestCompute, "TestIndex", TestIndex); if (TestKernel == ETestKernel.KernelTestNumberBuffer) { BeforeForwardOpaque.DispatchCompute(TestCompute, KernelTestNumberBuffer, dimension / 8, dimension / 8, 1); } else if (TestKernel == ETestKernel.KernelTestDepthBuffer) { BeforeForwardOpaque.DispatchCompute(TestCompute, KernelTestDepthBuffer, dimension / 8, dimension / 8, 1); } #endif AfterForwardOpaque.Clear(); AfterForwardOpaque.DispatchCompute(ResetCompute, KernelResetDepthBuffer, dimension / 8, dimension / 8, 1); AfterForwardOpaque.DispatchCompute(ResetCompute, KernelResetNumberBuffer, dimension / 8, dimension / 8, 1); }
private void Update() { BeforeForwardOpaque.Clear(); BeforeForwardOpaque.SetRenderTarget(BuiltinRenderTextureType.None); BeforeForwardOpaque.ClearRenderTarget(true, true, Color.white); Matrix4x4 lightMatrix = DirectionalLight.transform.worldToLocalMatrix; //if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore // || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3) { Vector4 forward = lightMatrix.GetRow(2); lightMatrix.SetRow(2, -forward); } BeforeForwardOpaque.SetViewMatrix(lightMatrix); Matrix4x4 projMatrix = Matrix4x4.Ortho(-1, 1, -1, 1, 0.1f, 10); BeforeForwardOpaque.SetProjectionMatrix(projMatrix); BeforeForwardOpaque.SetViewport(new Rect(0, 0, dimension, dimension)); /*if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) * { * Matrix4x4 mAdj = Matrix4x4.identity; * mAdj.m22 = -0.5f; * mAdj.m23 = 0.5f; * projMatrix = mAdj * projMatrix; * }*/ BeforeForwardOpaque.SetGlobalMatrix("_LightVP", projMatrix * lightMatrix); BeforeForwardOpaque.SetGlobalFloat("_HairAlpha", HairAlpha); BeforeForwardOpaque.BeginSample("ShadowMapMaterial"); Renderer[] renderers = FindObjectsOfType <Renderer>(); for (int i = 0, imax = renderers.Length; i < imax; i++) { Renderer rend = renderers[i]; if (rend.shadowCastingMode != ShadowCastingMode.Off) { //casterAABBs.Add(rend.bounds); if (BoundsUtils.IntersectFrustum(rend.bounds, rend.localToWorldMatrix, Camera.main.cullingMatrix)) { for (int m = 0, mmax = rend.sharedMaterials.Length; m < mmax; m++) { BeforeForwardOpaque.DrawRenderer(rend, ShadowMapMaterial, m, 0); } } } } BeforeForwardOpaque.ClearRenderTarget(true, true, Color.black); BeforeForwardOpaque.EndSample("ShadowMapMaterial"); BeforeForwardOpaque.DispatchCompute(SortCompute, KernelSortDepth, dimension / 8, dimension / 8, 1); BeforeForwardOpaque.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); BeforeForwardOpaque.SetViewMatrix(camera.worldToCameraMatrix); BeforeForwardOpaque.SetProjectionMatrix(camera.projectionMatrix); BeforeForwardOpaque.SetGlobalVector("CameraPos", camera.transform.position); BeforeForwardOpaque.SetGlobalVector("LightDir", DirectionalLight.transform.forward); BeforeForwardOpaque.SetGlobalColor("_HairColor", HairColor); #if UNITY_EDITOR BeforeForwardOpaque.DispatchCompute(TestCompute, KernelResetTestResult, dimension / 8, dimension / 8, 1); BeforeForwardOpaque.SetComputeIntParam(TestCompute, "TestIndex", TestIndex); if (TestKernel == ETestKernel.KernelTestNumberBuffer) { BeforeForwardOpaque.DispatchCompute(TestCompute, KernelTestNumberBuffer, dimension / 8, dimension / 8, 1); } else if (TestKernel == ETestKernel.KernelTestDepthBuffer) { BeforeForwardOpaque.DispatchCompute(TestCompute, KernelTestDepthBuffer, dimension / 8, dimension / 8, 1); } else if (TestKernel == ETestKernel.KernelTestRegressionBuffer) { BeforeForwardOpaque.DispatchCompute(TestCompute, KernelTestRegressionBuffer, dimension / 8, dimension / 8, 1); } #endif AfterForwardOpaque.Clear(); AfterForwardOpaque.DispatchCompute(ResetCompute, KernelResetDepthBuffer, dimension / 8, dimension / 8, 1); AfterForwardOpaque.DispatchCompute(ResetCompute, KernelResetRegressionBuffer, dimension / 8, dimension / 8, 1); AfterForwardOpaque.DispatchCompute(ResetCompute, KernelResetNumberBuffer, dimension / 8, dimension / 8, 1); }
IEnumerator PlaceSceneObjectCoroutine(Transform obj, Vector3 targetScale) { var go = obj.gameObject; // Don't let us direct select while placing this.RemoveFromSpatialHash(go); var start = Time.realtimeSinceStartup; var currTime = 0f; obj.parent = null; var localScale = obj.localScale; var startScale = localScale; var startPosition = BoundsUtils.GetBounds(obj).center; var position = obj.position; var pivotOffset = position - startPosition; var startRotation = obj.rotation; var targetRotation = startRotation.ConstrainYaw(); //Get bounds at target scale and rotation (scaled and rotated from bounds center) var origScale = localScale; obj.rotation = targetRotation; var rotationDiff = Quaternion.Inverse(startRotation) * targetRotation; var scaleDiff = targetScale.magnitude / startScale.magnitude; var targetPivotOffset = rotationDiff * pivotOffset * scaleDiff; var bounds = BoundsUtils.GetBounds(obj); localScale = origScale; obj.localScale = localScale; obj.localRotation = startRotation; obj.position = startPosition + pivotOffset; // We want to position the object so that it fits within the camera perspective at its original scale var camera = CameraUtils.GetMainCamera(); var halfAngle = camera.fieldOfView * 0.5f; var perspective = halfAngle + k_InstantiateFOVDifference; var camPosition = camera.transform.position; var forward = startPosition - camPosition; var distance = bounds.size.magnitude / Mathf.Tan(perspective * Mathf.Deg2Rad); var targetPosition = bounds.center; if (distance > forward.magnitude && obj.localScale != targetScale) { targetPosition = camPosition + forward.normalized * distance; } startPosition += pivotOffset; targetPosition += targetPivotOffset; while (currTime < k_GrowDuration) { currTime = Time.realtimeSinceStartup - start; var t = currTime / k_GrowDuration; var tSquared = t * t; obj.localScale = Vector3.Lerp(startScale, targetScale, tSquared); obj.position = Vector3.Lerp(startPosition, targetPosition, tSquared); obj.rotation = Quaternion.Lerp(startRotation, targetRotation, tSquared); yield return(null); } obj.localScale = targetScale; Selection.activeGameObject = go; this.AddToSpatialHash(go); #if UNITY_EDITOR UnityEditor.Undo.IncrementCurrentGroup(); #endif }
IEnumerator PlaceSceneObjectsCoroutine(Transform[] transforms, Vector3[] targetPositionOffsets, Quaternion[] targetRotations, Vector3[] targetScales) { var start = Time.realtimeSinceStartup; var currTime = 0f; var length = transforms.Length; var startPositions = new Vector3[length]; var startRotations = new Quaternion[length]; var startScales = new Vector3[length]; var center = BoundsUtils.GetBounds(transforms).center; var pivot = Vector3.zero; //Get bounds at target scale and rotation (scaled and rotated from bounds center) for (var i = 0; i < length; i++) { var transform = transforms[i]; this.RemoveFromSpatialHash(transform.gameObject); var position = transform.position; startPositions[i] = position; startRotations[i] = transform.rotation; startScales[i] = transform.localScale; pivot += position; transform.position = targetPositionOffsets[i]; transform.rotation = targetRotations[i]; transform.localScale = targetScales[i]; } pivot /= length; var bounds = BoundsUtils.GetBounds(transforms); for (var i = 0; i < length; i++) { var transform = transforms[i]; transform.position = startPositions[i]; transform.rotation = startRotations[i]; transform.localScale = startScales[i]; } // We want to position the object so that it fits within the camera perspective at its original scale var camera = CameraUtils.GetMainCamera(); var halfAngle = camera.fieldOfView * 0.5f; var perspective = halfAngle + k_InstantiateFOVDifference; var camPosition = camera.transform.position; var forward = center - camPosition; var distance = bounds.size.magnitude / Mathf.Tan(perspective * Mathf.Deg2Rad); var targetPosition = pivot; if (distance > forward.magnitude) { targetPosition = camPosition + forward.normalized * distance; } for (var i = 0; i < length; i++) { targetPositionOffsets[i] += targetPosition; } while (currTime < k_GrowDuration) { currTime = Time.realtimeSinceStartup - start; var t = currTime / k_GrowDuration; var tSquared = t * t; for (int i = 0; i < length; i++) { var transform = transforms[i]; transform.localScale = Vector3.Lerp(startScales[i], targetScales[i], tSquared); transform.position = Vector3.Lerp(startPositions[i], targetPositionOffsets[i], tSquared); transform.rotation = Quaternion.Slerp(startRotations[i], targetRotations[i], tSquared); yield return(null); } } var objects = new GameObject[length]; for (int i = 0; i < length; i++) { var transform = transforms[i]; objects[i] = transform.gameObject; transform.localScale = targetScales[i]; transform.rotation = targetRotations[i]; transform.position = targetPositionOffsets[i]; this.AddToSpatialHash(transform.gameObject); } Selection.objects = objects; #if UNITY_EDITOR UnityEditor.Undo.IncrementCurrentGroup(); #endif }
static void ImportEnvironment(string environmentName, string jsonText, string path, GameObject simulatedPlanePrefab, Material simulatedPlaneMaterial, Post postPrefab, MeshFilter meshPrefab, GameObject simulatedLightingPrefab, Action <UnityObject> callback) { var environment = SceneSerialization.FromJson <Environment>(jsonText); var height = environment.height; var vertices = environment.vertices; var center = Vector3.zero; var posts = CollectionPool <List <Post>, Post> .GetCollection(); var count = vertices.Count; Post previous = null; foreach (var vertex in vertices) { var post = UnityObject.Instantiate(postPrefab); posts.Add(post); center += vertex; var postTransform = post.transform; postTransform.position = vertex; post.SetTopSphereHeight(height); if (previous != null) { previous.Setup(); var previousPosition = previous.transform.position; previous.UpdateWall(vertex, previousPosition - vertex, height); } previous = post; } if (count != 0) { center /= count; } var prefabRoot = new GameObject(environmentName).transform; var floorPlan = new GameObject("Floor Plan").transform; prefabRoot.position = center; floorPlan.SetParent(prefabRoot, false); foreach (var post in posts) { post.transform.SetParent(floorPlan, true); var wall = post.Wall; if (wall != null) { wall.SetParent(floorPlan, true); } } var planesRoot = new GameObject("Planes").transform; planesRoot.SetParent(prefabRoot, false); foreach (var plane in environment.planes) { var synthesizedPlane = ((GameObject)PrefabUtility.InstantiatePrefab(simulatedPlanePrefab, planesRoot)).GetComponent <SynthesizedPlane>(); synthesizedPlane.transform.SetWorldPose(plane.pose); synthesizedPlane.SetMRPlaneData(plane.vertices, plane.center, plane.extents); synthesizedPlane.transform.SetParent(planesRoot, true); var renderer = synthesizedPlane.GetComponentInChildren <Renderer>(); renderer.AddMaterial(simulatedPlaneMaterial); } var meshCapture = environment.MeshCapture; if (meshCapture.Meshes.Count > 0) { var meshesRoot = new GameObject("Meshes").transform; meshesRoot.SetParent(prefabRoot, false); var meshPath = EditorUtility.SaveFilePanelInProject(k_SaveMeshDialogTitle, environmentName, "asset", string.Empty); var index = 0; foreach (var segment in meshCapture.Meshes) { var meshFilter = UnityObject.Instantiate(meshPrefab, meshesRoot); var mesh = new Mesh { name = $"Mesh Segment {index}" }; mesh.SetVertices(segment.Vertices); mesh.SetIndices(segment.Indices, MeshTopology.Triangles, 0); mesh.SetNormals(segment.Normals); meshFilter.transform.SetWorldPose(segment.Pose); meshFilter.sharedMesh = mesh; if (index == 0) { AssetDatabase.CreateAsset(mesh, meshPath); AssetDatabase.SetMainObject(mesh, meshPath); } else { AssetDatabase.AddObjectToAsset(mesh, meshPath); } index++; } AssetDatabase.SaveAssets(); } var environmentBounds = BoundsUtils.GetBounds(prefabRoot); var prefabRootGameObject = prefabRoot.gameObject; var environmentSettings = prefabRootGameObject.AddComponent <MARSEnvironmentSettings>(); var environmentInfo = environmentSettings.EnvironmentInfo; environmentInfo.EnvironmentBounds = environmentBounds; center = environmentBounds.center; var extents = environmentBounds.extents * 0.9f; // Reduce offset to avoid sim starting pose warning environmentInfo.DefaultCameraPivot = center; var cameraPose = new Pose(center + extents, Quaternion.LookRotation(-extents)); environmentInfo.DefaultCameraWorldPose = cameraPose; environmentInfo.DefaultCameraSize = environmentBounds.size.magnitude; environmentSettings.SetSimulationStartingPose(cameraPose, false); environmentSettings.UpdatePrefabInfo(); UnityObject.Instantiate(simulatedLightingPrefab, prefabRoot); var prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(prefabRootGameObject, path, InteractionMode.AutomatedAction); UnityObject.DestroyImmediate(prefabRootGameObject); AssetDatabase.SetLabels(prefab, new[] { MARSEnvironmentManager.EnvironmentLabel }); ModuleLoaderCore.instance.GetModule <MARSEnvironmentManager>().UpdateSimulatedEnvironmentCandidates(); callback(prefab); CollectionPool <List <Post>, Post> .RecycleCollection(posts); }