protected override void OnUpdate() { //Debug.Log("ACTIVE_CAMERA:" + ActiveCamera + " STATIC_CAMERA:" + HyperposStaticReferences.MainCamera); if (ActiveCameras[0] == null) { ActiveCameras[0] = HyperposStaticReferences.MainCamera; ActiveCameras[1] = HyperposStaticReferences.HyperdistCamera; } else { m_Planes = new FrustumPlanes(ActiveCameras[0]); UpdateMissingVisibleLocalToWorld(); Profiler.BeginSample("UpdateFrozenChunkCache"); UpdateFrozenChunkCache(); Profiler.EndSample(); Profiler.BeginSample("UpdateDynamicChunkCache"); UpdateDynamicChunkCache(); Profiler.EndSample(); Profiler.BeginSample("UpdateFrozenInstanceRenderer"); UpdateFrozenInstanceRenderer(); Profiler.EndSample(); Profiler.BeginSample("UpdateDynamicInstanceRenderer"); UpdateDynamicInstanceRenderer(); Profiler.EndSample(); } }
public void FrustumFromCamera_PlaneDistance(float zPosition) { var gameObject = new GameObject(); var camera = gameObject.AddComponent <Camera>(); var nearClipPlane = 0.3f; var farClipPlane = 1000f; camera.nearClipPlane = nearClipPlane; camera.farClipPlane = farClipPlane; gameObject.transform.position = new float3(0, 0, zPosition); using (var planes = new NativeArray <float4>(6, Allocator.Temp)) { FrustumPlanes.FromCamera(camera, planes); var nearPlane = planes[4]; var farPlane = planes[5]; Assert.That(nearPlane.w, Is.EqualTo(-nearClipPlane - zPosition).Within(1e-3f)); Assert.That(farPlane.w, Is.EqualTo(farClipPlane + zPosition).Within(1e-3f)); } UnityEngine.Object.DestroyImmediate(gameObject); }
public static void DrawFrustum(FrustumPlanes frustum) { if (frustum.zFar <= 0) return; var p0 = new Vector3(frustum.left, frustum.top, frustum.zFar); var p1 = new Vector3(frustum.right, frustum.top, frustum.zFar); var p2 = new Vector3(frustum.right, frustum.bottom, frustum.zFar); var p3 = new Vector3(frustum.left, frustum.bottom, frustum.zFar); Gizmos.DrawLine(p0, p1); Gizmos.DrawLine(p1, p2); Gizmos.DrawLine(p2, p3); Gizmos.DrawLine(p3, p0); var f = frustum.zNear > 0 && frustum.zNear < frustum.zFar ? frustum.zNear / frustum.zFar : 0; f = 1 - f; Gizmos.DrawRay(p0, -p0 * f); Gizmos.DrawRay(p1, -p1 * f); Gizmos.DrawRay(p2, -p2 * f); Gizmos.DrawRay(p3, -p3 * f); f = 1 - f; if(f > 0) { p0 *= f; p1 *= f; p2 *= f; p3 *= f; Gizmos.DrawLine(p0, p1); Gizmos.DrawLine(p1, p2); Gizmos.DrawLine(p2, p3); Gizmos.DrawLine(p3, p0); } }
public static void DrawFrustum(FrustumPlanes frustum, bool orthographic, Matrix4x4 transform) { var verts = new Vector3[] { new Vector3(frustum.left, frustum.bottom, frustum.zNear), new Vector3(frustum.right, frustum.bottom, frustum.zNear), new Vector3(frustum.right, frustum.top, frustum.zNear), new Vector3(frustum.left, frustum.top, frustum.zNear), new Vector3(frustum.left, frustum.bottom, frustum.zNear), }; if (orthographic) { var extend = Vector3.forward * (frustum.zFar - frustum.zNear); for (var i = 0; i < 4; i++) { Debug.DrawLine(transform.MultiplyPoint(verts[i]), transform.MultiplyPoint(verts[i + 1]), Color.yellow); Debug.DrawLine(transform.MultiplyPoint(verts[i]), transform.MultiplyPoint(verts[i] + extend), Color.green); Debug.DrawLine(transform.MultiplyPoint(verts[i] + extend), transform.MultiplyPoint(verts[i + 1] + extend), Color.green); } } else { for (var i = 0; i < 4; i++) { Debug.DrawLine(transform.MultiplyPoint(verts[i]), transform.MultiplyPoint(verts[i + 1]), Color.yellow); Debug.DrawLine(transform.MultiplyPoint(verts[i]), transform.MultiplyPoint(verts[i] * frustum.zFar / frustum.zNear), Color.green); Debug.DrawLine(transform.MultiplyPoint(verts[i] * frustum.zFar / frustum.zNear), transform.MultiplyPoint(verts[i + 1] * frustum.zFar / frustum.zNear), Color.green); } } }
public static bool IsInFrustum(Vector3 p, FrustumPlanes frustum) { if (p.z <= frustum.zNear || p.z >= frustum.zFar) { return(false); } var nor = TopNormalDir(frustum); if (Vector3.Dot(p, nor) >= 0) { return(false); } nor = DownNormalDir(frustum); if (Vector3.Dot(p, nor) >= 0) { return(false); } nor = RightNormalDir(frustum); if (Vector3.Dot(p, nor) >= 0) { return(false); } nor = LeftNormalDir(frustum); if (Vector3.Dot(p, nor) >= 0) { return(false); } return(true); }
private void OnPreCull() { if (-1 != viosoID) { Vector3 pos = new Vector3(0, 0, 0); Vector3 rot = new Vector3(0, 0, 0); Matrix4x4 mV = Matrix4x4.identity; Matrix4x4 mP = new Matrix4x4(); FrustumPlanes pl = new FrustumPlanes(); if (ERROR.NONE == GetViewClip(viosoID, ref pos, ref rot, ref mV, ref pl)) { mV = mV.transpose; Quaternion q = mV.rotation; Vector3 p = mV.GetColumn(3); cam.transform.localRotation = orig_rot * q; cam.transform.localPosition = orig_pos + p; mP = Matrix4x4.Frustum(pl); cam.projectionMatrix = mP; } else { Debug.Log("Failed to get initialized camera. Stoping warper. For detailed information see VIOSOWarpBlend.log"); viosoID = -1; } } }
// Modify the pointer location and orientation to point along the shortest rotation, // toward tergetPosition, keeping the pointer confined inside the frustum defined by // planes. private void UpdatePointerTransform(Camera camera, Plane[] planes, Vector3 targetPosition) { // Use the camera information to create the new bounding volume UpdateIndicatorVolume(camera); // Start by assuming the pointer should be placed at the target position. Vector3 indicatorPosition = cameraPosition + Depth * (targetPosition - cameraPosition).normalized; // Test the target position with the frustum planes except the "far" plane since // far away objects should be considered in view. bool pointNotInsideIndicatorField = false; for (int i = 0; i < 5; ++i) { float dot = Vector3.Dot(planes[i].normal, (targetPosition - cameraPosition).normalized); if (dot <= 0.0f) { pointNotInsideIndicatorField = true; break; } } // if the target object appears outside the indicator area... if (pointNotInsideIndicatorField) { // ...then we need to do some geometry calculations to lock it to the edge. // used to determine which edge of the screen the indicator vector // would exit through. FrustumPlanes exitPlane = GetExitPlane(targetPosition, camera); Ray r; if (TryGetIndicatorPosition(targetPosition, planes[(int)exitPlane], out r)) { indicatorPosition = cameraPosition + Depth * r.direction.normalized; } } this.transform.position = indicatorPosition; // The pointer's direction should always appear pointing away from the user's center // of view. Thus we find the center point of the user's view in world space. // But the pointer should also appear perpendicular to the viewer so we find the // center position of the view that is on the same plane as the pointer position. // We do this by projecting the vector from the pointer to the camera onto the // the camera's forward vector. Vector3 indicatorFieldOffset = indicatorPosition - cameraPosition; indicatorFieldOffset = Vector3.Dot(indicatorFieldOffset, cameraForward) * cameraForward; Vector3 indicatorFieldCenter = cameraPosition + indicatorFieldOffset; Vector3 pointerDirection = (indicatorPosition - indicatorFieldCenter).normalized; // allign this object's up vector with the pointerDirection this.transform.rotation = Quaternion.LookRotation(cameraForward, pointerDirection); }
public void MultiPlaneTest(int planeCount) { using (var par = CreatePlanes(planeCount)) using (var soap = FrustumPlanes.BuildSOAPlanePackets(par, Allocator.Temp)) { foreach (var box in boxes) { Assert.AreEqual(ReferenceTest(par, box), FrustumPlanes.Intersect2(soap, box)); } } }
public static Matrix4x4 GenerateJitteredProjectionMatrixFromOriginal(PostProcessRenderContext context, Matrix4x4 origProj, Vector2 jitter) { FrustumPlanes decomposeProjection = origProj.decomposeProjection; float num = Math.Abs(decomposeProjection.top) + Math.Abs(decomposeProjection.bottom); float num2 = Math.Abs(decomposeProjection.left) + Math.Abs(decomposeProjection.right); Vector2 vector = new Vector2(jitter.x * num2 / (float)context.screenWidth, jitter.y * num / (float)context.screenHeight); decomposeProjection.left += vector.x; decomposeProjection.right += vector.x; decomposeProjection.top += vector.y; decomposeProjection.bottom += vector.y; return(Matrix4x4.Frustum(decomposeProjection)); }
/// <summary> /// Converts the ZFrustumBounds struct to Unity's corresponding /// FrustumPlanes struct. /// </summary> /// /// <returns> /// FrustumPlanes initialized based on the current state of the /// ZFrustumBounds. /// </returns> public FrustumPlanes ToFrustumPlanes() { FrustumPlanes frustumPlanes = new FrustumPlanes(); frustumPlanes.left = this.left; frustumPlanes.right = this.right; frustumPlanes.bottom = this.bottom; frustumPlanes.top = this.top; frustumPlanes.zNear = this.nearClip; frustumPlanes.zFar = this.farClip; return(frustumPlanes); }
private FrustumPlanes.IntersectResult ReferenceTest(NativeArray <Plane> par, AABB box) { FrustumPlanes.IntersectResult result; var temp = new NativeArray <float4>(par.Length, Allocator.Temp); for (int i = 0; i < par.Length; ++i) { temp[i] = new float4(par[i].normal, par[i].distance); } result = FrustumPlanes.Intersect(temp, box); temp.Dispose(); return(result); }
public static FrustumPlanes BestfitFrustum(bool orthographic, Matrix4x4 transform, params Vector3[] verts) { FrustumPlanes frustum = new FrustumPlanes() { left = float.MaxValue, right = float.MinValue, bottom = float.MaxValue, top = float.MinValue, zNear = float.MaxValue, zFar = float.MinValue, }; if (orthographic) { for (var i = 0; i < verts.Length; i++) { var transformedP = transform.MultiplyPoint(verts[i]); frustum.left = Mathf.Min(frustum.left, transformedP.x); frustum.bottom = Mathf.Min(frustum.bottom, transformedP.y); frustum.zNear = Mathf.Min(frustum.zNear, transformedP.z); frustum.right = Mathf.Max(frustum.right, transformedP.x); frustum.top = Mathf.Max(frustum.top, transformedP.y); frustum.zFar = Mathf.Max(frustum.zFar, transformedP.z); } } else { //单位框 for (var i = 0; i < verts.Length; i++) { var transformedP = transform.MultiplyPoint(verts[i]); frustum.left = Mathf.Min(frustum.left, transformedP.x / transformedP.z); frustum.right = Mathf.Max(frustum.right, transformedP.x / transformedP.z); frustum.bottom = Mathf.Min(frustum.bottom, transformedP.y / transformedP.z); frustum.top = Mathf.Max(frustum.top, transformedP.y / transformedP.z); frustum.zNear = Mathf.Min(frustum.zNear, transformedP.z); frustum.zFar = Mathf.Max(frustum.zFar, transformedP.z); } //单位框 缩放 near frustum.left *= frustum.zNear; frustum.right *= frustum.zNear; frustum.bottom *= frustum.zNear; frustum.top *= frustum.zNear; } return(frustum); }
public static int constructor(IntPtr l) { int result; try { FrustumPlanes frustumPlanes = default(FrustumPlanes); LuaObject.pushValue(l, true); LuaObject.pushValue(l, frustumPlanes); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static void UpdateProjection(Camera cam, List <Vector3> posList) { var nearPosList = posList .Select(wPos => WorldPosToNearPos(cam, wPos)) .ToList(); var xList = nearPosList.Select(p => p.x); var yList = nearPosList.Select(p => p.y); var frustum = new FrustumPlanes() { left = xList.Min(), right = xList.Max(), bottom = yList.Min(), top = yList.Max(), zNear = cam.nearClipPlane, zFar = cam.farClipPlane }; // rect のはみ出てる部分は自動的に範囲内に収まるようなのでfrustrumでクリップする var rect = cam.rect; if (rect.xMin < 0f) { frustum.left *= 0.5f / Mathf.Abs(rect.xMin - 0.5f); } if (rect.xMax > 1f) { frustum.right *= 0.5f / Mathf.Abs(rect.xMax - 0.5f); } if (rect.yMin < 0f) { frustum.bottom *= 0.5f / Mathf.Abs(rect.yMin - 0.5f); } if (rect.yMax > 1f) { frustum.top *= 0.5f / Mathf.Abs(rect.yMax - 0.5f); } cam.projectionMatrix = Matrix4x4.Frustum(frustum); }
public DeferredTiler(int tilePixelWidth, int tilePixelHeight, int avgLightPerTile, int tilerLevel) { m_TilePixelWidth = tilePixelWidth; m_TilePixelHeight = tilePixelHeight; m_TileXCount = 0; m_TileYCount = 0; // Finest tiler (at index 0) computes extra tile data stored into the header, so it requires more space. See CullFinalLights() vs CullIntermediateLights(). // Finest tiler: lightListOffset, lightCount, listDepthRange, listBitMask // Coarse tilers: lightListOffset, lightCount m_TileHeaderSize = tilerLevel == 0 ? 4 : 2; m_AvgLightPerTile = avgLightPerTile; m_TilerLevel = tilerLevel; m_FrustumPlanes = new FrustumPlanes { left = 0, right = 0, bottom = 0, top = 0, zNear = 0, zFar = 0 }; m_IsOrthographic = false; m_Counters = new NativeArray <int>(); m_TileData = new NativeArray <ushort>(); m_TileHeaders = new NativeArray <uint>(); m_PreTiles = new NativeArray <PreTile>(); }
private void OnPreCull() { if (-1 != viosoID) { Vector3 pos = new Vector3(0, 0, 0); Vector3 rot = new Vector3(0, 0, 0); Matrix4x4 mV = Matrix4x4.identity; Matrix4x4 mP = new Matrix4x4(); FrustumPlanes pl = new FrustumPlanes(); if (ERROR.NONE == GetViewClip(viosoID, ref pos, ref rot, ref mV, ref pl)) { mV = mV.transpose; Quaternion q = mV.rotation; Vector3 p = mV.GetColumn(3); cam.transform.localRotation = orig_rot * q; cam.transform.localPosition = orig_pos + p; mP = Matrix4x4.Frustum(pl); cam.projectionMatrix = mP; } } }
public static Vector3 LeftNormalDir(FrustumPlanes frustum) { return(new Vector3(frustum.zFar * frustum.bottom - frustum.zFar * frustum.top, 0, frustum.left * frustum.top - frustum.left * frustum.bottom)); }
public static Vector3 RightNormalDir(FrustumPlanes frustum) { return(new Vector3(frustum.zFar * frustum.top - frustum.zFar * frustum.bottom, 0, frustum.right * frustum.bottom - frustum.right * frustum.top)); }
public static Vector3 DownNormalDir(FrustumPlanes frustum) { return(new Vector3(0, frustum.zFar * frustum.left - frustum.zFar * frustum.right, frustum.right * frustum.bottom - frustum.left * frustum.bottom)); }
// not normalized public static Vector3 TopNormalDir(FrustumPlanes frustum) { return(new Vector3(0, frustum.zFar * frustum.right - frustum.zFar * frustum.left, frustum.left * frustum.top - frustum.right * frustum.top)); }
public void PrecomputeTiles(Matrix4x4 proj, bool isOrthographic, int renderWidth, int renderHeight) { m_TileXCount = (renderWidth + m_TilePixelWidth - 1) / m_TilePixelWidth; m_TileYCount = (renderHeight + m_TilePixelHeight - 1) / m_TilePixelHeight; m_PreTiles = DeferredShaderData.instance.GetPreTiles(m_TilerLevel, m_TileXCount * m_TileYCount); // Adjust render width and height to account for tile size expanding over the screen (tiles have a fixed pixel size). int adjustedRenderWidth = Align(renderWidth, m_TilePixelWidth); int adjustedRenderHeight = Align(renderHeight, m_TilePixelHeight); // Now adjust the right and bottom clipping planes. m_FrustumPlanes = proj.decomposeProjection; m_FrustumPlanes.right = m_FrustumPlanes.left + (m_FrustumPlanes.right - m_FrustumPlanes.left) * (adjustedRenderWidth / (float)renderWidth); m_FrustumPlanes.bottom = m_FrustumPlanes.top + (m_FrustumPlanes.bottom - m_FrustumPlanes.top) * (adjustedRenderHeight / (float)renderHeight); m_IsOrthographic = isOrthographic; // Tile size in world units. float tileWidthWS = (m_FrustumPlanes.right - m_FrustumPlanes.left) / m_TileXCount; float tileHeightWS = (m_FrustumPlanes.top - m_FrustumPlanes.bottom) / m_TileYCount; if (!isOrthographic) // perspective { for (int j = 0; j < m_TileYCount; ++j) { float tileTop = m_FrustumPlanes.top - tileHeightWS * j; float tileBottom = tileTop - tileHeightWS; for (int i = 0; i < m_TileXCount; ++i) { float tileLeft = m_FrustumPlanes.left + tileWidthWS * i; float tileRight = tileLeft + tileWidthWS; // Camera view space is always OpenGL RH coordinates system. // In view space with perspective projection, all planes pass by (0,0,0). PreTile preTile; preTile.planeLeft = MakePlane(new float3(tileLeft, tileBottom, -m_FrustumPlanes.zNear), new float3(tileLeft, tileTop, -m_FrustumPlanes.zNear)); preTile.planeRight = MakePlane(new float3(tileRight, tileTop, -m_FrustumPlanes.zNear), new float3(tileRight, tileBottom, -m_FrustumPlanes.zNear)); preTile.planeBottom = MakePlane(new float3(tileRight, tileBottom, -m_FrustumPlanes.zNear), new float3(tileLeft, tileBottom, -m_FrustumPlanes.zNear)); preTile.planeTop = MakePlane(new float3(tileLeft, tileTop, -m_FrustumPlanes.zNear), new float3(tileRight, tileTop, -m_FrustumPlanes.zNear)); m_PreTiles[i + j * m_TileXCount] = preTile; } } } else { for (int j = 0; j < m_TileYCount; ++j) { float tileTop = m_FrustumPlanes.top - tileHeightWS * j; float tileBottom = tileTop - tileHeightWS; for (int i = 0; i < m_TileXCount; ++i) { float tileLeft = m_FrustumPlanes.left + tileWidthWS * i; float tileRight = tileLeft + tileWidthWS; // Camera view space is always OpenGL RH coordinates system. PreTile preTile; preTile.planeLeft = MakePlane(new float3(tileLeft, tileBottom, -m_FrustumPlanes.zNear), new float3(tileLeft, tileBottom, -m_FrustumPlanes.zNear - 1.0f), new float3(tileLeft, tileTop, -m_FrustumPlanes.zNear)); preTile.planeRight = MakePlane(new float3(tileRight, tileTop, -m_FrustumPlanes.zNear), new float3(tileRight, tileTop, -m_FrustumPlanes.zNear - 1.0f), new float3(tileRight, tileBottom, -m_FrustumPlanes.zNear)); preTile.planeBottom = MakePlane(new float3(tileRight, tileBottom, -m_FrustumPlanes.zNear), new float3(tileRight, tileBottom, -m_FrustumPlanes.zNear - 1.0f), new float3(tileLeft, tileBottom, -m_FrustumPlanes.zNear)); preTile.planeTop = MakePlane(new float3(tileLeft, tileTop, -m_FrustumPlanes.zNear), new float3(tileLeft, tileTop, -m_FrustumPlanes.zNear - 1.0f), new float3(tileRight, tileTop, -m_FrustumPlanes.zNear)); m_PreTiles[i + j * m_TileXCount] = preTile; } } } }
//////////////////////////////////////////////////////////////////////// // Public Extension Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Converts Unity's FrustumPlanes data structure to the zSpace /// SDK's ZFrustumBounds data structure. /// </summary> /// /// <returns> /// ZFrustumBounds initialized based on the current state of /// the FrustumPlanes. /// </returns> public static ZFrustumBounds ToZFrustumBounds(this FrustumPlanes f) { return(new ZFrustumBounds( f.left, f.right, f.bottom, f.top, f.zNear, f.zFar)); }
private static extern ERROR GetViewClip(int id, ref Vector3 pos, ref Vector3 rot, ref Matrix4x4 view, ref FrustumPlanes clip);
// Modify the pointer location and orientation to point along the shortest rotation, // toward tergetPosition, keeping the pointer confined inside the frustum defined by // planes. private void UpdatePointerTransform(Camera camera, Plane[] planes, Vector3 targetPosition) { // Use the camera information to create the new bounding volume UpdateIndicatorVolume(camera); // Start by assuming the pointer should be placed at the target position. Vector3 indicatorPosition = cameraPosition + Depth * (targetPosition - cameraPosition).normalized; // Test the target position with the frustum planes except the "far" plane since // far away objects should be considered in view. bool pointNotInsideIndicatorField = false; for (int i = 0; i < 5; ++i) { float dot = Vector3.Dot(planes[i].normal, (targetPosition - cameraPosition).normalized); if (dot <= 0.0f) { pointNotInsideIndicatorField = true; break; } } // if the target object appears outside the Indicator area... if (pointNotInsideIndicatorField) { // ...then we need to do some geometry calculations to lock it to the edge. // used to determine which edge of the screen the Indicator vector // would exit through. FrustumPlanes exitPlane = GetExitPlane(targetPosition, camera); Ray r; if (TryGetIndicatorPosition(targetPosition, planes[(int)exitPlane], out r)) { indicatorPosition = cameraPosition + Depth * r.direction.normalized; } } this.transform.position = indicatorPosition; // The pointer's direction should always appear pointing away from the user's center // of view. Thus we find the center point of the user's view in world space. // But the pointer should also appear perpendicular to the viewer so we find the // center position of the view that is on the same plane as the pointer position. // We do this by projecting the vector from the pointer to the camera onto the // the camera's forward vector. Vector3 indicatorFieldOffset = indicatorPosition - cameraPosition; indicatorFieldOffset = Vector3.Dot(indicatorFieldOffset, cameraForward) * cameraForward; Vector3 indicatorFieldCenter = cameraPosition + indicatorFieldOffset; Vector3 pointerDirection = (indicatorPosition - indicatorFieldCenter).normalized; // allign this object's up vector with the pointerDirection this.transform.rotation = Quaternion.LookRotation(cameraForward, pointerDirection); //ADDED FROM MYSELF !!!!!! --> This code shows the frustrum as pink plane if color of line renderer is white when second positions parameter is Indicator position GameObject line = GameObject.Find("LineRenderer"); GameObject cursor = GameObject.Find("DefaultCursor"); Vector3 cursorPosition = cursor.transform.position; Vector3[] positions = new[] { cursorPosition, indicatorPosition }; line.GetComponent <LineRenderer>().SetPositions(positions); // Vector3 scalesOldArrow = new Vector3(0.1f, 0.1f, 0.1f); // this.transform.localScale = scalesOldArrow; // pointer2.transform.position = cursorPosition; //CODE FROM MYSELF TILL HERE }