public Vector4d(Vector3d2 v, double w) { x = v.x; y = v.y; z = v.z; this.w = w; }
static public Matrix4x4d Translate(Vector3d2 v) { return(new Matrix4x4d(1, 0, 0, v.x, 0, 1, 0, v.y, 0, 0, 1, v.z, 0, 0, 0, 1)); }
public override Box2d DeformedToLocalBounds(Vector3d2 deformedCenter, double deformedRadius) { Vector3d2 p = DeformedToLocal(deformedCenter); double r = deformedRadius; if (double.IsInfinity(p.x) || double.IsInfinity(p.y)) { return(new Box2d()); } double k = (1.0 - r * r / (2.0 * R * R)) * (new Vector3d2(p.x, p.y, R)).Magnitude(); double A = k * k - p.x * p.x; double B = k * k - p.y * p.y; double C = -2.0 * p.x * p.y; double D = -2.0 * R * R * p.x; double E = -2.0 * R * R * p.y; double F = R * R * (k * k - R * R); double a = C * C - 4.0 * A * B; double b = 2.0 * C * E - 4.0 * B * D; double c = E * E - 4.0 * B * F; double d = Math.Sqrt(b * b - 4.0 * a * c); double x1 = (-b - d) / (2.0 * a); double x2 = (-b + d) / (2.0 * a); b = 2.0 * C * D - 4.0 * A * E; c = D * D - 4.0 * A * F; d = Math.Sqrt(b * b - 4.0 * a * c); double y1 = (-b - d) / (2.0 * a); double y2 = (-b + d) / (2.0 * a); return(new Box2d(new Vector2d(x1, y1), new Vector2d(x2, y2))); }
/* * Sets the shader uniforms that are necessary to project on screen the * given TerrainQuad. This method can set the uniforms that are specific to * the given quad. */ public virtual void SetUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock) { if (matPropertyBlock == null || node == null || quad == null) { return; } double ox = quad.GetOX(); double oy = quad.GetOY(); double l = quad.GetLength(); double distFactor = (double)node.GetDistFactor(); int level = quad.GetLevel(); matPropertyBlock.AddVector(m_uniforms.offset, new Vector4((float)ox, (float)oy, (float)l, (float)level)); Vector3d2 camera = node.GetLocalCameraPos(); matPropertyBlock.AddVector(m_uniforms.camera, new Vector4((float)((camera.x - ox) / l), (float)((camera.y - oy) / l), (float)((camera.z - node.GetView().GetGroundHeight()) / (l * distFactor)), (float)camera.z)); Vector3d2 c = node.GetLocalCameraPos(); Matrix3x3d m = m_localToTangent * (new Matrix3x3d(l, 0.0, ox - c.x, 0.0, l, oy - c.y, 0.0, 0.0, 1.0)); matPropertyBlock.AddMatrix(m_uniforms.tileToTangent, m.ToMatrix4x4()); SetScreenUniforms(node, quad, matPropertyBlock); }
protected virtual void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock) { double ox = quad.GetOX(); double oy = quad.GetOY(); double l = quad.GetLength(); Vector3d2 p0 = new Vector3d2(ox, oy, 0.0); Vector3d2 p1 = new Vector3d2(ox + l, oy, 0.0); Vector3d2 p2 = new Vector3d2(ox, oy + l, 0.0); Vector3d2 p3 = new Vector3d2(ox + l, oy + l, 0.0); Matrix4x4d corners = new Matrix4x4d(p0.x, p1.x, p2.x, p3.x, p0.y, p1.y, p2.y, p3.y, p0.z, p1.z, p2.z, p3.z, 1.0, 1.0, 1.0, 1.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * corners).ToMatrix4x4()); Matrix4x4d verticals = new Matrix4x4d(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * verticals).ToMatrix4x4()); }
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(); }
public static Frustum.VISIBILTY GetVisibility(Vector4d clip, Vector3d2[] b, double f) { double o = b[0].x * clip.x + b[0].y * clip.y + b[0].z * clip.z; bool p = o + clip.w > 0.0; if ((o * f + clip.w > 0.0) == p) { o = b[1].x * clip.x + b[1].y * clip.y + b[1].z * clip.z; if ((o + clip.w > 0.0) == p && (o * f + clip.w > 0.0) == p) { o = b[2].x * clip.x + b[2].y * clip.y + b[2].z * clip.z; if ((o + clip.w > 0.0) == p && (o * f + clip.w > 0.0) == p) { o = b[3].x * clip.x + b[3].y * clip.y + b[3].z * clip.z; return (o + clip.w > 0.0) == p && (o * f + clip.w > 0.0) == p ? (p ? Frustum.VISIBILTY.FULLY : Frustum.VISIBILTY.INVISIBLE) : Frustum.VISIBILTY.PARTIALLY; } } } return Frustum.VISIBILTY.PARTIALLY; }
public Quat(Vector3d2 to, Vector3d2 _from) { Vector3d2 f = _from.Normalized(); Vector3d2 t = to.Normalized(); double dotProdPlus1 = 1.0 + f.Dot(t); if (dotProdPlus1 < 1e-7) { w = 0; if (System.Math.Abs(f.x) < 0.6) { double norm = System.Math.Sqrt(1 - f.x * f.x); x = 0; y = f.z / norm; z = -f.y / norm; } else if (System.Math.Abs(f.y) < 0.6) { double norm = System.Math.Sqrt(1 - f.y * f.y); x = -f.z / norm; y = 0; z = f.x / norm; } else { double norm = System.Math.Sqrt(1 - f.z * f.z); x = f.y / norm; y = -f.x / norm; z = 0; } } else { double s = System.Math.Sqrt(0.5 * dotProdPlus1); Vector3d2 tmp = (f.Cross(t)) / (2.0 * s); x = tmp.x; y = tmp.y; z = tmp.z; w = s; } }
static public Matrix4x4d Scale(Vector3d2 v) { return(new Matrix4x4d(v.x, 0, 0, 0, 0, v.y, 0, 0, 0, 0, v.z, 0, 0, 0, 0, 1)); }
/* * Sets the shader uniforms that are necessary to project on screen the * TerrainQuad of the given TerrainNode. This method can set the uniforms * that are common to all the quads of the given terrain. */ public virtual void SetUniforms(TerrainNode node, Material mat) { if (mat == null || node == null) { return; } float d1 = node.GetSplitDist() + 1.0f; float d2 = 2.0f * node.GetSplitDist(); mat.SetVector(m_uniforms.blending, new Vector2(d1, d2 - d1)); m_localToCamera = node.GetView().GetWorldToCamera() * node.GetLocalToWorld(); m_localToScreen = node.GetView().GetCameraToScreen() * m_localToCamera; Vector3d2 localCameraPos = node.GetLocalCameraPos(); Vector3d2 worldCamera = node.GetView().GetWorldCameraPos(); Matrix4x4d A = LocalToDeformedDifferential(localCameraPos); Matrix4x4d B = DeformedToTangentFrame(worldCamera); Matrix4x4d ltot = B * node.GetLocalToWorld() * A; m_localToTangent = new Matrix3x3d(ltot.m[0, 0], ltot.m[0, 1], ltot.m[0, 3], ltot.m[1, 0], ltot.m[1, 1], ltot.m[1, 3], ltot.m[3, 0], ltot.m[3, 1], ltot.m[3, 3]); mat.SetMatrix(m_uniforms.localToScreen, m_localToScreen.ToMatrix4x4()); mat.SetMatrix(m_uniforms.localToWorld, node.GetLocalToWorld().ToMatrix4x4()); }
static public Matrix4x4d Rotate(Vector3d2 rotation) { Quat x = new Quat(new Vector3d2(1, 0, 0), rotation.x * MathUtility.Deg2Rad); Quat y = new Quat(new Vector3d2(0, 1, 0), rotation.y * MathUtility.Deg2Rad); Quat z = new Quat(new Vector3d2(0, 0, 1), rotation.z * MathUtility.Deg2Rad); return((z * y * x).ToMatrix4x4d()); }
// Use this for initialization void Start() { m_view = GetComponent <TerrainView>(); m_target = new TerrainView.Position(); m_start = new TerrainView.Position(); m_end = new TerrainView.Position(); m_previousMousePos = new Vector3d2(Input.mousePosition); }
/* * Returns a direction interpolated between the two given direction. * * param slon start longitude. * param slat start latitude. * param elon end longitude. * param elat end latitude. * param t interpolation parameter between 0 and 1. * param[out] lon interpolated longitude. * param[out] lat interpolated latitude. */ public virtual void InterpolateDirection(double slon, double slat, double elon, double elat, double t, ref double lon, ref double lat) { Vector3d2 s = new Vector3d2(Math.Cos(slon) * Math.Cos(slat), Math.Sin(slon) * Math.Cos(slat), Math.Sin(slat)); Vector3d2 e = new Vector3d2(Math.Cos(elon) * Math.Cos(elat), Math.Sin(elon) * Math.Cos(elat), Math.Sin(elat)); Vector3d2 v = (s * (1.0 - t) + e * t).Normalized(); lat = MathUtility.Safe_Asin(v.z); lon = Math.Atan2(v.y, v.x); }
public Box3d(Vector3d2 p, Vector3d2 q) { xmin = System.Math.Min(p.x,q.x); xmax = System.Math.Max(p.x,q.x); ymin = System.Math.Min(p.y,q.y); ymax = System.Math.Max(p.y,q.y); zmin = System.Math.Min(p.z,q.z); zmax = System.Math.Max(p.z,q.z); }
public Box3d(Vector3d2 p, Vector3d2 q) { xmin = System.Math.Min(p.x, q.x); xmax = System.Math.Max(p.x, q.x); ymin = System.Math.Min(p.y, q.y); ymax = System.Math.Max(p.y, q.y); zmin = System.Math.Min(p.z, q.z); zmax = System.Math.Max(p.z, q.z); }
public static Vector3d2 operator *(Matrix3x3d m, Vector3d2 v) { Vector3d2 kProd = new Vector3d2(); kProd.x = m.m[0,0] * v.x + m.m[0,1] * v.y + m.m[0,2] * v.z; kProd.y = m.m[1,0] * v.x + m.m[1,1] * v.y + m.m[1,2] * v.z; kProd.z = m.m[2,0] * v.x + m.m[2,1] * v.y + m.m[2,2] * v.z; return kProd; }
public static Vector3d2 operator *(Matrix3x3d m, Vector3d2 v) { Vector3d2 kProd = new Vector3d2(); kProd.x = m.m[0, 0] * v.x + m.m[0, 1] * v.y + m.m[0, 2] * v.z; kProd.y = m.m[1, 0] * v.x + m.m[1, 1] * v.y + m.m[1, 2] * v.z; kProd.z = m.m[2, 0] * v.x + m.m[2, 1] * v.y + m.m[2, 2] * v.z; return(kProd); }
// Update is called once per frame public virtual void UpdateView() { Constrain(); SetWorldToCameraMatrix(); SetProjectionMatrix(); m_worldCameraPos = m_worldPos; m_cameraDir = (m_worldPos - GetLookAtPos()).Normalized(); }
public Quat(Vector3d2 axis, double angle) { Vector3d2 axisN = axis.Normalized(); double a = angle * 0.5; double sina = System.Math.Sin(a); double cosa = System.Math.Cos(a); x = axisN.x * sina; y = axisN.y * sina; z = axisN.z * sina; w = cosa; }
public override Matrix4x4d DeformedToTangentFrame(Vector3d2 deformedPt) { Vector3d2 Uz = deformedPt.Normalized(); Vector3d2 Ux = (new Vector3d2(0, 1, 0)).Cross(Uz).Normalized(); Vector3d2 Uy = Uz.Cross(Ux); return(new Matrix4x4d(Ux.x, Ux.y, Ux.z, 0.0, Uy.x, Uy.y, Uy.z, 0.0, Uz.x, Uz.y, Uz.z, -R, 0.0, 0.0, 0.0, 1.0)); }
public static Vector3d2 operator *(Matrix4x4d m, Vector3d2 v) { Vector3d2 kProd = new Vector3d2(); double fInvW = 1.0 / (m.m[3, 0] * v.x + m.m[3, 1] * v.y + m.m[3, 2] * v.z + m.m[3, 3]); kProd.x = (m.m[0, 0] * v.x + m.m[0, 1] * v.y + m.m[0, 2] * v.z + m.m[0, 3]) * fInvW; kProd.y = (m.m[1, 0] * v.x + m.m[1, 1] * v.y + m.m[1, 2] * v.z + m.m[1, 3]) * fInvW; kProd.z = (m.m[2, 0] * v.x + m.m[2, 1] * v.y + m.m[2, 2] * v.z + m.m[2, 3]) * fInvW; return(kProd); }
// Use this for initialization protected virtual void Start() { m_worldToCameraMatrix = Matrix4x4d.Identity(); m_cameraToWorldMatrix = Matrix4x4d.Identity(); m_cameraToScreenMatrix = Matrix4x4d.Identity(); m_screenToCameraMatrix = Matrix4x4d.Identity(); m_worldCameraPos = new Vector3d2(); m_cameraDir = new Vector3d2(); m_worldPos = new Vector3d2(); Constrain(); }
public override void Move(Vector3d2 oldp, Vector3d2 p, double speed) { Vector3d2 oldpos = oldp.Normalized(); Vector3d2 pos = p.Normalized(); double oldlat = MathUtility.Safe_Asin(oldpos.z); double oldlon = Math.Atan2(oldpos.y, oldpos.x); double lat = MathUtility.Safe_Asin(pos.z); double lon = Math.Atan2(pos.y, pos.x); m_position.x0 -= (lon - oldlon) * speed * Math.Max(1.0, GetHeight()); m_position.y0 -= (lat - oldlat) * speed * Math.Max(1.0, GetHeight()); }
/* * Override the default TileSampler NeedTile to retrive the tile * that is below the camera as well as its default behaviour */ protected override bool NeedTile(TerrainQuad quad) { Vector3d2 c = quad.GetOwner().GetLocalCameraPos(); int l = quad.GetLevel(); double ox = quad.GetOX(); double oy = quad.GetOY(); if (c.x >= ox && c.x < ox + l && c.y >= oy && c.y < oy + l) { return(true); } return(base.NeedTile(quad)); }
protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock) { double ox = quad.GetOX(); double oy = quad.GetOY(); double l = quad.GetLength(); Vector3d2 p0 = new Vector3d2(ox, oy, R); Vector3d2 p1 = new Vector3d2(ox + l, oy, R); Vector3d2 p2 = new Vector3d2(ox, oy + l, R); Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R); Vector3d2 pc = (p0 + p3) * 0.5; double l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0; Vector3d2 v0 = p0.Normalized(ref l0); Vector3d2 v1 = p1.Normalized(ref l1); Vector3d2 v2 = p2.Normalized(ref l2); Vector3d2 v3 = p3.Normalized(ref l3); Matrix4x4d deformedCorners = new Matrix4x4d(v0.x * R, v1.x * R, v2.x * R, v3.x * R, v0.y * R, v1.y * R, v2.y * R, v3.y * R, v0.z * R, v1.z * R, v2.z * R, v3.z * R, 1.0, 1.0, 1.0, 1.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4()); Matrix4x4d deformedVerticals = new Matrix4x4d(v0.x, v1.x, v2.x, v3.x, v0.y, v1.y, v2.y, v3.y, v0.z, v1.z, v2.z, v3.z, 0.0, 0.0, 0.0, 0.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4()); matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3)); Vector3d2 uz = pc.Normalized(); Vector3d2 ux = (new Vector3d2(0, 1, 0)).Cross(uz).Normalized(); Vector3d2 uy = uz.Cross(ux); Matrix4x4d ltow = node.GetLocalToWorld(); Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0, 0], ltow.m[0, 1], ltow.m[0, 2], ltow.m[1, 0], ltow.m[1, 1], ltow.m[1, 2], ltow.m[2, 0], ltow.m[2, 1], ltow.m[2, 2]); Matrix3x3d m = new Matrix3x3d(ux.x, uy.x, uz.x, ux.y, uy.y, uz.y, ux.z, uy.z, uz.z); matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4()); }
public override void MoveForward(double distance) { double co = Math.Cos(m_position.x0); // x0 = longitude double so = Math.Sin(m_position.x0); double ca = Math.Cos(m_position.y0); // y0 = latitude double sa = Math.Sin(m_position.y0); Vector3d2 po = new Vector3d2(co * ca, so * ca, sa) * m_radius; Vector3d2 px = new Vector3d2(-so, co, 0.0); Vector3d2 py = new Vector3d2(-co * sa, -so * sa, ca); Vector3d2 pd = (po - px * Math.Sin(m_position.phi) * distance + py * Math.Cos(m_position.phi) * distance).Normalized(); m_position.x0 = Math.Atan2(pd.y, pd.x); m_position.y0 = MathUtility.Safe_Asin(pd.z); }
public override void Start() { base.Start(); m_oldLocalCamera = Vector3d2.Zero(); m_needReadBack = new Dictionary <Tile.Id, QuadTreeZ>(new Tile.EqualityComparerID()); m_elevations = new DictionaryQueue <Tile.Id, ElevationInfo>(new Tile.EqualityComparerID()); int size = GetProducer().GetTileSize(0); m_elevationsBuffer = new ComputeBuffer(size * size, sizeof(float)); m_groundBuffer = new ComputeBuffer(1, sizeof(float)); }
protected override void SetWorldToCameraMatrix() { double co = Math.Cos(m_position.x0); // x0 = longitude double so = Math.Sin(m_position.x0); double ca = Math.Cos(m_position.y0); // y0 = latitude double sa = Math.Sin(m_position.y0); Vector3d2 po = new Vector3d2(co*ca, so*ca, sa) * m_radius; Vector3d2 px = new Vector3d2(-so, co, 0.0); Vector3d2 py = new Vector3d2(-co*sa, -so*sa, ca); Vector3d2 pz = new Vector3d2(co*ca, so*ca, sa); double ct = Math.Cos(m_position.theta); double st = Math.Sin(m_position.theta); double cp = Math.Cos(m_position.phi); double sp = Math.Sin(m_position.phi); Vector3d2 cx = px * cp + py * sp; Vector3d2 cy = (px*-1.0) * sp*ct + py * cp*ct + pz * st; Vector3d2 cz = px * sp*st - py * cp*st + pz * ct; m_worldPos = po + cz * m_position.distance; if (m_worldPos.Magnitude() < m_radius + 10.0 + m_groundHeight) { m_worldPos = m_worldPos.Normalized(m_radius + 10.0 + m_groundHeight); } Matrix4x4d view = new Matrix4x4d( cx.x, cx.y, cx.z, 0.0, cy.x, cy.y, cy.z, 0.0, cz.x, cz.y, cz.z, 0.0, 0.0, 0.0, 0.0, 1.0); m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0); //Flip first row to match Unitys winding order. m_worldToCameraMatrix.m[0,0] *= -1.0; m_worldToCameraMatrix.m[0,1] *= -1.0; m_worldToCameraMatrix.m[0,2] *= -1.0; m_worldToCameraMatrix.m[0,3] *= -1.0; m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse(); camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4(); camera.transform.position = m_worldPos.ToVector3(); }
protected override void SetWorldToCameraMatrix() { double co = Math.Cos(m_position.x0); // x0 = longitude double so = Math.Sin(m_position.x0); double ca = Math.Cos(m_position.y0); // y0 = latitude double sa = Math.Sin(m_position.y0); Vector3d2 po = new Vector3d2(co * ca, so * ca, sa) * m_radius; Vector3d2 px = new Vector3d2(-so, co, 0.0); Vector3d2 py = new Vector3d2(-co * sa, -so * sa, ca); Vector3d2 pz = new Vector3d2(co * ca, so * ca, sa); double ct = Math.Cos(m_position.theta); double st = Math.Sin(m_position.theta); double cp = Math.Cos(m_position.phi); double sp = Math.Sin(m_position.phi); Vector3d2 cx = px * cp + py * sp; Vector3d2 cy = (px * -1.0) * sp * ct + py * cp * ct + pz * st; Vector3d2 cz = px * sp * st - py * cp * st + pz * ct; m_worldPos = po + cz * m_position.distance; if (m_worldPos.Magnitude() < m_radius + 10.0 + m_groundHeight) { m_worldPos = m_worldPos.Normalized(m_radius + 10.0 + m_groundHeight); } Matrix4x4d view = new Matrix4x4d(cx.x, cx.y, cx.z, 0.0, cy.x, cy.y, cy.z, 0.0, cz.x, cz.y, cz.z, 0.0, 0.0, 0.0, 0.0, 1.0); m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0); //Flip first row to match Unitys winding order. m_worldToCameraMatrix.m[0, 0] *= -1.0; m_worldToCameraMatrix.m[0, 1] *= -1.0; m_worldToCameraMatrix.m[0, 2] *= -1.0; m_worldToCameraMatrix.m[0, 3] *= -1.0; m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse(); camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4(); camera.transform.position = m_worldPos.ToVector3(); }
public override double Interpolate( double sx0, double sy0, double stheta, double sphi, double sd, double dx0, double dy0, double dtheta, double dphi, double dd, double t) { Vector3d2 s = new Vector3d2(Math.Cos(sx0) * Math.Cos(sy0), Math.Sin(sx0) * Math.Cos(sy0), Math.Sin(sy0)); Vector3d2 e = new Vector3d2(Math.Cos(dx0) * Math.Cos(dy0), Math.Sin(dx0) * Math.Cos(dy0), Math.Sin(dy0)); double dist = Math.Max(MathUtility.Safe_Acos(s.Dot(e)) * m_radius, 1e-3); t = Math.Min(t + Math.Min(0.1, 5000.0 / dist), 1.0); double T = 0.5 * Math.Atan(4.0 * (t - 0.5)) / Math.Atan(4.0 * 0.5) + 0.5; InterpolateDirection(sx0, sy0, dx0, dy0, T, ref m_position.x0, ref m_position.y0); InterpolateDirection(sphi, stheta, dphi, dtheta, T, ref m_position.phi, ref m_position.theta); double W = 10.0; m_position.distance = sd * (1.0 - t) + dd * t + dist * (Math.Exp(-W * (t - 0.5) * (t - 0.5)) - Math.Exp(-W * 0.25)); return t; }
public override double Interpolate(double sx0, double sy0, double stheta, double sphi, double sd, double dx0, double dy0, double dtheta, double dphi, double dd, double t) { Vector3d2 s = new Vector3d2(Math.Cos(sx0) * Math.Cos(sy0), Math.Sin(sx0) * Math.Cos(sy0), Math.Sin(sy0)); Vector3d2 e = new Vector3d2(Math.Cos(dx0) * Math.Cos(dy0), Math.Sin(dx0) * Math.Cos(dy0), Math.Sin(dy0)); double dist = Math.Max(MathUtility.Safe_Acos(s.Dot(e)) * m_radius, 1e-3); t = Math.Min(t + Math.Min(0.1, 5000.0 / dist), 1.0); double T = 0.5 * Math.Atan(4.0 * (t - 0.5)) / Math.Atan(4.0 * 0.5) + 0.5; InterpolateDirection(sx0, sy0, dx0, dy0, T, ref m_position.x0, ref m_position.y0); InterpolateDirection(sphi, stheta, dphi, dtheta, T, ref m_position.phi, ref m_position.theta); double W = 10.0; m_position.distance = sd * (1.0 - t) + dd * t + dist * (Math.Exp(-W * (t - 0.5) * (t - 0.5)) - Math.Exp(-W * 0.25)); return(t); }
/* * Computes the world to camera matrix using double precision * and applies it to the camera. */ protected virtual void SetWorldToCameraMatrix() { Vector3d2 po = new Vector3d2(m_position.x0, m_position.y0, 0.0); Vector3d2 px = new Vector3d2(1.0, 0.0, 0.0); Vector3d2 py = new Vector3d2(0.0, 1.0, 0.0); Vector3d2 pz = new Vector3d2(0.0, 0.0, 1.0); double ct = Math.Cos(m_position.theta); double st = Math.Sin(m_position.theta); double cp = Math.Cos(m_position.phi); double sp = Math.Sin(m_position.phi); Vector3d2 cx = px * cp + py * sp; Vector3d2 cy = (px * -1.0) * sp * ct + py * cp * ct + pz * st; Vector3d2 cz = px * sp * st - py * cp * st + pz * ct; m_worldPos = po + cz * m_position.distance; if (m_worldPos.z < m_groundHeight + 10.0) { m_worldPos.z = m_groundHeight + 10.0; } Matrix4x4d view = new Matrix4x4d(cx.x, cx.y, cx.z, 0.0, cy.x, cy.y, cy.z, 0.0, cz.x, cz.y, cz.z, 0.0, 0.0, 0.0, 0.0, 1.0); m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0); m_worldToCameraMatrix.m[0, 0] *= -1.0; m_worldToCameraMatrix.m[0, 1] *= -1.0; m_worldToCameraMatrix.m[0, 2] *= -1.0; m_worldToCameraMatrix.m[0, 3] *= -1.0; m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse(); camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4(); camera.transform.position = m_worldPos.ToVector3(); }
public override Matrix4x4d LocalToDeformedDifferential(Vector3d2 localPt, bool clamp = false) { if (!MathUtility.IsFinite(localPt.x) || !MathUtility.IsFinite(localPt.y) || !MathUtility.IsFinite(localPt.z)) { return Matrix4x4d.Identity(); } Vector3d2 pt = new Vector3d2(localPt); if (clamp) { pt.x = pt.x - Math.Floor((pt.x + R) / (2.0 * R)) * 2.0 * R; pt.y = pt.y - Math.Floor((pt.y + R) / (2.0 * R)) * 2.0 * R; } double l = pt.x*pt.x + pt.y*pt.y + R*R; double c0 = 1.0 / Math.Sqrt(l); double c1 = c0 * R / l; return new Matrix4x4d(( pt.y*pt.y + R*R)*c1, -pt.x*pt.y*c1, pt.x*c0, R*pt.x*c0, -pt.x*pt.y*c1, (pt.x*pt.x + R*R)*c1, pt.y*c0, R*pt.y*c0, -pt.x*R*c1, -pt.y*R*c1, R*c0, (R*R)*c0, 0.0, 0.0, 0.0, 1.0); }
/* * Updates the ground height below camera. */ void UpdateGroundHeight() { Vector3d2 localCamPos = GetTerrainNode().GetLocalCameraPos(); //If camera has moved update ground height if ((localCamPos - m_oldLocalCamera).Magnitude() > 1.0 && m_cameraQuad != null && m_cameraQuad.tile != null) { GPUTileStorage.GPUSlot slot = m_cameraQuad.tile.GetSlot()[0] as GPUTileStorage.GPUSlot; if (slot != null) { int border = GetProducer().GetBorder(); int tileSize = GetProducer().GetTileSizeMinBorder(0); float dx = m_cameraQuadCoords.x * tileSize; float dy = m_cameraQuadCoords.y * tileSize; //x,y are the non-normalized position in the elevations texture where the //ground height below the camera is. float x = dx + (float)border; float y = dy + (float)border; //Read the single value from the render texture CBUtility.ReadSingleFromRenderTexture(slot.GetTexture(), x, y, 0, m_groundBuffer, m_manager.GetReadData(), true); //Get single height value from buffer float[] height = new float[1]; m_groundBuffer.GetData(height); //Update the ground height. Stored as a static value in the TerrainNode script GetView().SetGroundHeight(Math.Max(0.0, height[0])); m_oldLocalCamera.x = localCamPos.x; m_oldLocalCamera.y = localCamPos.y; m_oldLocalCamera.z = localCamPos.z; } } m_cameraQuad = null; }
protected override void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad) { if (tree == null) { tree = new QuadTreeZ(parent, quad); tree.needTile = NeedTile(quad); } QuadTreeZ t = tree as QuadTreeZ; //If tile needs elevation data read back add to container if (t.tile != null && t.tile.GetTask().IsDone() && !t.readBack && m_maxReadBacksPerFrame > 0) { if (!m_needReadBack.ContainsKey(t.tile.GetId())) { t.readBack = true; m_needReadBack.Add(t.tile.GetId(), t); } } base.GetTiles(parent, ref tree, quad); //Check if this quad is below the camera. If so store a reference to it. if (m_cameraQuad == null && t.tile != null && t.tile.GetTask().IsDone()) { Vector3d2 c = quad.GetOwner().GetLocalCameraPos(); double l = quad.GetLength(); double ox = quad.GetOX(); double oy = quad.GetOY(); if (c.x >= ox && c.x < ox + l && c.y >= oy && c.y < oy + l) { m_cameraQuadCoords = new Vector2((float)((c.x - ox) / l), (float)((c.y - oy) / l)); m_cameraQuad = t; } } }
public override Matrix4x4d LocalToDeformedDifferential(Vector3d2 localPt, bool clamp = false) { if (!MathUtility.IsFinite(localPt.x) || !MathUtility.IsFinite(localPt.y) || !MathUtility.IsFinite(localPt.z)) { return(Matrix4x4d.Identity()); } Vector3d2 pt = new Vector3d2(localPt); if (clamp) { pt.x = pt.x - Math.Floor((pt.x + R) / (2.0 * R)) * 2.0 * R; pt.y = pt.y - Math.Floor((pt.y + R) / (2.0 * R)) * 2.0 * R; } double l = pt.x * pt.x + pt.y * pt.y + R * R; double c0 = 1.0 / Math.Sqrt(l); double c1 = c0 * R / l; return(new Matrix4x4d((pt.y * pt.y + R * R) * c1, -pt.x * pt.y * c1, pt.x * c0, R * pt.x * c0, -pt.x * pt.y * c1, (pt.x * pt.x + R * R) * c1, pt.y * c0, R * pt.y * c0, -pt.x * R * c1, -pt.y * R * c1, R * c0, (R * R) * c0, 0.0, 0.0, 0.0, 1.0)); }
public override void MoveForward(double distance) { double co = Math.Cos(m_position.x0); // x0 = longitude double so = Math.Sin(m_position.x0); double ca = Math.Cos(m_position.y0); // y0 = latitude double sa = Math.Sin(m_position.y0); Vector3d2 po = new Vector3d2(co*ca, so*ca, sa) * m_radius; Vector3d2 px = new Vector3d2(-so, co, 0.0); Vector3d2 py = new Vector3d2(-co*sa, -so*sa, ca); Vector3d2 pd = (po - px * Math.Sin(m_position.phi) * distance + py * Math.Cos(m_position.phi) * distance).Normalized(); m_position.x0 = Math.Atan2(pd.y, pd.x); m_position.y0 = MathUtility.Safe_Asin(pd.z); }
// Use this for initialization void Start() { m_view = GetComponent<TerrainView>(); m_target = new TerrainView.Position(); m_start = new TerrainView.Position(); m_end = new TerrainView.Position(); m_previousMousePos = new Vector3d2(Input.mousePosition); }
/** * Returns an orthonormal reference frame of the tangent space at the given * deformed point. This reference frame is such that its xy plane is the * tangent plane, at deformedPt, to the deformed surface corresponding to * the local plane z=0. Note that this orthonormal reference frame does * not give the differential of the inverse deformation funtion, * which in general is not an orthonormal transformation. If p is a deformed * point, then deformedToLocalFrame(deformedPt) * p gives the coordinates of * p in the orthonormal reference frame defined above. * * param deformedPt a point in the deformed (i.e., destination) space. * return the orthonormal reference frame at deformedPt defined above. */ public virtual Matrix4x4d DeformedToTangentFrame(Vector3d2 deformedPt) { return Matrix4x4d.Translate(new Vector3d2(-deformedPt.x, -deformedPt.y, 0.0)); }
void MouseMotion() { if(Input.GetMouseButton(0) && Input.GetKey(KeyCode.LeftControl)) { m_target.phi -= Input.GetAxis("Mouse X") * m_rotateSpeed; m_target.theta += Input.GetAxis("Mouse Y") * m_rotateSpeed; } else if(Input.GetMouseButton(0)) { Vector3d2 mousePos = new Vector3d2(); mousePos.x = Input.mousePosition.x; mousePos.y = Input.mousePosition.y; mousePos.z = 0.0; Vector3d2 preMousePos = new Vector3d2(); preMousePos.x = m_previousMousePos.x; preMousePos.y = m_previousMousePos.y; preMousePos.z = 0.0; Vector3d2 oldp = m_view.GetCameraToWorld() * preMousePos; Vector3d2 p = m_view.GetCameraToWorld() * mousePos; if (!(double.IsNaN(oldp.x) || double.IsNaN(oldp.y) || double.IsNaN(oldp.z) || double.IsNaN(p.x) || double.IsNaN(p.y) || double.IsNaN(p.z))) { TerrainView.Position current = new TerrainView.Position(); GetPosition(current); SetPosition(m_target); m_view.Move(new Vector3d2(oldp), new Vector3d2(p), m_dragSpeed); GetPosition(m_target); SetPosition(current); } } m_previousMousePos = new Vector3d2(Input.mousePosition); }
/* * Computes the world to camera matrix using double precision * and applies it to the camera. */ protected virtual void SetWorldToCameraMatrix() { Vector3d2 po = new Vector3d2(m_position.x0, m_position.y0, 0.0); Vector3d2 px = new Vector3d2(1.0, 0.0, 0.0); Vector3d2 py = new Vector3d2(0.0, 1.0, 0.0); Vector3d2 pz = new Vector3d2(0.0, 0.0, 1.0); double ct = Math.Cos(m_position.theta); double st = Math.Sin(m_position.theta); double cp = Math.Cos(m_position.phi); double sp = Math.Sin(m_position.phi); Vector3d2 cx = px * cp + py * sp; Vector3d2 cy = (px*-1.0) * sp*ct + py * cp*ct + pz * st; Vector3d2 cz = px * sp*st - py * cp*st + pz * ct; m_worldPos = po + cz * m_position.distance; if (m_worldPos.z < m_groundHeight + 10.0) { m_worldPos.z = m_groundHeight + 10.0; } Matrix4x4d view = new Matrix4x4d( cx.x, cx.y, cx.z, 0.0, cy.x, cy.y, cy.z, 0.0, cz.x, cz.y, cz.z, 0.0, 0.0, 0.0, 0.0, 1.0); m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0); m_worldToCameraMatrix.m[0,0] *= -1.0; m_worldToCameraMatrix.m[0,1] *= -1.0; m_worldToCameraMatrix.m[0,2] *= -1.0; m_worldToCameraMatrix.m[0,3] *= -1.0; m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse(); camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4(); camera.transform.position = m_worldPos.ToVector3(); }
/** * Returns the differential of the deformation function at the given local * point. This differential gives a linear approximation of the deformation * around a given point, represented with a matrix. More precisely, if p * is near localPt, then the deformed point corresponding to p can be * approximated with localToDeformedDifferential(localPt) * (p - localPt). * * param localPt a point in the local (i.e., source) space. The z * coordinate of this point is ignored, and considered to be 0. * return the differential of the deformation function at the given local * point. */ public virtual Matrix4x4d LocalToDeformedDifferential(Vector3d2 localPt, bool clamp = false) { return Matrix4x4d.Translate(new Vector3d2(localPt.x, localPt.y, 0.0)); }
/** * Returns the deformed point corresponding to the given source point. * * param localPt a point in the local (i.e., source) space. * return the corresponding point in the deformed (i.e., destination) space. */ public virtual Vector3d2 LocalToDeformed(Vector3d2 localPt) { return localPt; }
protected virtual void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock) { double ox = quad.GetOX(); double oy = quad.GetOY(); double l = quad.GetLength(); Vector3d2 p0 = new Vector3d2(ox, oy, 0.0); Vector3d2 p1 = new Vector3d2(ox + l, oy, 0.0); Vector3d2 p2 = new Vector3d2(ox, oy + l, 0.0); Vector3d2 p3 = new Vector3d2(ox + l, oy + l, 0.0); Matrix4x4d corners = new Matrix4x4d(p0.x, p1.x, p2.x, p3.x, p0.y, p1.y, p2.y, p3.y, p0.z, p1.z, p2.z, p3.z, 1.0, 1.0, 1.0, 1.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * corners).ToMatrix4x4()); Matrix4x4d verticals = new Matrix4x4d( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * verticals).ToMatrix4x4()); }
public void SetRow(int iRow, Vector3d2 v) { m[iRow,0] = v.x; m[iRow,1] = v.y; m[iRow,2] = v.z; }
public void SetColumn(int iCol, Vector3d2 v) { m[0,iCol] = v.x; m[1,iCol] = v.y; m[2,iCol] = v.z; }
/** * Returns the local bounding box corresponding to the given source disk. * * param deformedPt the source disk center in deformed space. * param deformedRadius the source disk radius in deformed space. * return the local bounding box corresponding to the given source disk. */ public virtual Box2d DeformedToLocalBounds(Vector3d2 deformedCenter, double deformedRadius) { return new Box2d(deformedCenter.x - deformedRadius, deformedCenter.x + deformedRadius, deformedCenter.y - deformedRadius, deformedCenter.y + deformedRadius); }
/** * Returns the local point corresponding to the given source point. * * param deformedPt a point in the deformed (i.e., destination) space. * return the corresponding point in the local (i.e., source) space. */ public virtual Vector3d2 DeformedToLocal(Vector3d2 deformedPt) { return deformedPt; }
public override Vector3d2 LocalToDeformed(Vector3d2 localPt) { return (new Vector3d2(localPt.x, localPt.y, R)).Normalized(localPt.z + R); }
/** * Returns the distance in local (i.e., source) space between a point and a * bounding box. * * param localPt a point in local space. * param localBox a bounding box in local space. */ public virtual double GetLocalDist(Vector3d2 localPt, Box3d localBox) { return Math.Max(Math.Abs(localPt.z - localBox.zmax), Math.Max(Math.Min(Math.Abs(localPt.x - localBox.xmin), Math.Abs(localPt.x - localBox.xmax)), Math.Min(Math.Abs(localPt.y - localBox.ymin), Math.Abs(localPt.y - localBox.ymax)))); }
/** * Returns a direction interpolated between the two given direction. * * param slon start longitude. * param slat start latitude. * param elon end longitude. * param elat end latitude. * param t interpolation parameter between 0 and 1. * param[out] lon interpolated longitude. * param[out] lat interpolated latitude. */ public virtual void InterpolateDirection(double slon, double slat, double elon, double elat, double t, ref double lon, ref double lat) { Vector3d2 s = new Vector3d2(Math.Cos(slon) * Math.Cos(slat), Math.Sin(slon) * Math.Cos(slat), Math.Sin(slat)); Vector3d2 e = new Vector3d2(Math.Cos(elon) * Math.Cos(elat), Math.Sin(elon) * Math.Cos(elat), Math.Sin(elat)); Vector3d2 v = (s * (1.0 - t) + e * t).Normalized(); lat = MathUtility.Safe_Asin(v.z); lon = Math.Atan2(v.y, v.x); }
/** * Moves the "look at" point so that "oldp" appears at the position of "p" * on screen. */ public virtual void Move(Vector3d2 oldp, Vector3d2 p, double speed) { m_position.x0 -= (p.x - oldp.x) * speed * Math.Max (1.0, GetHeight()); m_position.y0 -= (p.y - oldp.y) * speed * Math.Max (1.0, GetHeight()); }
protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock) { double ox = quad.GetOX(); double oy = quad.GetOY(); double l = quad.GetLength(); Vector3d2 p0 = new Vector3d2(ox, oy, R); Vector3d2 p1 = new Vector3d2(ox + l, oy, R); Vector3d2 p2 = new Vector3d2(ox, oy + l, R); Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R); Vector3d2 pc = (p0 + p3) * 0.5; double l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0; Vector3d2 v0 = p0.Normalized(ref l0); Vector3d2 v1 = p1.Normalized(ref l1); Vector3d2 v2 = p2.Normalized(ref l2); Vector3d2 v3 = p3.Normalized(ref l3); Matrix4x4d deformedCorners = new Matrix4x4d(v0.x * R, v1.x * R, v2.x * R, v3.x * R, v0.y * R, v1.y * R, v2.y * R, v3.y * R, v0.z * R, v1.z * R, v2.z * R, v3.z * R, 1.0, 1.0, 1.0, 1.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4()); Matrix4x4d deformedVerticals = new Matrix4x4d( v0.x, v1.x, v2.x, v3.x, v0.y, v1.y, v2.y, v3.y, v0.z, v1.z, v2.z, v3.z, 0.0, 0.0, 0.0, 0.0); matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4()); matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3)); Vector3d2 uz = pc.Normalized(); Vector3d2 ux = (new Vector3d2(0,1,0)).Cross(uz).Normalized(); Vector3d2 uy = uz.Cross(ux); Matrix4x4d ltow = node.GetLocalToWorld(); Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0,0], ltow.m[0,1], ltow.m[0,2], ltow.m[1,0], ltow.m[1,1], ltow.m[1,2], ltow.m[2,0], ltow.m[2,1], ltow.m[2,2]); Matrix3x3d m = new Matrix3x3d( ux.x, uy.x, uz.x, ux.y, uy.y, uz.y, ux.z, uy.z, uz.z); matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4()); }