public override Vector3d2 DeformedToLocal(Vector3d2 deformedPt)
        {
            double l = deformedPt.Magnitude();

            if (deformedPt.z >= Math.Abs(deformedPt.x) && deformedPt.z >= Math.Abs(deformedPt.y))
            {
                return(new Vector3d2(deformedPt.x / deformedPt.z * R, deformedPt.y / deformedPt.z * R, l - R));
            }
            if (deformedPt.z <= -Math.Abs(deformedPt.x) && deformedPt.z <= -Math.Abs(deformedPt.y))
            {
                return(new Vector3d2(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity));
            }
            if (deformedPt.y >= Math.Abs(deformedPt.x) && deformedPt.y >= Math.Abs(deformedPt.z))
            {
                return(new Vector3d2(deformedPt.x / deformedPt.y * R, (2.0 - deformedPt.z / deformedPt.y) * R, l - R));
            }
            if (deformedPt.y <= -Math.Abs(deformedPt.x) && deformedPt.y <= -Math.Abs(deformedPt.z))
            {
                return(new Vector3d2(-deformedPt.x / deformedPt.y * R, (-2.0 - deformedPt.z / deformedPt.y) * R, l - R));
            }
            if (deformedPt.x >= Math.Abs(deformedPt.y) && deformedPt.x >= Math.Abs(deformedPt.z))
            {
                return(new Vector3d2((2.0 - deformedPt.z / deformedPt.x) * R, deformedPt.y / deformedPt.x * R, l - R));
            }
            if (deformedPt.x <= -Math.Abs(deformedPt.y) && deformedPt.x <= -Math.Abs(deformedPt.z))
            {
                return(new Vector3d2((-2.0 - deformedPt.z / deformedPt.x) * R, -deformedPt.y / deformedPt.x * R, l - R));
            }
            //should never reach here
            Debug.Log("Proland::SpericalDeformation::DeformToLocal - fail");
            return(new Vector3d2());
        }
		public override Vector3d2 DeformedToLocal(Vector3d2 deformedPt)
		{
			double l = deformedPt.Magnitude();
			
			if (deformedPt.z >= Math.Abs(deformedPt.x) && deformedPt.z >= Math.Abs(deformedPt.y)) {
				return new Vector3d2(deformedPt.x / deformedPt.z * R, deformedPt.y / deformedPt.z * R, l - R);
			}
			if (deformedPt.z <= -Math.Abs(deformedPt.x) && deformedPt.z <= -Math.Abs(deformedPt.y)) {
				return new Vector3d2(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity);
			}
			if (deformedPt.y >= Math.Abs(deformedPt.x) && deformedPt.y >= Math.Abs(deformedPt.z)) {
				return new Vector3d2(deformedPt.x / deformedPt.y * R, (2.0 - deformedPt.z / deformedPt.y) * R, l - R);
			}
			if (deformedPt.y <= -Math.Abs(deformedPt.x) && deformedPt.y <= -Math.Abs(deformedPt.z)) {
				return new Vector3d2(-deformedPt.x / deformedPt.y * R, (-2.0 - deformedPt.z / deformedPt.y) * R, l - R);
			}
			if (deformedPt.x >= Math.Abs(deformedPt.y) && deformedPt.x >= Math.Abs(deformedPt.z)) {
				return new Vector3d2((2.0 - deformedPt.z / deformedPt.x) * R, deformedPt.y / deformedPt.x * R, l - R);
			}
			if (deformedPt.x <= -Math.Abs(deformedPt.y) && deformedPt.x <= -Math.Abs(deformedPt.z)) {
				return new Vector3d2((-2.0 - deformedPt.z / deformedPt.x) * R, -deformedPt.y / deformedPt.x * R, l - R);
			}
			//should never reach here
			Debug.Log("Proland::SpericalDeformation::DeformToLocal - fail");
			return new Vector3d2();
		}
Beispiel #3
0
        public void updateCameraSpecificUniforms(Material oceanMaterial, Camera inCamera)
        {
            cameraToScreen = GL.GetGPUProjectionMatrix(inCamera.projectionMatrix, false);
            screenToCamera = cameraToScreen.inverse;

            m_oceanMaterial.SetMatrix("_Globals_CameraToScreen", cameraToScreen);
            m_oceanMaterial.SetMatrix("_Globals_ScreenToCamera", screenToCamera);


            //Calculates the required data for the projected grid

            // compute ltoo = localToOcean transform, where ocean frame = tangent space at
            // camera projection on sphere radius in local space

            //move these to dedicated projected grid class?

            Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix;

            Matrix4x4d cameraToWorld = new Matrix4x4d(ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03,
                                                      ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13,
                                                      ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23,
                                                      ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);

            Vector3d translation = m_manager.parentLocalTransform.position;


            Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x,
                                                     0, 1, 0, -translation.y,
                                                     0, 0, 1, -translation.z,
                                                     0, 0, 0, 1);

            Matrix4x4d camToLocal = worldToLocal * cameraToWorld;
            Matrix4x4d localToCam = camToLocal.Inverse();

            // camera in local space relative to planet's origin
            Vector3d2 cl = new Vector3d2();

            cl = camToLocal * Vector3d2.Zero();

            double radius = m_manager.GetRadius();

            uz = cl.Normalized();              // unit z vector of ocean frame, in local space

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                ux = (new Vector3d2(m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross(uz).Normalized();
            }
            else
            {
                ux = Vector3d2.UnitZ().Cross(uz).Normalized();
            }

            uy = uz.Cross(ux);              // unit y vector

            oo = uz * (radius);             // origin of ocean frame, in local space

            //local to ocean transform
            //computed from oo and ux, uy, uz should be correct
            Matrix4x4d localToOcean = new Matrix4x4d(
                ux.x, ux.y, ux.z, -ux.Dot(oo),
                uy.x, uy.y, uy.z, -uy.Dot(oo),
                uz.x, uz.y, uz.z, -uz.Dot(oo),
                0.0, 0.0, 0.0, 1.0);

            Matrix4x4d cameraToOcean = localToOcean * camToLocal;
            Matrix4x4d worldToOcean  = localToOcean * worldToLocal;

            Vector3d2 delta = new Vector3d2(0, 0, 0);

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                delta     = localToOcean * (m_oldlocalToOcean.Inverse() * Vector3d2.Zero());
                m_offset += delta;
            }

            //reset offset when bigger than 20000 to  avoid floating point issues when later casting the offset to float
            if (Mathf.Max(Mathf.Abs((float)m_offset.x), Mathf.Abs((float)m_offset.y)) > 20000f)
            {
                m_offset.x = 0.0;
                m_offset.y = 0.0;
            }

            m_oldlocalToOcean = localToOcean;

//			Matrix4x4d ctos = ModifiedProjectionMatrix (inCamera); //moved to command buffer
//			Matrix4x4d stoc = ctos.Inverse ();

            Vector3d2 oc = cameraToOcean * Vector3d2.Zero();

            h = oc.z;

            offset = new Vector3d2(-m_offset.x, -m_offset.y, h);

            //old horizon code
            //This breaks down when you tilt the camera by 90 degrees in any direction
            //I made some new horizon code down, scroll down

//			Vector4d stoc_w = (stoc * Vector4d.UnitW ()).XYZ0 ();
//			Vector4d stoc_x = (stoc * Vector4d.UnitX ()).XYZ0 ();
//			Vector4d stoc_y = (stoc * Vector4d.UnitY ()).XYZ0 ();
//
//			Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ ();
//			Vector3d2 dA = (cameraToOcean * stoc_x).XYZ ();
//			Vector3d2 B = (cameraToOcean * stoc_y).XYZ ();
//
//			Vector3d2 horizon1, horizon2;
//
//			double h1 = h * (h + 2.0 * radius);
//			double h2 = (h + radius) * (h + radius);
//			double alpha = B.Dot (B) * h1 - B.z * B.z * h2;
//
//			double beta0 = (A0.Dot (B) * h1 - B.z * A0.z * h2) / alpha;
//			double beta1 = (dA.Dot (B) * h1 - B.z * dA.z * h2) / alpha;
//
//			double gamma0 = (A0.Dot (A0) * h1 - A0.z * A0.z * h2) / alpha;
//			double gamma1 = (A0.Dot (dA) * h1 - A0.z * dA.z * h2) / alpha;
//			double gamma2 = (dA.Dot (dA) * h1 - dA.z * dA.z * h2) / alpha;
//
//			horizon1 = new Vector3d2 (-beta0, -beta1, 0.0);
//			horizon2 = new Vector3d2 (beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2);

            Vector3d2 sunDir      = new Vector3d2(m_manager.getDirectionToSun().normalized);
            Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d() * sunDir;

            oceanMaterial.SetMatrix(ShaderProperties._Globals_CameraToWorld_PROPERTY, cameraToWorld.ToMatrix4x4());

            oceanMaterial.SetVector(ShaderProperties._Ocean_SunDir_PROPERTY, oceanSunDir.ToVector3());

            oceanMaterial.SetMatrix(ShaderProperties._Ocean_CameraToOcean_PROPERTY, cameraToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Ocean_OceanToCamera_PROPERTY, cameraToOcean.Inverse().ToMatrix4x4());

//			oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, ctos.ToMatrix4x4 ());
//			oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, stoc.ToMatrix4x4 ());

            oceanMaterial.SetMatrix(ShaderProperties._Globals_WorldToOcean_PROPERTY, worldToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Globals_OceanToWorld_PROPERTY, worldToOcean.Inverse().ToMatrix4x4());

            oceanMaterial.SetVector(ShaderProperties._Ocean_CameraPos_PROPERTY, offset.ToVector3());

            //horizon calculations
            //these are used to find where the horizon line is on screen
            //and "clamp" vertexes that are above it back to it
            //as the grid is projected on the whole screen, vertexes over the horizon need to be dealt with
            //simply passing a flag to drop fragments or moving these vertexes offscreen will cause issues
            //as the horizon line can be between two vertexes and the horizon line will appear "pixelated"
            //as whole chunks go missing

            //these need to be done here
            //1)for double precision
            //2)for speed

            Vector3d2 sphereDir = localToCam * Vector3d2.Zero();             //vector to center of planet
            double    OHL       = sphereDir.Magnitude();                     //distance to center of planet

            sphereDir = sphereDir.Normalized();                              //direction to center of planet

            double rHorizon = Math.Sqrt((OHL)*(OHL)-(radius * radius));      //distance to the horizon, i.e distance to ocean sphere tangent
            //basic geometry yo

            //Theta=angle to horizon, now all that is left to do is check the viewdir against this angle in the shader
            double cosTheta = rHorizon / (OHL);
            double sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);

            oceanMaterial.SetVector(ShaderProperties.sphereDir_PROPERTY, sphereDir.ToVector3());
            oceanMaterial.SetFloat(ShaderProperties.cosTheta_PROPERTY, (float)cosTheta);
            oceanMaterial.SetFloat(ShaderProperties.sinTheta_PROPERTY, (float)sinTheta);

            //planetshine properties
            if (Scatterer.Instance.mainSettings.usePlanetShine)
            {
                Matrix4x4 planetShineSourcesMatrix = m_manager.m_skyNode.planetShineSourcesMatrix;

                Vector3d2 oceanSunDir2;
                for (int i = 0; i < 4; i++)
                {
                    Vector4 row = planetShineSourcesMatrix.GetRow(i);
                    oceanSunDir2 = localToOcean.ToMatrix3x3d() * new Vector3d2(row.x, row.y, row.z);
                    planetShineSourcesMatrix.SetRow(i, new Vector4((float)oceanSunDir2.x, (float)oceanSunDir2.y, (float)oceanSunDir2.z, row.w));
                }
                oceanMaterial.SetMatrix("planetShineSources", planetShineSourcesMatrix);                  //this can become shared code to not recompute

                oceanMaterial.SetMatrix("planetShineRGB", m_manager.m_skyNode.planetShineRGBMatrix);
            }

            if (!ReferenceEquals(causticsShadowMaskModulator, null))
            {
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix("CameraToWorld", inCamera.cameraToWorldMatrix);
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix("WorldToLight", Scatterer.Instance.sunLight.transform.worldToLocalMatrix);
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetVector("PlanetOrigin", m_manager.parentLocalTransform.position);

                float warpTime = (TimeWarp.CurrentRate > 1) ? (float)Planetarium.GetUniversalTime() : 0f;
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetFloat("warpTime", warpTime);
            }
        }