static int _CreateGeometryUtility(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 0) { GeometryUtility obj = new GeometryUtility(); LuaScriptMgr.PushObject(L, obj); return 1; } else { LuaDLL.luaL_error(L, "invalid arguments to method: GeometryUtility.New"); } return 0; }
bool CanSeePlayer(Bounds player_bounds) { Plane[] frustum_planes = GeometryUtility.CalculateFrustumPlanes(view_cam); return(GeometryUtility.TestPlanesAABB(frustum_planes, player_bounds)); }
public static bool IsVisibleFrom(this Renderer renderer, Camera camera) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera); return(GeometryUtility.TestPlanesAABB(planes, renderer.bounds)); }
protected virtual bool CalculateTagalongTargetPosition(Vector3 fromPosition, out Vector3 toPosition) { // Check to see if any part of the Tagalong's BoxCollider's bounds is // inside the camera's view frustum. Note, the bounds used are an Axis // Aligned Bounding Box (AABB). bool needsToMove = !GeometryUtility.TestPlanesAABB(frustumPlanes, tagAlongCollider.bounds); // Calculate a default position where the Tagalong should go. In this // case TagalongDistance from the camera along the gaze vector. toPosition = Camera.main.transform.position + Camera.main.transform.forward * tagAlongDistance; // If we already know we don't need to move, bail out early. if (!needsToMove) { return(false); } // Create a Ray and set it's origin to be the default toPosition that // was calculated above. Ray ray = new Ray(toPosition, Vector3.zero); Plane plane = new Plane(); float distanceOffset = 0f; // Determine if the Tagalong needs to move to the right or the left // to get back inside the camera's view frustum. The normals of the // planes that make up the camera's view frustum point inward. bool moveRight = frustumPlanes[frustumLeft].GetDistanceToPoint(fromPosition) < 0; bool moveLeft = frustumPlanes[frustumRight].GetDistanceToPoint(fromPosition) < 0; if (moveRight) { // If the Tagalong needs to move to the right, that means it is to // the left of the left frustum plane. Remember that plane and set // our Ray's direction to point towards that plane (remember the // Ray's origin is already inside the view frustum. plane = frustumPlanes[frustumLeft]; ray.direction = -Camera.main.transform.right; } else if (moveLeft) { // Apply similar logic to above for the case where the Tagalong // needs to move to the left. plane = frustumPlanes[frustumRight]; ray.direction = Camera.main.transform.right; } if (moveRight || moveLeft) { // If the Tagalong needed to move in the X direction, cast a Ray // from the default position to the plane we are working with. plane.Raycast(ray, out distanceOffset); // Get the point along that ray that is on the plane and update // the x component of the Tagalong's desired position. toPosition.x = ray.GetPoint(distanceOffset).x; } // Similar logic follows below for determining if and how the // Tagalong would need to move up or down. bool moveDown = frustumPlanes[frustumTop].GetDistanceToPoint(fromPosition) < 0; bool moveUp = frustumPlanes[frustumBottom].GetDistanceToPoint(fromPosition) < 0; if (moveDown) { plane = frustumPlanes[frustumTop]; ray.direction = Camera.main.transform.up; } else if (moveUp) { plane = frustumPlanes[frustumBottom]; ray.direction = -Camera.main.transform.up; } if (moveUp || moveDown) { plane.Raycast(ray, out distanceOffset); toPosition.y = ray.GetPoint(distanceOffset).y; } // Create a ray that starts at the camera and points in the direction // of the calculated toPosition. ray = new Ray(Camera.main.transform.position, toPosition - Camera.main.transform.position); // Find the point along that ray that is the right distance away and // update the calculated toPosition to be that point. toPosition = ray.GetPoint(tagAlongDistance); // If we got here, needsToMove will be true. return(needsToMove); }
public static bool IsVisible(GameObject @object) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main); return(GeometryUtility.TestPlanesAABB(planes, @object.GetComponent <Collider2D>().bounds)); }
// We have to use OnPreCull or OnPreRender as otherwise particlesystems will make unity crash //void OnPreCull () { void OnPreRender() { #if UNITY_EDITOR if (!Application.isPlaying) { if (defaultBump == null) { defaultBump = new Texture2D(1, 1, TextureFormat.RGBA32, false); defaultBump.SetPixel(0, 0, new Color(0.5f, 0.5f, 1.0f, 0.5f).gamma); defaultBump.Apply(false); } Shader.SetGlobalTexture(_LuxWater_NormalOverlayPID, defaultBump); Shader.SetGlobalTexture(_LuxWater_FoamOverlayPID, Texture2D.blackTexture); return; } #endif cam = GetComponent <Camera>(); #if UNITY_EDITOR if (UnityEditor.SceneView.currentDrawingSceneView != null && UnityEditor.SceneView.currentDrawingSceneView.camera == cam) { // Shader.DisableKeyword("USINGWATERPROJECTORS"); return; } #endif // Check if we have to do anything var numFoamProjectors = LuxWater_Projector.FoamProjectors.Count; var numNormalProjectors = LuxWater_Projector.NormalProjectors.Count; // No registered projectors if (numFoamProjectors + numNormalProjectors == 0) { if (cb_Foam != null) { cb_Foam.Clear(); } if (cb_Normals != null) { cb_Normals.Clear(); } Shader.DisableKeyword("USINGWATERPROJECTORS"); return; } else { Shader.EnableKeyword("USINGWATERPROJECTORS"); } var projectionMatrix = cam.projectionMatrix; var worldToCameraMatrix = cam.worldToCameraMatrix; var worldToProjectionMatrix = projectionMatrix * worldToCameraMatrix; var camPixelWidth = cam.pixelWidth; var camPixelHeight = cam.pixelHeight; //UnityEngine.Profiling.Profiler.BeginSample("Get Planes"); GeomUtil.CalculateFrustumPlanes(frustumPlanes, worldToProjectionMatrix); //UnityEngine.Profiling.Profiler.EndSample(); // Foam Buffer var rtWidth = Mathf.FloorToInt(camPixelWidth / (int)FoamBufferResolution); var rtHeight = Mathf.FloorToInt(camPixelHeight / (int)FoamBufferResolution); // Check if buffer's rt has to be created/updated if (!ProjectedFoam) { ProjectedFoam = new RenderTexture(rtWidth, rtHeight, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); Shader.SetGlobalTexture(_LuxWater_FoamOverlayPID, ProjectedFoam); } else if (ProjectedFoam.width != rtWidth) { DestroyImmediate(ProjectedFoam); ProjectedFoam = new RenderTexture(rtWidth, rtHeight, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); // We have to reassign the texture (prevented projectors from being updated after pause) Shader.SetGlobalTexture(_LuxWater_FoamOverlayPID, ProjectedFoam); } GL.PushMatrix(); GL.modelview = worldToCameraMatrix; GL.LoadProjectionMatrix(projectionMatrix); cb_Foam.Clear(); cb_Foam.SetRenderTarget(ProjectedFoam); cb_Foam.ClearRenderTarget(true, true, new Color(0, 0, 0, 0), 1.0f); //Shader.SetGlobalTexture(_CameraDepthTexturePID, Texture2D.whiteTexture); drawnFoamProjectors = 0; for (int i = 0; i < numFoamProjectors; i++) { // Check renderer's bounds against frustum before calling DrawRenderer var currentProjector = LuxWater_Projector.FoamProjectors[i]; tempBounds = currentProjector.m_Rend.bounds; if (GeometryUtility.TestPlanesAABB(frustumPlanes, tempBounds)) { cb_Foam.DrawRenderer(currentProjector.m_Rend, currentProjector.m_Mat); drawnFoamProjectors++; } } Graphics.ExecuteCommandBuffer(cb_Foam); // Normal Buffer rtWidth = Mathf.FloorToInt(camPixelWidth / (int)NormalBufferResolution); rtHeight = Mathf.FloorToInt(camPixelHeight / (int)NormalBufferResolution); // Check if buffer's rt has to be created/updated if (!ProjectedNormals) { ProjectedNormals = new RenderTexture(rtWidth, rtHeight, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear); Shader.SetGlobalTexture(_LuxWater_NormalOverlayPID, ProjectedNormals); } else if (ProjectedNormals.width != rtWidth) { DestroyImmediate(ProjectedNormals); ProjectedNormals = new RenderTexture(rtWidth, rtHeight, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear); // We have to reassign the texture (prevented projectors from being updated after pause) Shader.SetGlobalTexture(_LuxWater_NormalOverlayPID, ProjectedNormals); } cb_Normals.Clear(); cb_Normals.SetRenderTarget(ProjectedNormals); // Regular ARGB buffer // cb_Normals.ClearRenderTarget(true, true, new Color(0.5f,0.5f,1.0f,0.5f), 1.0f); // ARGBHalf buffer cb_Normals.ClearRenderTarget(true, true, new Color(0.0f, 0.0f, 1.0f, 0.0f), 1.0f); drawnNormalProjectors = 0; for (int i = 0; i < numNormalProjectors; i++) { // Check renderer's bounds against frustum before calling DrawRenderer var currentProjector = LuxWater_Projector.NormalProjectors[i]; tempBounds = currentProjector.m_Rend.bounds; if (GeometryUtility.TestPlanesAABB(frustumPlanes, tempBounds)) { cb_Normals.DrawRenderer(currentProjector.m_Rend, currentProjector.m_Mat); drawnNormalProjectors++; } } Graphics.ExecuteCommandBuffer(cb_Normals); GL.PopMatrix(); }
private void LookForYandere() { float num = Vector3.Distance(base.transform.position, this.Yandere.transform.position); if (num < this.VisionCone.farClipPlane) { if (GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(this.VisionCone), this.Yandere.GetComponent <Collider>().bounds)) { Vector3 end = new Vector3(this.Yandere.transform.position.x, this.Yandere.Head.position.y, this.Yandere.transform.position.z); RaycastHit raycastHit; if (Physics.Linecast(this.Eyes.transform.position, end, out raycastHit)) { if (raycastHit.collider.gameObject == this.Yandere.gameObject) { if (this.Yandere.Pickpocketing) { if (!this.ClubLeader.Angry) { this.Alarm = Mathf.MoveTowards(this.Alarm, 100f, Time.deltaTime * (100f / num)); if (this.Alarm == 100f) { this.PickpocketMinigame.NotNurse = true; this.PickpocketMinigame.End(); this.ClubLeader.Punish(); } } else { this.Alarm = Mathf.MoveTowards(this.Alarm, 0f, Time.deltaTime * 100f); } } else { this.Alarm = Mathf.MoveTowards(this.Alarm, 0f, Time.deltaTime * 100f); } } else { this.Alarm = Mathf.MoveTowards(this.Alarm, 0f, Time.deltaTime * 100f); } } else { this.Alarm = Mathf.MoveTowards(this.Alarm, 0f, Time.deltaTime * 100f); } } else { this.Alarm = Mathf.MoveTowards(this.Alarm, 0f, Time.deltaTime * 100f); } } this.DetectionMarker.Tex.transform.localScale = new Vector3(this.DetectionMarker.Tex.transform.localScale.x, this.Alarm / 100f, this.DetectionMarker.Tex.transform.localScale.z); if (this.Alarm > 0f) { if (!this.DetectionMarker.Tex.enabled) { this.DetectionMarker.Tex.enabled = true; } this.DetectionMarker.Tex.color = new Color(this.DetectionMarker.Tex.color.r, this.DetectionMarker.Tex.color.g, this.DetectionMarker.Tex.color.b, this.Alarm / 100f); return; } if (this.DetectionMarker.Tex.color.a != 0f) { this.DetectionMarker.Tex.enabled = false; this.DetectionMarker.Tex.color = new Color(this.DetectionMarker.Tex.color.r, this.DetectionMarker.Tex.color.g, this.DetectionMarker.Tex.color.b, 0f); } }
//A method for determining if a gameObject is visible to the camera. //I started using renderer.isVisible...but that failed to function correctly in at least one case. public bool IsInCamera(GameObject go) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(gameCamera); return(GeometryUtility.TestPlanesAABB(planes, go.GetComponent <Renderer>().bounds)); }
void Start() { // pos = transform.position; // ARcam = GameObject.Find ("Camera"); planes = GeometryUtility.CalculateFrustumPlanes(minimapCam); }
/// <summary> /// 检查对象渲染器是否在摄像机的可见范围内 /// </summary> /// <param name="renderer">渲染对象</param> /// <param name="camera">摄像机</param> /// <returns></returns> public static bool IsVisibleFrom(Bounds bound, Camera camera) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera); return(GeometryUtility.TestPlanesAABB(planes, bound)); }
public RecalculateShadowResult RecalculateShadow(Plane[] frustumPlanes, bool force) { _isVisible = _isStatic; // Determine whether the owner GameObject changed the active state // and react correspondingly bool isGameObjectActive = SS_Extensions.IsActiveInHierarchy(gameObject); if (isGameObjectActive != _isGameObjectActivePrev) { _isGameObjectActivePrev = isGameObjectActive; if (isGameObjectActive) { RegisterShadow(); return(RecalculateShadowResult.ChangedManager); } else { UnregisterShadow(); return(RecalculateShadowResult.ChangedManager); } } _isGameObjectActivePrev = isGameObjectActive; if (!isGameObjectActive) { return(RecalculateShadowResult.Skipped); } // Updating the transform state (position and forward vectors) // Determine whether the transform has moved Vector3 transformPosition = _transform.position; Vector3 transformForward = _transform.forward; bool transformChanged = false; if (_autoStaticTime > 0) { if (transformPosition.x != _transformPositionPrev.x || transformPosition.y != _transformPositionPrev.y || transformPosition.z != _transformPositionPrev.z || transformForward.x != _transformForwardPrev.x || transformForward.y != _transformForwardPrev.y || transformForward.z != _transformForwardPrev.z ) { _autoStaticTimeCounter = 0f; transformChanged = true; } _transformPositionPrev = transformPosition; _transformForwardPrev = transformForward; } if (!_isFirstCalculation) { // If we have AutoStatic if (_autoStaticTime > 0f) { // If the object has moved - remove the shadow // from static manager and move to non-static if (_isStatic && transformChanged) { UnregisterShadow(); _isStatic = false; RegisterShadow(); return(RecalculateShadowResult.ChangedManager); } // If the object hasn't moved for AutoStaticTime seconds, // then mark it as static _autoStaticTimeCounter += Time.deltaTime; if (!_isStatic && _autoStaticTimeCounter > _autoStaticTime) { UnregisterShadow(); _isStatic = true; RegisterShadow(); return(RecalculateShadowResult.ChangedManager); } } // Do not update static shadows by default if (_isStatic && !force) { return(RecalculateShadowResult.Skipped); } // Return if the time hasn't come yet if (_frameSkip != 0) { if (_frameSkipCounter < _frameSkip) { _frameSkipCounter++; return(RecalculateShadowResult.Skipped); } _frameSkipCounter = 0; } } // Is this our first update? _isFirstCalculation = false; // Determine the light source position bool useLightSource = _lightVectorSource == LightVectorSourceEnum.GameObject && _lightSourceObject != null; Vector3 lightSourcePosition = useLightSource ? _lightSourceObject.transform.position : new Vector3(); // The actual light direction vector that'll be used Vector3 actualLightVector; if (_lightVectorSource == LightVectorSourceEnum.GameObject && _lightSourceObject != null) { if (_lightSourceObjectIsDirectionalLight) { actualLightVector = _lightSourceObject.rotation * Vector3.forward; } else { actualLightVector.x = transformPosition.x - lightSourcePosition.x; actualLightVector.y = transformPosition.y - lightSourcePosition.y; actualLightVector.z = transformPosition.z - lightSourcePosition.z; actualLightVector = actualLightVector.FastNormalized(); } } else { actualLightVector = _lightVector; } _actualLightVectorPrev = actualLightVector; // Do a raycast from transform.position to the center of the shadow RaycastHit hitInfo; bool raycastResult = Physics.Raycast(transformPosition, actualLightVector, out hitInfo, _projectionDistance, _layerMask); if (raycastResult) { // Scale the shadow respectively Vector3 lossyScale = transform.lossyScale; float scaledDoubleShadowSize = Mathf.Max(Mathf.Max(lossyScale.x, lossyScale.y), lossyScale.z) * ShadowSize; if (!_isStatic && _cullInvisible) { // We can calculate approximate bounds for orthographic shadows easily // and cull shadows based on these bounds and camera frustum if (!_isPerspectiveProjection) { Bounds bounds = new Bounds(hitInfo.point, new Vector3(scaledDoubleShadowSize, scaledDoubleShadowSize, scaledDoubleShadowSize)); _isVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, bounds); if (!_isVisible) { return(RecalculateShadowResult.Skipped); } } else { // For perspective shadows, we can at least try to // not draw shadows that fall on invisible objects Transform hitTransform = hitInfo.collider.transform; if (frustumPlanes != null) { Renderer hitRenderer = hitTransform != null ? hitTransform.renderer : null; if (hitRenderer != null) { _isVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, hitRenderer.bounds); if (!_isVisible) { return(RecalculateShadowResult.Skipped); } } } } } // Calculate angle from light direction vector to surface normal _normal = hitInfo.normal; float angleToNormal = SS_Math.FastAcos(-Vector3.Dot(actualLightVector, _normal)) * Mathf.Rad2Deg; if (angleToNormal > _angleFadeMax) { // Skip shadows that fall with extreme angles _isVisible = false; return(RecalculateShadowResult.Skipped); } // Determine the forward direction of shadow base quad Vector3 forward; float dot = Vector3.Dot(transformForward, actualLightVector); if (Mathf.Abs(dot) < 1f - Vector3.kEpsilon) { forward = (transformForward - dot * actualLightVector).FastNormalized(); } else { // If the forward direction matches the light direction vector somehow Vector3 transformUp = _transform.up; forward = (transformUp - Vector3.Dot(transformUp, actualLightVector) * actualLightVector).FastNormalized(); } // Rotation of shadow base quad Quaternion rotation = Quaternion.LookRotation(forward, -actualLightVector); // Optimized version of // Vector3 right = rotation * Vector3.right; float num2 = rotation.y * 2f; float num3 = rotation.z * 2f; float num5 = rotation.y * num2; float num6 = rotation.z * num3; float num7 = rotation.x * num2; float num8 = rotation.x * num3; float num11 = rotation.w * num2; float num12 = rotation.w * num3; Vector3 right; right.x = 1f - (num5 + num6); right.y = num7 + num12; right.z = num8 - num11; // Base vertices calculation float scaledShadowSize = scaledDoubleShadowSize * 0.5f; float aspectRatioInv = 1f / _aspectRatio; Vector3 diff; diff.x = (forward.x - right.x * aspectRatioInv) * scaledShadowSize; diff.y = (forward.y - right.y * aspectRatioInv) * scaledShadowSize; diff.z = (forward.z - right.z * aspectRatioInv) * scaledShadowSize; Vector3 sum; sum.x = (forward.x + right.x * aspectRatioInv) * scaledShadowSize; sum.y = (forward.y + right.y * aspectRatioInv) * scaledShadowSize; sum.z = (forward.z + right.z * aspectRatioInv) * scaledShadowSize; Vector3 baseVertex; baseVertex.x = transformPosition.x - sum.x; baseVertex.y = transformPosition.y - sum.y; baseVertex.z = transformPosition.z - sum.z; _baseVertices[0] = baseVertex; baseVertex.x = transformPosition.x + diff.x; baseVertex.y = transformPosition.y + diff.y; baseVertex.z = transformPosition.z + diff.z; _baseVertices[1] = baseVertex; baseVertex.x = transformPosition.x + sum.x; baseVertex.y = transformPosition.y + sum.y; baseVertex.z = transformPosition.z + sum.z; _baseVertices[2] = baseVertex; baseVertex.x = transformPosition.x - diff.x; baseVertex.y = transformPosition.y - diff.y; baseVertex.z = transformPosition.z - diff.z; _baseVertices[3] = baseVertex; // Calculate a plane from normal and position SS_Plane shadowPlane = new SS_Plane(); shadowPlane.SetNormalAndPosition(_normal, hitInfo.point + _normal * _shadowOffset); float distanceToPlane; SS_Ray ray = new SS_Ray(); // Calculate the shadow vertices if (_isPerspectiveProjection && useLightSource) { ray.direction = lightSourcePosition - _baseVertices[0]; ray.origin = _baseVertices[0]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[0] = ray.origin + ray.direction * distanceToPlane; ray.direction = lightSourcePosition - _baseVertices[1]; ray.origin = _baseVertices[1]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[1] = ray.origin + ray.direction * distanceToPlane; ray.direction = lightSourcePosition - _baseVertices[2]; ray.origin = _baseVertices[2]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[2] = ray.origin + ray.direction * distanceToPlane; ray.direction = lightSourcePosition - _baseVertices[3]; ray.origin = _baseVertices[3]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[3] = ray.origin + ray.direction * distanceToPlane; } else { ray.direction = actualLightVector; ray.origin = _baseVertices[0]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[0] = ray.origin + ray.direction * distanceToPlane; ray.origin = _baseVertices[1]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[1] = ray.origin + ray.direction * distanceToPlane; ray.origin = _baseVertices[2]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[2] = ray.origin + ray.direction * distanceToPlane; ray.origin = _baseVertices[3]; shadowPlane.Raycast(ref ray, out distanceToPlane); _shadowVertices[3] = ray.origin + ray.direction * distanceToPlane; } // Calculate the shadow alpha float shadowAlpha = _initialAlpha; // Alpha base on distance to the surface float distance = hitInfo.distance; if (distance > _fadeDistance) { shadowAlpha = shadowAlpha - (distance - _fadeDistance) / (_projectionDistance - _fadeDistance) * shadowAlpha; } // Alpha based on shadow fall angle if (angleToNormal > _angleFadeMin) { shadowAlpha = shadowAlpha - (angleToNormal - _angleFadeMin) / (_angleFadeMax - _angleFadeMin) * shadowAlpha; } // Convert float alpha to byte _color.a = shadowAlpha; _color32.a = (byte)(shadowAlpha * 255f); _isVisible = true; } return(RecalculateShadowResult.Recalculated); }
private void TrySelect(ref Bounds selectionBounds, HashSet <GameObject> selection, FilteringArgs args, ref Bounds bounds, GameObject go, Plane[] frustumPlanes) { if (!GeometryUtility.TestPlanesAABB(frustumPlanes, bounds)) { return; } bool select; if (MethodOverride == BoxSelectionMethod.LooseFitting) { select = LooseFitting(ref selectionBounds, ref bounds); } else if (MethodOverride == BoxSelectionMethod.Vertex) { select = LooseFitting(ref selectionBounds, ref bounds); if (select && !selection.Contains(go)) { select = false; MeshFilter meshFilter = go.GetComponent <MeshFilter>(); if (meshFilter != null && meshFilter.sharedMesh != null) { Vector3[] vertices = meshFilter.sharedMesh.vertices; for (int i = 0; i < vertices.Length; ++i) { Vector3 vertex = go.transform.TransformPoint(vertices[i]); vertex = Window.Camera.WorldToScreenPoint(vertex); vertex.z = 0; if (selectionBounds.Contains(vertex)) { select = true; break; } } } else { SkinnedMeshRenderer smr = go.GetComponent <SkinnedMeshRenderer>(); if (smr != null && smr.sharedMesh != null) { Mesh bakedMesh = new Mesh(); smr.BakeMesh(bakedMesh); Matrix4x4 m = Matrix4x4.TRS(go.transform.localPosition, go.transform.localRotation, Vector3.one); if (smr.transform.parent != null) { m = m * smr.transform.parent.localToWorldMatrix; } Vector3[] vertices = bakedMesh.vertices; for (int i = 0; i < vertices.Length; ++i) { Vector3 vertex = m.MultiplyPoint(vertices[i]); vertex = Window.Camera.WorldToScreenPoint(vertex); vertex.z = 0; if (selectionBounds.Contains(vertex)) { select = true; break; } } Destroy(bakedMesh); } } } } else if (MethodOverride == BoxSelectionMethod.BoundsCenter) { select = BoundsCenter(ref selectionBounds, ref bounds); } else { select = TransformCenter(ref selectionBounds, go.transform); } if (select) { Filter(selection, args, go); } }
void AlertBehavior() { if (lastPlacePlayerSeen != null) { faceDirX = (int)Mathf.Sign(lastPlacePlayerSeen.position.x - gameObject.transform.position.x); } if (GeometryUtility.TestPlanesAABB(planes, thisCollider.bounds)) { if (Time.time > NextTimeToRaycast) { RaycastHit2D hit = LookAtPlayerSpiderWalker(); if (hit && hit.transform.tag == "Player") { if (Time.time > timeToFire && !passive && !alwaysPassive) { SwitchToFiring(); } endAlertTime = Time.time + alertAttentionSpan; } else { if (Time.time > endAlertTime) { SwitchToPatrol(); } } } } else { if (Time.time > endAlertTime) { SwitchToPatrol(); } } if (lastPlacePlayerSeen != null && playerTransform != null) { if (player.artemisState != Player.ArtemisState.dead) { if (WithinMovementRange(gameObject.transform.position) != Mathf.Sign(lastPlacePlayerSeen.position.x - gameObject.transform.position.x)) { velocity.x = Mathf.Sign(lastPlacePlayerSeen.position.x - gameObject.transform.position.x) * patrolSpeed; if (Mathf.Abs(playerTransform.position.y - gameObject.transform.position.y) < gameObject.transform.lossyScale.y * 4) { timeToFire = Time.time + alertTimeUntilFire; } } else { velocity.x = 0; } } else { velocity.x = 0; } } else { velocity.x = 0; } }
void SetCommonShadowRequestSettings(HDShadowRequest shadowRequest, Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 viewProjection, Vector2 viewportSize, int lightIndex) { // zBuffer param to reconstruct depth position (for transmission) float f = legacyLight.range; float n = shadowNearPlane; shadowRequest.zBufferParam = new Vector4((f - n) / n, 1.0f, (f - n) / n * f, 1.0f / f); shadowRequest.viewBias = new Vector4(m_ShadowData.viewBiasMin, m_ShadowData.viewBiasMax, m_ShadowData.viewBiasScale, 2.0f / shadowRequest.deviceProjectionYFlip.m00 / viewportSize.x * 1.4142135623730950488016887242097f); shadowRequest.normalBias = new Vector3(m_ShadowData.normalBiasMin, m_ShadowData.normalBiasMax, m_ShadowData.normalBiasScale); shadowRequest.flags = 0; shadowRequest.flags |= m_ShadowData.sampleBiasScale ? (int)HDShadowFlag.SampleBiasScale : 0; shadowRequest.flags |= m_ShadowData.edgeLeakFixup ? (int)HDShadowFlag.EdgeLeakFixup : 0; shadowRequest.flags |= m_ShadowData.edgeToleranceNormal ? (int)HDShadowFlag.EdgeToleranceNormal : 0; shadowRequest.edgeTolerance = m_ShadowData.edgeTolerance; // Make light position camera relative: // TODO: think about VR (use different camera position for each eye) if (ShaderConfig.s_CameraRelativeRendering != 0) { var translation = Matrix4x4.Translate(cameraPos); shadowRequest.view *= translation; translation.SetColumn(3, -cameraPos); translation[15] = 1.0f; invViewProjection = translation * invViewProjection; } if (legacyLight.type == LightType.Directional || (legacyLight.type == LightType.Spot && spotLightShape == SpotLightShape.Box)) { shadowRequest.position = new Vector3(shadowRequest.view.m03, shadowRequest.view.m13, shadowRequest.view.m23); } else { shadowRequest.position = (ShaderConfig.s_CameraRelativeRendering != 0) ? transform.position - cameraPos : transform.position; } shadowRequest.shadowToWorld = invViewProjection.transpose; shadowRequest.zClip = (legacyLight.type != LightType.Directional); shadowRequest.lightIndex = lightIndex; // We don't allow shadow resize for directional cascade shadow if (legacyLight.type == LightType.Directional) { shadowRequest.shadowMapType = ShadowMapType.CascadedDirectional; } else if (lightTypeExtent == LightTypeExtent.Rectangle) { shadowRequest.shadowMapType = ShadowMapType.AreaLightAtlas; } else { shadowRequest.shadowMapType = ShadowMapType.PunctualAtlas; } shadowRequest.lightType = (int)legacyLight.type; // shadow clip planes (used for tessellation clipping) GeometryUtility.CalculateFrustumPlanes(viewProjection, m_ShadowFrustumPlanes); if (shadowRequest.frustumPlanes?.Length != 6) { shadowRequest.frustumPlanes = new Vector4[6]; } // Left, right, top, bottom, near, far. for (int i = 0; i < 6; i++) { shadowRequest.frustumPlanes[i] = new Vector4( m_ShadowFrustumPlanes[i].normal.x, m_ShadowFrustumPlanes[i].normal.y, m_ShadowFrustumPlanes[i].normal.z, m_ShadowFrustumPlanes[i].distance ); } // Shadow algorithm parameters shadowRequest.shadowSoftness = shadowSoftness / 100f; shadowRequest.blockerSampleCount = blockerSampleCount; shadowRequest.filterSampleCount = filterSampleCount; shadowRequest.minFilterSize = minFilterSize; shadowRequest.kernelSize = (uint)kernelSize; shadowRequest.lightAngle = (lightAngle * Mathf.PI / 180.0f); shadowRequest.maxDepthBias = maxDepthBias; // We transform it to base two for faster computation. // So e^x = 2^y where y = x * log2 (e) const float log2e = 1.44269504089f; shadowRequest.evsmParams.x = evsmExponent * log2e; shadowRequest.evsmParams.y = evsmLightLeakBias; shadowRequest.evsmParams.z = evsmVarianceBias; shadowRequest.evsmParams.w = evsmBlurPasses; }
private void ProcessTerrainCell(TreeSystemStructuredTrees cell, ref float treeDistSqr) { // Draw all trees instanced in MAX_BATCH chunks int tempIndex = 0; float x, y, z; // If we are completely inside frustum we don't need to AABB test each tree bool insideFrustum = TUtils.IsCompletelyInsideFrustum(m_PlanesTemp, TUtils.BoundsCorners(ref cell.m_Bounds, ref m_TempCorners)); // Tree instances TreeSystemStoredInstance[] treeInstances = cell.m_Instances; // TODO: Hm... if we take that hash it doesn't mean that it's the first visible one... int treeHash = treeInstances[0].m_TreeHash; int currentTreeHash = treeHash; for (int treeIndex = 0; treeIndex < treeInstances.Length; treeIndex++) { // 1.33 ms for 110k trees // This is an order of magnitude faster than (treeInstances[treeIndex].m_WorldPosition - pos).sqrMagnitude // since it does not initiate with a ctor an extra vector during the computation x = treeInstances[treeIndex].m_WorldPosition.x - m_CameraPosTemp.x; y = treeInstances[treeIndex].m_WorldPosition.y - m_CameraPosTemp.y; z = treeInstances[treeIndex].m_WorldPosition.z - m_CameraPosTemp.z; float distToTree = x * x + y * y + z * z; // 17 ms for 110k trees // float distToTree = (treeInstances[treeIndex].m_WorldPosition - pos).sqrMagnitude; if (insideFrustum) { // If we are completely inside the frustum we don't need to check each individual tree's bounds if (distToTree <= treeDistSqr) { currentTreeHash = treeInstances[treeIndex].m_TreeHash; if (tempIndex >= MAX_BATCH || treeHash != currentTreeHash) { IssueDrawTrees(m_ManagedPrototypesIndexed[treeHash], cell, m_IdxTemp, m_DstTemp, tempIndex); tempIndex = 0; // Update the hash treeHash = currentTreeHash; } m_IdxTemp[tempIndex] = treeIndex; m_DstTemp[tempIndex] = Mathf.Sqrt(distToTree); tempIndex++; m_DataIssuedMeshTrees++; } } else { // If we are not completely inside the frustum we need to check the bounds of each individual tree if (distToTree <= treeDistSqr && GeometryUtility.TestPlanesAABB(m_PlanesTemp, treeInstances[treeIndex].m_WorldBounds)) { currentTreeHash = treeInstances[treeIndex].m_TreeHash; if (tempIndex >= MAX_BATCH || treeHash != currentTreeHash) { IssueDrawTrees(m_ManagedPrototypesIndexed[treeHash], cell, m_IdxTemp, m_DstTemp, tempIndex); tempIndex = 0; // Update the hash treeHash = currentTreeHash; } m_IdxTemp[tempIndex] = treeIndex; m_DstTemp[tempIndex] = Mathf.Sqrt(distToTree); tempIndex++; m_DataIssuedMeshTrees++; } } } // End cell tree iteration if (tempIndex > 0) { // Get a tree hash from the first element of the array so that we know for sure that we use the correc prototype data IssueDrawTrees(m_ManagedPrototypesIndexed[treeInstances[m_IdxTemp[0]].m_TreeHash], cell, m_IdxTemp, m_DstTemp, tempIndex); tempIndex = 0; } }
void Update() { _currentFrustum = GeometryUtility.CalculateFrustumPlanes(Camera.main); }
protected void Render(Camera camera) { if (_skinnedMeshes == null || _instanceData == null) { return; } _renderedObjects.Clear(); Plane[] planes = null; if (_frustrumCulling != eFrustrumCulling.Off) { planes = GeometryUtility.CalculateFrustumPlanes(camera); } for (int i = 0; i < _instanceData.Length; i++) { bool rendered = IsObjectActive(ref _instanceData[i]); //If frustum culling is enabled, check should draw this game object if (rendered && _frustrumCulling == eFrustrumCulling.Bounds) { rendered = AreBoundsInFrustrum(planes, ref _instanceData[i]); } else if (rendered && _frustrumCulling == eFrustrumCulling.Sphere) { Vector3 position = _instanceData[i]._gameObject.transform.position; Vector3 scale = _instanceData[i]._gameObject.transform.lossyScale; rendered = MathUtils.IsSphereInFrustrum(ref planes, ref position, _sphereCullingRadius * Mathf.Max(scale.x, scale.y, scale.z)); } if (rendered) { _renderData[i]._index = i; _renderData[i]._transform = GetTransform(ref _instanceData[i]); if (_sortByDepth) { Vector3 position = new Vector3(_renderData[i]._transform.m03, _renderData[i]._transform.m13, _renderData[i]._transform.m23); _renderData[i]._zDist = (camera.transform.position - position).sqrMagnitude; } AddToSortedList(ref _renderData[i]); } } if (_renderedObjects.Count > 0) { UpdateProperties(); FillTransformMatricies(); for (int i = 0; i < _skinnedMeshes.Length; i++) { for (int j = 0; j < _skinnedMeshes[i].sharedMesh.subMeshCount; j++) { Graphics.DrawMeshInstanced(_skinnedMeshes[i].sharedMesh, j, _skinnedMeshes[i].sharedMaterials[j], _renderedObjectTransforms, _renderedObjects.Count, _propertyBlock); } } } }
private void LateUpdate() { if (!UpdateAllInstanceTransformBufferIfNeeded()) { return; } visibleCellIDList.Clear(); //https://docs.unity3d.com/ScriptReference/GeometryUtility.CalculateFrustumPlanes.html float cameraOriginalFarPlane = cam.farClipPlane; cam.farClipPlane = drawDistance; //自己写了一个类似于unity 的 CalculateFrustumPlanes() 但是还是用unity 的CPP 代码 //CalculateFrustumPlanes(cam, cameraFrustumPlanes); GeometryUtility.CalculateFrustumPlanes(cam, cameraFrustumPlanes); //Ordering: [0] = Left, [1] = Right, [2] = Down, [3] = Up, [4] = Near, [5] = Far cam.farClipPlane = cameraOriginalFarPlane; Profiler.BeginSample("CPU cell frustum culling (heavy)"); //有几个草块可以看见 //TODO:(A)用四叉树测试替换这个forloop? //TODO:(B)把这个forloop转换成job+burst?(UnityException:TestPlaneSabb只能从主线程调用。) Vector3 sizeWS = new Vector3(Mathf.Abs(maxX - minX) / cellCountX, 0, Mathf.Abs(maxZ - minZ) / cellCountZ); for (int i = 0; i < cellPosWSsList.Length; i++) { Vector3 centerPosWS = new Vector3(i % cellCountX + 0.5f, 0, i / cellCountX + 0.5f); centerPosWS.x = Mathf.Lerp(minX, maxX, centerPosWS.x / cellCountX); centerPosWS.z = Mathf.Lerp(minZ, maxZ, centerPosWS.z / cellCountZ); Bounds cellBound = new Bounds(centerPosWS, sizeWS); //https://docs.unity3d.com/ScriptReference/GeometryUtility.TestPlanesAABB.html if (GeometryUtility.TestPlanesAABB(cameraFrustumPlanes, cellBound)) { visibleCellIDList.Add(i); } } Profiler.EndSample(); Matrix4x4 v = cam.worldToCameraMatrix; Matrix4x4 p = cam.projectionMatrix; Matrix4x4 vp = p * v; //设置计数器为0 visibleInstancesOnlyPosWSIDBuffer.SetCounterValue(0); cullingComputeShader.SetMatrix("_VPMatrix", vp); cullingComputeShader.SetFloat("_MaxDrawDistance", drawDistance); dispatchCount = 0; for (int i = 0; i < visibleCellIDList.Count; i++) { int targetCellFlattenID = visibleCellIDList[i]; int memoryOffset = 0; for (int j = 0; j < targetCellFlattenID; j++) { //添加草块里面的草的数量 memoryOffset += cellPosWSsList[j].Count; } cullingComputeShader.SetInt("_StartOffset", memoryOffset); //剔除从偏移位置开始的读取数据,将从单元在内存中的总偏移量开始 int jobLength = cellPosWSsList[targetCellFlattenID].Count; //合并n个dispatchs 为一个 dispatch , 如果内存是连续的在 allInstancesPosWSBuffer if (shouldBatchDispatch) { while ((i < visibleCellIDList.Count - 1) && (visibleCellIDList[i + 1] == visibleCellIDList[i] + 1)) { jobLength += cellPosWSsList[visibleCellIDList[i + 1]].Count; i++; } } cullingComputeShader.Dispatch(0, Mathf.CeilToInt(jobLength / 64f), 1, 1); dispatchCount++; } //复制计数器value args[1] = dstOffsetBytes = sizeof(uint) / sizeof(byte) = 4 ComputeBuffer.CopyCount(visibleInstancesOnlyPosWSIDBuffer, argsBuffer, 4); Bounds renderBound = new Bounds(); renderBound.SetMinMax(new Vector3(minX, 0, minZ), new Vector3(maxX, 0, maxZ)); Graphics.DrawMeshInstancedIndirect(GetGrassMeshCache(), 0, instanceMaterial, renderBound, argsBuffer); }
private bool AreBoundsInFrustrum(Plane[] cameraFrustrumPlanes, ref InstanceData instanceData) { //Only test first skinned mesh? return(GeometryUtility.TestPlanesAABB(cameraFrustrumPlanes, instanceData._skinnedMeshes[0].bounds)); }
static Plane[] PreserveFunc() { return(GeometryUtility.CalculateFrustumPlanes(Matrix4x4.identity)); }
bool Detection() { Plane[] ps = GeometryUtility.CalculateFrustumPlanes(sight); return(GeometryUtility.TestPlanesAABB(ps, m_player.GetComponent <CharacterController>().bounds)); }
public void CreateViewportFromModelStart() { using (Transaction transaction = _doc.Database.TransactionManager.StartTransaction()) { #region Switch to model space Application.SetSystemVariable("TILEMODE", 1); #endregion #region Get View Rectangle Pts from model space PromptPointOptions VportRectangleOpts = new PromptPointOptions("\nSpecify rectangle describing the desired view : \n"); PromptPointResult VportRectangleRes = _doc.Editor.GetPoint(VportRectangleOpts); if (VportRectangleRes.Status != PromptStatus.OK) { return; } Point3d CornerPt = VportRectangleRes.Value; RectangleJig Recjig = new RectangleJig(CornerPt); if (_doc.Editor.Drag(Recjig).Status == PromptStatus.Cancel) { return; } Polyline ViewPline = Recjig.Polyline; Point3dCollection ViewPlinePts = GeometryUtility.GetPointsFromPolyline(ViewPline); if (ViewPlinePts.Count == 5) { ViewPlinePts.RemoveAt(4); } #endregion #region Calculate View height double viewHeight = Math.Abs(ViewPlinePts[0].Y - ViewPlinePts[2].Y); #endregion #region Calculate View width double viewWidth = Math.Abs(ViewPlinePts[0].X - ViewPlinePts[2].X); #endregion #region Calculate View Center Pt double baseWidth = ViewPlinePts[0].X; if (ViewPlinePts[0].X > ViewPlinePts[2].X) { baseWidth = ViewPlinePts[2].X; } double baseHeight = ViewPlinePts[0].Y; if (ViewPlinePts[0].Y > ViewPlinePts[2].Y) { baseHeight = ViewPlinePts[2].Y; } Point2d ViewCenterPt = new Point2d( baseWidth + (Math.Abs(ViewPlinePts[0].X - ViewPlinePts[2].X) / 2), baseHeight + (Math.Abs(ViewPlinePts[0].Y - ViewPlinePts[2].Y) / 2)); #endregion #region Select Paper Space PromptKeywordOptions PaperSpaceOpts = new PromptKeywordOptions(""); PaperSpaceOpts.Message = "\nChose paper space : "; PaperSpaceOpts.AllowNone = false; Layout currLayout; // Open the Block table for read BlockTable Bt = transaction.GetObject(_doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord BtrModelSpace = (BlockTableRecord)transaction.GetObject(Bt[BlockTableRecord.ModelSpace], OpenMode.ForRead); foreach (ObjectId BtrId in Bt) { BlockTableRecord Btr = (BlockTableRecord)transaction.GetObject(BtrId, OpenMode.ForRead); if (Btr.IsLayout && Btr.ObjectId != BtrModelSpace.ObjectId) { currLayout = (Layout)transaction.GetObject(Btr.LayoutId, OpenMode.ForRead); PaperSpaceOpts.Keywords.Add(currLayout.LayoutName); } } PromptResult PaperSpaceRes = _doc.Editor.GetKeywords(PaperSpaceOpts); LayoutManager.Current.CurrentLayout = PaperSpaceRes.StringResult; #endregion var keywordSelectionResult = _editorHelper.PromptForKeywordSelection( "\nSpecify rectangle describing viewport or base point with scale factor", new[] { "Rectangle", "Base point" }, false, "Rectangle"); if (keywordSelectionResult.Status != PromptStatus.OK) { return; } var viewportHeight = 0.0; var viewportWidth = 0.0; var CenterPt = new Point3d(); var viewportCustomScale = 0.0; if (keywordSelectionResult.StringResult == "Rectangle") { #region Get Viewport Rectangle Pts VportRectangleOpts = new PromptPointOptions("\nSpecify rectangle describing the viewport : \n"); VportRectangleRes = _doc.Editor.GetPoint(VportRectangleOpts); if (VportRectangleRes.Status != PromptStatus.OK) { return; } CornerPt = VportRectangleRes.Value; Recjig = new RectangleJig(CornerPt); if (_doc.Editor.Drag(Recjig).Status == PromptStatus.Cancel) { return; } Polyline ViewportPline = Recjig.Polyline; Point3dCollection ViewportPlinePts = GeometryUtility.GetPointsFromPolyline(ViewportPline); GeometryUtility.RemoveDuplicate(ViewportPlinePts); if (ViewportPlinePts.Count == 5) { ViewportPlinePts.RemoveAt(4); } #endregion #region Calculate Viewport height viewportHeight = Math.Abs(ViewportPlinePts[0].Y - ViewportPlinePts[2].Y); #endregion #region Calculate Viewport width viewportWidth = Math.Abs(ViewportPlinePts[0].X - ViewportPlinePts[2].X); #endregion #region Calculate Viewport Center Pt baseWidth = ViewportPlinePts[0].X; if (ViewportPlinePts[0].X > ViewportPlinePts[2].X) { baseWidth = ViewportPlinePts[2].X; } baseHeight = ViewportPlinePts[0].Y; if (ViewportPlinePts[0].Y > ViewportPlinePts[2].Y) { baseHeight = ViewportPlinePts[2].Y; } CenterPt = new Point3d( baseWidth + (Math.Abs(ViewportPlinePts[0].X - ViewportPlinePts[2].X) / 2), baseHeight + (Math.Abs(ViewportPlinePts[0].Y - ViewportPlinePts[2].Y) / 2), 0.0); #endregion #region Calculate Viewport Custom Scale viewportCustomScale = viewportHeight / viewHeight; #endregion } else { #region Get Viewport Base Point var viewportBasePoint = _editorHelper.PromptForPoint("\nSpecify bottom left point of viewport : "); if (viewportBasePoint.Status != PromptStatus.OK) { return; } #endregion #region Get ViewportCustomScale var scaleFactorResult = _editorHelper.PromptForDouble("\nSpecify viewport scale factor : ", 1.0); if (scaleFactorResult.Status != PromptStatus.OK) { return; } if (scaleFactorResult.Value <= 0) { _editorHelper.WriteMessage("\nSpecified scale factor is incorrect !\n"); } viewportCustomScale = scaleFactorResult.Value; #endregion #region Calculate Viewport height viewportHeight = viewHeight * viewportCustomScale; #endregion #region Calculate Viewport width viewportWidth = viewWidth * viewportCustomScale; #endregion #region Calculate Viewport Center Pt CenterPt = new Point3d(viewportBasePoint.Value.X + viewportWidth / 2, viewportBasePoint.Value.Y + viewportHeight / 2, 0); #endregion } #region create viewport var Vport = new Viewport { ViewCenter = ViewCenterPt, CenterPoint = CenterPt, Height = viewportHeight, Width = viewportWidth, CustomScale = viewportCustomScale }; #endregion #region Insert viewport into paper space BlockTableRecord PaperSpaceBtr = new BlockTableRecord(); foreach (ObjectId BtrId in Bt) { BlockTableRecord Btr = (BlockTableRecord)transaction.GetObject(BtrId, OpenMode.ForRead); if (Btr.IsLayout && Btr.ObjectId != BtrModelSpace.ObjectId) { currLayout = (Layout)transaction.GetObject(Btr.LayoutId, OpenMode.ForRead); if (currLayout.LayoutName == PaperSpaceRes.StringResult) { PaperSpaceBtr = (BlockTableRecord) transaction.GetObject(Bt[BlockTableRecord.PaperSpace], OpenMode.ForWrite); } } } if (PaperSpaceBtr == null) { _doc.Editor.WriteMessage("Error getting the selected layout"); } // Add the new object to the block table record and the transaction PaperSpaceBtr.AppendEntity(Vport); transaction.AddNewlyCreatedDBObject(Vport, true); // Enable the viewport Vport.On = true; // Set the new viewport current via an imported ObjectARX function #if acad2012 SetCurrentVPort2010(Vport.UnmanagedObject); #endif #if acad2013 SetCurrentVPort2013(Vport.UnmanagedObject); #endif #if bcad SetCurrentVPortBCad(Vport.UnmanagedObject); #endif #endregion transaction.Commit(); } }
/// <summary> /// Checks if the child is in the cameras frustum. /// </summary> /// <returns></returns> public static bool IsVisibleChild(Camera FrustumCamera, GameObject ObjectToCheck, GameObject Parent, Vector3 DesiredPosition) { GameObject BufferObject = ObjectToCheck; BufferObject.transform.position = DesiredPosition + ObjectToCheck.transform.localPosition; if (!BufferObject.GetComponent <Renderer>()) { return(false); } Bounds BoundsToCheck = BufferObject.GetComponent <Renderer>().bounds; Plane[] CameraBounds = GeometryUtility.CalculateFrustumPlanes(FrustumCamera); if (GeometryUtility.TestPlanesAABB(CameraBounds, BoundsToCheck)) { if (!UseOcclusionCulling) { return(true); } Vector3[] RayCastPositions = new Vector3[8]; RayCastPositions[0] = new Vector3(-BoundsToCheck.extents.x, +BoundsToCheck.extents.y, -BoundsToCheck.extents.z); RayCastPositions[1] = new Vector3(-BoundsToCheck.extents.x, -BoundsToCheck.extents.y, -BoundsToCheck.extents.z); RayCastPositions[2] = new Vector3(+BoundsToCheck.extents.x, -BoundsToCheck.extents.y, -BoundsToCheck.extents.z); RayCastPositions[3] = new Vector3(+BoundsToCheck.extents.x, +BoundsToCheck.extents.y, -BoundsToCheck.extents.z); RayCastPositions[4] = new Vector3(-BoundsToCheck.extents.x, +BoundsToCheck.extents.y, BoundsToCheck.extents.z); RayCastPositions[5] = new Vector3(-BoundsToCheck.extents.x, -BoundsToCheck.extents.y, BoundsToCheck.extents.z); RayCastPositions[6] = new Vector3(+BoundsToCheck.extents.x, -BoundsToCheck.extents.y, BoundsToCheck.extents.z); RayCastPositions[7] = new Vector3(+BoundsToCheck.extents.x, +BoundsToCheck.extents.y, BoundsToCheck.extents.z); for (int index = 0; index < RayCastPositions.Length; index++) { RaycastHit hit; if (!Physics.Linecast(RayCastPositions[index] + BoundsToCheck.center, FrustumCamera.transform.position, out hit)) { return(true); } else { bool IsIgnoredObject = false; if (FrustumIgnoredObjects != null) { for (int IgnoredObjectIndex = 0; IgnoredObjectIndex < FrustumIgnoredObjects.Count; IgnoredObjectIndex++) { if (FrustumIgnoredObjects[IgnoredObjectIndex] != null) { if (FrustumIgnoredObjects[IgnoredObjectIndex].transform != null) { if (FrustumIgnoredObjects[IgnoredObjectIndex].gameObject != null) { if (FrustumIgnoredObjects[IgnoredObjectIndex].gameObject == hit.transform.gameObject) { IsIgnoredObject = true; } } } } } } if (IsIgnoredObject) { return(true); } } } return(false); } return(false); }
// Start is called before the first frame update void Start() { colliders = Physics.OverlapSphere(transform.position, radius, mask); camera = GetComponent <Camera>(); planes = GeometryUtility.CalculateFrustumPlanes(camera); }
public static bool IsVisibleInCamera(this SpriteRenderer _spriteRenderer, Camera _camera) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(_camera); return(GeometryUtility.TestPlanesAABB(planes, _spriteRenderer.bounds)); }
public void Update(PostProcessLayer postProcessLayer, FrameSettings frameSettings) { // If TAA is enabled projMatrix will hold a jittered projection matrix. The original, // non-jittered projection matrix can be accessed via nonJitteredProjMatrix. bool taaEnabled = Application.isPlaying && camera.cameraType == CameraType.Game && CoreUtils.IsTemporalAntialiasingActive(postProcessLayer); var nonJitteredCameraProj = camera.projectionMatrix; var cameraProj = taaEnabled ? postProcessLayer.temporalAntialiasing.GetJitteredProjectionMatrix(camera) : nonJitteredCameraProj; // The actual projection matrix used in shaders is actually massaged a bit to work across all platforms // (different Z value ranges etc.) var gpuProj = GL.GetGPUProjectionMatrix(cameraProj, true); // Had to change this from 'false' var gpuView = camera.worldToCameraMatrix; var gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true); var pos = camera.transform.position; var relPos = pos; // World-origin-relative if (ShaderConfig.s_CameraRelativeRendering != 0) { // Zero out the translation component. gpuView.SetColumn(3, new Vector4(0, 0, 0, 1)); relPos = Vector3.zero; // Camera-relative } var gpuVP = gpuNonJitteredProj * gpuView; // A camera could be rendered multiple times per frame, only updates the previous view proj & pos if needed if (m_LastFrameActive != Time.frameCount) { if (isFirstFrame) { prevCameraPos = pos; prevViewProjMatrix = gpuVP; } else { prevCameraPos = cameraPos; prevViewProjMatrix = nonJitteredViewProjMatrix; } isFirstFrame = false; } const uint taaFrameCount = 8; taaFrameIndex = taaEnabled ? (uint)Time.renderedFrameCount % taaFrameCount : 0; taaFrameRotation = new Vector2(Mathf.Sin(taaFrameIndex * (0.5f * Mathf.PI)), Mathf.Cos(taaFrameIndex * (0.5f * Mathf.PI))); viewMatrix = gpuView; projMatrix = gpuProj; nonJitteredProjMatrix = gpuNonJitteredProj; cameraPos = pos; viewParam = new Vector4(viewMatrix.determinant, 0.0f, 0.0f, 0.0f); if (ShaderConfig.s_CameraRelativeRendering != 0) { Matrix4x4 cameraDisplacement = Matrix4x4.Translate(cameraPos - prevCameraPos); // Non-camera-relative positions prevViewProjMatrix *= cameraDisplacement; // Now prevViewProjMatrix correctly transforms this frame's camera-relative positionWS } // Warning: near and far planes appear to be broken. GeometryUtility.CalculateFrustumPlanes(viewProjMatrix, frustumPlanes); for (int i = 0; i < 4; i++) { // Left, right, top, bottom. frustumPlaneEquations[i] = new Vector4(frustumPlanes[i].normal.x, frustumPlanes[i].normal.y, frustumPlanes[i].normal.z, frustumPlanes[i].distance); } // Near, far. // We need to switch forward direction based on handness (Reminder: Regular camera have a negative determinant in Unity and reflection probe follow DX convention and have a positive determinant) Vector3 forward = viewParam.x < 0.0f ? camera.transform.forward : -camera.transform.forward; frustumPlaneEquations[4] = new Vector4(forward.x, forward.y, forward.z, -Vector3.Dot(forward, relPos) - camera.nearClipPlane); frustumPlaneEquations[5] = new Vector4(-forward.x, -forward.y, -forward.z, Vector3.Dot(forward, relPos) + camera.farClipPlane); m_LastFrameActive = Time.frameCount; RenderTextureDescriptor tempDesc; if (frameSettings.enableStereo) { screenSize = new Vector4(XRSettings.eyeTextureWidth, XRSettings.eyeTextureHeight, 1.0f / XRSettings.eyeTextureWidth, 1.0f / XRSettings.eyeTextureHeight); tempDesc = XRSettings.eyeTextureDesc; } else { screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight); tempDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight); } tempDesc.msaaSamples = 1; // will be updated later, deferred will always set to 1 tempDesc.depthBufferBits = 0; tempDesc.autoGenerateMips = false; tempDesc.useMipMap = false; tempDesc.enableRandomWrite = false; tempDesc.memoryless = RenderTextureMemoryless.None; renderTextureDesc = tempDesc; }
private void BeginSnap() { if (Window.Camera == null) { return; } if (Model != null && Model is PositionHandleModel) { ((PositionHandleModel)Model).IsVertexSnapping = true; } HashSet <Transform> snapTargetsHS = new HashSet <Transform>(); List <Transform> snapTargets = new List <Transform>(); List <Bounds> snapTargetBounds = new List <Bounds>(); if (Target != null) { for (int i = 0; i < RealTargets.Length; ++i) { Transform target = RealTargets[i]; if (target != null) { ExposeToEditor exposeToEditor = target.GetComponent <ExposeToEditor>(); if (exposeToEditor != null) { snapTargetBounds.Add(exposeToEditor.Bounds); snapTargets.Add(exposeToEditor.BoundsObject.transform); snapTargetsHS.Add(exposeToEditor.BoundsObject.transform); } else { snapTargets.Add(target); snapTargetsHS.Add(target); MeshFilter filter = target.GetComponent <MeshFilter>(); if (filter != null && filter.sharedMesh != null) { snapTargetBounds.Add(filter.sharedMesh.bounds); } else { SkinnedMeshRenderer smr = target.GetComponent <SkinnedMeshRenderer>(); if (smr != null && smr.sharedMesh != null) { snapTargetBounds.Add(smr.sharedMesh.bounds); } else { Bounds b = new Bounds(Vector3.zero, Vector3.zero); snapTargetBounds.Add(b); } } } } } } m_snapTargets = snapTargets.ToArray(); m_targetLayers = new int[m_snapTargets.Length]; m_snapTargetsBounds = snapTargetBounds.ToArray(); Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(Window.Camera); ExposeToEditor[] exposeToEditorObjects = FindObjectsOfType <ExposeToEditor>(); List <ExposeToEditor> insideOfFrustum = new List <ExposeToEditor>(); for (int i = 0; i < exposeToEditorObjects.Length; ++i) { ExposeToEditor exposeToEditor = exposeToEditorObjects[i]; if (exposeToEditor.CanSnap) { if (GeometryUtility.TestPlanesAABB(frustumPlanes, new Bounds(exposeToEditor.transform.TransformPoint(exposeToEditor.Bounds.center), Vector3.zero))) { if (!snapTargetsHS.Contains(exposeToEditor.transform)) { insideOfFrustum.Add(exposeToEditor); } } } } m_allExposedToEditor = insideOfFrustum.ToArray(); }
public void FinalizeDraw() { this.RemoveUnusedMeshes(this.meshes); Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.current); if (this.surfaceMaterial == null || this.lineMaterial == null) { return; } for (int i = 0; i <= 1; i++) { Material material = (i == 0) ? this.surfaceMaterial : this.lineMaterial; for (int j = 0; j < material.passCount; j++) { material.SetPass(j); for (int k = 0; k < this.meshes.Count; k++) { if (this.meshes[k].lines == (material == this.lineMaterial) && GeometryUtility.TestPlanesAABB(planes, this.meshes[k].mesh.bounds)) { Graphics.DrawMeshNow(this.meshes[k].mesh, Matrix4x4.identity); } } } } this.usedHashes.Clear(); }
public void Update() { CommandBuffer buffer; var cam = Camera.current; if (!cam) { return; } buffer = GetBuffer(cam); if (system.availableLayers.Count == 0) { return; } renderedDecals = 0; if (!gameObject.activeInHierarchy && enabled) { return; } GeometryUtility.CalculateFrustumPlanes(cam, planes); // copy g-buffer normals into a temporary RT buffer.GetTemporaryRT(diffuseID, -1, -1); buffer.GetTemporaryRT(smoothnessID, -1, -1); buffer.GetTemporaryRT(normalsID, -1, -1); renderTargets[0] = BuiltinRenderTextureType.GBuffer0; renderTargets[1] = BuiltinRenderTextureType.GBuffer1; renderTargets[2] = BuiltinRenderTextureType.GBuffer2; foreach (var layer in system.availableLayers) { bool copiedTextures = false; if (!system.layerToDecals.TryGetValue(layer, out List <Decal> decals)) { return; } foreach (var decal in decals) { if (!GeometryUtility.TestPlanesAABB(planes, decal.DecalBounds)) { continue; } if (!copiedTextures) { // In shader you can't really read and write to the texture at the same time // That's why we need to copy existing textures for each layer CopyRenderes(); copiedTextures = true; } renderedDecals++; // matricies.Add(Matrix4x4.TRS(decalTransform.position, decalTransform.rotation, decalTransform.lossyScale)); buffer.DrawMesh(m_CubeMesh, decal.transform.localToWorldMatrix, decal.DecalMaterial); // TODO: Should support instancing } } // release temporary normals RT buffer.ReleaseTemporaryRT(normalsID); buffer.ReleaseTemporaryRT(diffuseID); buffer.ReleaseTemporaryRT(smoothnessID); void CopyRenderes() { buffer.Blit(BuiltinRenderTextureType.GBuffer0, diffuseID); buffer.Blit(BuiltinRenderTextureType.GBuffer1, smoothnessID); buffer.Blit(BuiltinRenderTextureType.GBuffer2, normalsID); buffer.SetRenderTarget(renderTargets, BuiltinRenderTextureType.CameraTarget); } }
private void RenderLightSources() { ConfigLightCamera(false); if (EnableNormalMapping) { if (_singleLightSourceTexture == null) { _singleLightSourceTexture = new RenderTexture(_smallLightTextureSize.x, _smallLightTextureSize.y, 0, _texFormat); _singleLightSourceTexture.filterMode = LightTexturesFilterMode; } if (_normalMappedLightMaterial == null) { _normalMappedLightMaterial = new Material(Shader.Find("Light2D/Internal/Normal Mapped Light")); _normalMappedLightMaterial.SetTexture("_MainTex", _singleLightSourceTexture); } if (_lightCombiningMaterial == null) { _lightCombiningMaterial = new Material(Shader.Find("Light2D/Internal/Light Blender")); _lightCombiningMaterial.SetTexture("_MainTex", _singleLightSourceTexture); } Plane[] cameraPlanes = GeometryUtility.CalculateFrustumPlanes(_camera); _lightSourcesTexture.DiscardContents(); Color oldBackgroundColor = LightCamera.backgroundColor; RenderTexture oldRt = RenderTexture.active; Graphics.SetRenderTarget(_lightSourcesTexture); GL.Clear(false, true, oldBackgroundColor); Graphics.SetRenderTarget(oldRt); _lightSpritesCache.Clear(); foreach (LightSprite lightSprite in LightSprite.AllLightSprites) { if (lightSprite.RendererEnabled && GeometryUtility.TestPlanesAABB(cameraPlanes, lightSprite.Renderer.bounds)) { _lightSpritesCache.Add(lightSprite); } } Vector3 lightCamLocPos = LightCamera.transform.localPosition; LightCamera.targetTexture = _singleLightSourceTexture; LightCamera.cullingMask = 0; LightCamera.backgroundColor = new Color(0, 0, 0, 0); foreach (LightSprite lightSprite in _lightSpritesCache) { // HACK: won't work for unknown reason without that line LightCamera.RenderWithShader(_normalMapRenderShader, "f84j"); Graphics.SetRenderTarget(_singleLightSourceTexture); lightSprite.DrawLightingNow(lightCamLocPos); Graphics.SetRenderTarget(_lightSourcesTexture); lightSprite.DrawLightNormalsNow(_normalMappedLightMaterial); } Graphics.SetRenderTarget(oldRt); LightCamera.cullingMask = 1 << LightSourcesLayer; LightCamera.Render(); Graphics.Blit(_singleLightSourceTexture, _lightSourcesTexture, _lightCombiningMaterial); LightCamera.targetTexture = null; LightCamera.cullingMask = 0; LightCamera.backgroundColor = oldBackgroundColor; } else { LightCamera.targetTexture = _lightSourcesTexture; LightCamera.cullingMask = 1 << LightSourcesLayer; //LightCamera.backgroundColor = new Color(0, 0, 0, 0); LightCamera.Render(); LightCamera.targetTexture = null; LightCamera.cullingMask = 0; } }
void Awake() { boxCol = GetComponent <BoxCollider>(); planes = GeometryUtility.CalculateFrustumPlanes(Camera.main); }