private void Update() { // Check if this source's transform has changed. if (transform.hasChanged) { m_Dirty = true; // Recalculate camera bounds. m_CameraBounds = LOSHelper.CalculateSourceBounds(m_Camera); // Reset transform changed flag. transform.hasChanged = false; } // Check if this source and it's frustum are visible to the camera used by the LOS mask. m_IsVisibile = GeometryUtility.TestPlanesAABB(LOSMask.CameraFrustumPlanes, m_CameraBounds); // Only update frustum planes when the source is visible and dirty. if (m_IsVisibile && m_Dirty) { // Recalculate frustum planes. LOSHelper.ExtractFrustumPlanes(m_FrustumPlanes, m_Camera); m_Dirty = false; } }
private void OnRenderImage(RenderTexture source, RenderTexture destination) { if (m_Camera == null) { return; } // Calculate Frustum origins and rays for mask camera. Matrix4x4 frustumOrigins; Matrix4x4 frustumRays; LOSHelper.CalculateViewVectors(m_Camera, out frustumRays, out frustumOrigins); // Push parameters which are identical for all LOS sources. Materials.Mask.SetMatrix(ShaderID.FrustumRays, frustumRays); Materials.Mask.SetMatrix(ShaderID.FrustumOrigins, frustumOrigins); Materials.Mask.SetMatrix(ShaderID.WorldToCameraMatrix, m_Camera.worldToCameraMatrix); // Store original skybox. Material originalSkybox = RenderSettings.skybox; // Set-up skybox material which clears render texture to farplane depth. RenderSettings.skybox = Materials.SkyBox; // Create Mask Render Texture. RenderTexture maskRenderTexture = CreateMaskRenderTexture(); // Get list with all LOS sources. List <LOSSource> losSources = LOSManager.Instance.LOSSources; // Iterate over all LOS sources. for (int i = 0; i < losSources.Count; i++) { RenderSourceToMask(losSources[i], ref maskRenderTexture); } // Revert original skybox. RenderSettings.skybox = originalSkybox; // Get unmodified screen buffer. Materials.Combine.SetTexture(ShaderID.PreEffectTex, m_BufferStorage.BufferTexture); // Set-up material. Materials.Combine.SetTexture(ShaderID.MaskTex, maskRenderTexture); // Check if Stencil Mask component is used. bool isStencilMaskEnabled = (m_StencilMask != null) && (m_StencilMask.enabled == true); if (isStencilMaskEnabled) { // Set Stencil Mask texture. Materials.Combine.SetTexture(ShaderID.StencilMaskTex, m_StencilMask.MaskTexture); } // Render final effect. Graphics.Blit(source, destination, Materials.Combine, isStencilMaskEnabled ? 1 : 0); RenderTexture.ReleaseTemporary(maskRenderTexture); }
/// <summary> /// Checks to see if object is inside the view frustum of any of the LOS cameras. /// Ideally should be called in OnWillRenderObject, but it's to late to disable renderer.. /// Early outs when visible to one camera. /// </summary> private void UpdateVisibleSources() { Bounds meshBounds = gameObject.GetComponent <Renderer>().bounds; // Get list of sources. List <LOSSource> losSources = LOSManager.Instance.LOSSources; for (int i = 0; i < losSources.Count; ++i) { LOSSource losSource = losSources[i]; bool isVisible = LOSHelper.CheckBoundsVisibility(losSource, meshBounds, m_RaycastLayerMask.value); UpdateList(losSource, isVisible); } }
private void RenderWorldPosition(RenderTexture source, RenderTexture destination) { // Calculate Frustum origins and rays for mask camera. Matrix4x4 frustumOrigins; Matrix4x4 frustumRays; LOSHelper.CalculateViewVectors(m_Camera, out frustumRays, out frustumOrigins); // Push parameters which are identical for all LOS sources. Materials.Debug.SetMatrix(ShaderID.FrustumRays, frustumRays); Materials.Debug.SetMatrix(ShaderID.FrustumOrigins, frustumOrigins); Materials.Debug.SetPass(2); LOSMask.IndexedGraphicsBlit(destination); }
/// <summary> /// Checks to see if object is inside the view frustum of any of the LOS cameras. /// Ideally should be called in OnWillRenderObject, but it's to late to disable renderer.. /// Early outs when visible to one camera. /// </summary> private static bool CustomCull(Bounds meshBounds, int layerMask) { // Get list of sources. List <LOSSource> losSources = LOSManager.Instance.LOSSources; for (int i = 0; i < losSources.Count; ++i) { LOSSource losSource = losSources[i]; if (LOSHelper.CheckBoundsVisibility(losSource, meshBounds, layerMask)) { return(true); } } return(false); }
private void OnPreRender() { if (m_Camera == null) { return; } // Make sure we can acces the cameras depth buffer in our shader. m_Camera.depthTextureMode = DepthTextureMode.DepthNormals; // Update Mask Camera frutsum planes if needed. if (transform.hasChanged) { LOSHelper.ExtractFrustumPlanes(m_CameraFrustumPlanes, m_Camera); transform.hasChanged = false; } }
/// <summary> /// Checks if the mesh bounds are visible to the LOS Source /// </summary> public static bool CheckBoundsVisibility(LOSSource losSource, Bounds meshBounds, int layerMask) { Camera currentCamera = losSource.SourceCamera; if (losSource.IsVisible && currentCamera != null) { Plane[] cameraPlanes = losSource.FrustumPlanes; if (GeometryUtility.TestPlanesAABB(cameraPlanes, meshBounds)) { if (LOSHelper.CheckRayCast(currentCamera, meshBounds, losSource.SourceInfo.w, layerMask)) { return(true); } } } return(false); }
/// <summary> /// Calculates AABB for source camera. /// </summary> public static Bounds CalculateSourceBounds(Camera sourceCamera) { Matrix4x4 frustumCorners = LOSHelper.CalculatePerspectiveCorners(sourceCamera); Vector3 cameraPosition = sourceCamera.transform.position; Vector3 frustumMin = GetFrustumMin(frustumCorners); frustumMin = Vector3.Min(frustumMin + cameraPosition, cameraPosition); Vector3 frustumMax = GetFrustumMax(frustumCorners); frustumMax = Vector3.Max(frustumMax + cameraPosition, cameraPosition); Bounds cameraBound = new Bounds(); cameraBound.SetMinMax(frustumMin, frustumMax); return(cameraBound); }
private void OnEnable() { // Check if this component can be enabled. // Disable if post processing not supported. enabled &= Util.Verify(SystemInfo.supportsImageEffects, "Image effects not supported."); // Disable if buffer storage is not assigned. enabled &= Util.Verify(m_BufferStorage != null, "LOS Buffer Storage property not assigned."); // Disable if camera component is missing. enabled &= Util.Verify(m_Camera != null, "Camera component missing."); if (enabled) { // Make sure Frustum planes are initiliazed. LOSHelper.ExtractFrustumPlanes(m_CameraFrustumPlanes, m_Camera); m_StencilMask = GetComponent <LOSStencilMask>(); } }
private void OnEnable() { // Register with LOS manager singleton. LOSManager.Instance.AddLOSSource(this); // Check if component can be enabled. enabled &= Util.Verify(m_Camera != null, "Camera Component missing"); if (enabled) { // Alert user if camera is set to orthographic. Debug.Assert(!m_Camera.orthographic, "Cameras attached to an LOS source can't be orthographic, changing to perspective!"); // Initiliaze source camera. LOSHelper.InitSourceCamera(m_Camera); // Initiliaze bounds. m_CameraBounds = LOSHelper.CalculateSourceBounds(m_Camera); // Initiliaze frustum planes. LOSHelper.ExtractFrustumPlanes(m_FrustumPlanes, m_Camera); } }
/// <summary> /// Checks to see if object is inside the view frustum of any of the LOS cameras. /// Ideally should be called in OnWillRenderObject, but it's to late to disable renderer.. /// Early outs when visible to one camera. /// </summary> /* private static bool culler(GameObject _self, Bounds meshBounds, int layerMask) * { * // Get list of sources. * List<LOSSource> losSources = LOSManager.Instance.LOSSources; * * for (int i = 0; i < losSources.Count; ++i) * { * LOSSource losSource = losSources[i]; * * if (LOSHelper.CheckBoundsVisibility(losSource, meshBounds, layerMask) && losSources[i].transform.root.name != "player") * { * if (losSources[i].transform.parent.GetComponent<IA>() != null) * { * losSources[i].transform.parent.GetComponent<IA>().detectView(true); * } * * return true; * } * else if(!LOSHelper.CheckBoundsVisibility(losSource, meshBounds, layerMask) && losSources[i].transform.root.name != "player") * { * if (losSources[i].transform.parent.GetComponent<IA>()!=null) { * losSources[i].transform.parent.GetComponent<IA>().detectView(false); * } * } * } * * return false; * }*/ private static bool CustomCull(Transform _target, LOSSource losSource, GameObject objMesh, int layerMask) { //Debug.Log("Target: "+_target.GetComponent<SimpleIA>().typeNPC + " losSource: "+ losSource+" objMesh: "+objMesh.transform.parent.GetComponent<BodyChange>()); /* if (objMesh.tag == "Player" && LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent<Renderer>().bounds, layerMask)) { * Debug.Log("veo: "+objMesh.transform.parent.gameObject.name + " " + objMesh.transform.parent.gameObject.activeSelf); * _target.GetComponent<SimpleIA>().setTarget(objMesh.transform); * _target.GetComponent<SimpleIA>().setDetectado(true); * return true; * } * else if(objMesh.tag == "Player" && !LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent<Renderer>().bounds, layerMask) * && _target.GetComponent<SimpleIA>().getDetectado()) * { * Debug.Log("no veo: " + objMesh.transform.parent.gameObject.name + " " + objMesh.transform.parent.gameObject.activeSelf); * if (!_target.GetComponent<SimpleIA>().ActionRangeAlerta()) * { * _target.GetComponent<SimpleIA>().setDetectado(false); * _target.GetComponent<SimpleIA>().setState(2); * * } * else * { * // Debug.Log(" alerta in but not focus " + objMesh.transform.parent.gameObject.name); * * } * return false; * }*/ if (objMesh.tag == "Player" && LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent <Renderer>().bounds, layerMask) && objMesh.transform.parent.gameObject.activeSelf && !_target.GetComponent <SimpleIA>().getDetectado()) { // Debug.Log("te veo "+ objMesh.transform.parent.gameObject.name+" activo "+ objMesh.transform.parent.gameObject.activeSelf); _target.GetComponent <SimpleIA>().setTarget(objMesh.transform); _target.GetComponent <SimpleIA>().setDetectado(true); return(true); } else if (objMesh.tag == "Player" && !LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent <Renderer>().bounds, layerMask) && _target.GetComponent <SimpleIA>().getDetectado() && objMesh.transform.parent.gameObject.activeSelf) { // Debug.Log(" fuera de foco " + _target.GetComponent<SimpleIA>().ActionRangeAlerta()); //verifico con rango alerta if (!_target.GetComponent <SimpleIA>().ActionRangeAlerta()) { _target.GetComponent <SimpleIA>().setDetectado(false); _target.GetComponent <SimpleIA>().setState(2); } else { // Debug.Log(" alerta in but not focus " + objMesh.transform.parent.gameObject.name); } return(true); } else if (objMesh.tag == "Player" && LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent <Renderer>().bounds, layerMask) && !objMesh.transform.parent.gameObject.activeSelf) { //Debug.Log("No te veo " + objMesh.transform.parent.gameObject.name); //verifico con rango alerta _target.GetComponent <SimpleIA>().setDetectado(false); _target.GetComponent <SimpleIA>().setState(2); // return true; } else if (objMesh.tag == "NPC" && _target.GetComponent <SimpleIA>().typeNPC == SimpleIA.TypeNPC.clero && objMesh.transform.parent.GetComponent <BodyChange>().dominate&& !_target.GetComponent <BodyChange>().dominate&& LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent <Renderer>().bounds, layerMask) && objMesh.transform.parent.GetComponent <SimpleIA>().typeNPC == SimpleIA.TypeNPC.normal) { // Debug.Log("veo impostor " + _target.GetComponent<SimpleIA>().typeNPC+ "//"+objMesh.transform.parent.GetComponent<SimpleIA>().typeNPC); _target.GetComponent <SimpleIA>().setTarget(objMesh.transform); _target.GetComponent <SimpleIA>().setDetectado(true); // return true; } else if (objMesh.tag == "NPC" && _target.GetComponent <SimpleIA>().typeNPC == SimpleIA.TypeNPC.clero && objMesh.transform.parent.GetComponent <BodyChange>().dominate&& !_target.GetComponent <BodyChange>().dominate&& !LOSHelper.CheckBoundsVisibility(losSource, objMesh.GetComponent <Renderer>().bounds, layerMask) && _target.GetComponent <SimpleIA>().getDetectado()) { // Debug.Log("no veo impostor"+ objMesh.transform.parent.name+" "+ _target.name); _target.GetComponent <SimpleIA>().setDetectado(false); _target.GetComponent <SimpleIA>().setState(2); //return true; } return(false); }