private static void MyCurrentCamPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { ViewFrustumFunctions vf = d as ViewFrustumFunctions; object newVal = e.NewValue; HelixToolkit.SharpDX.ProjectionCamera cam = newVal as HelixToolkit.SharpDX.ProjectionCamera; if (vf != null && cam != null && vf.SynchrCam) { // clear children list vf.Children.Clear(); // get the size of the viewport double parentH = 0; double parentW = 0; Viewport3DX parent = vf.Parent as Viewport3DX; if (parent != null) { vf.CurrentPos = parent.CurrentPosition; parentH = parent.ActualHeight; parentW = parent.ActualWidth; //var test = parent.Parent; } // add new View Frustum vf.DefineViewFrustum(cam, parentH, parentW); vf.BuildViewFrustumModel(); } }
private void DefineViewFrustum(HelixToolkit.SharpDX.ProjectionCamera _cam, double _vpH, double _vpW) { if (_cam == null) { return; } // check for orthographic projection HelixToolkit.SharpDX.OrthographicCamera camOrtho = _cam as HelixToolkit.SharpDX.OrthographicCamera; // calculate CAMERA CS Point3D camPos = _cam.Position; Vector3D camViewDir = _cam.LookDirection; double distToTarget = camViewDir.Length; Utils.CommonExtensions.NormalizeVector3D(ref camViewDir); Vector3D camUpDir = _cam.UpDirection; Utils.CommonExtensions.NormalizeVector3D(ref camUpDir); // turn to orthogonal CS Vector3D camXDir = Vector3D.CrossProduct(camViewDir, camUpDir); Utils.CommonExtensions.NormalizeVector3D(ref camXDir); camUpDir = Vector3D.CrossProduct(camViewDir, camXDir); Utils.CommonExtensions.NormalizeVector3D(ref camUpDir); float zFar = (float)_cam.FarPlaneDistance; float zNear = (float)_cam.NearPlaneDistance; // calculate base of frustum pyramid // perspective projection float nHalfH = (float)((zNear / zFar) * _vpH); float nHalfW = (float)((zNear / zFar) * _vpW); if (camOrtho != null) { // orthographic projection nHalfH = (float)((zNear / zFar) * distToTarget * _vpH); nHalfW = (float)((zNear / zFar) * distToTarget * _vpW); } this.nearBL = camPos + zNear * camViewDir - nHalfW * camXDir - nHalfH * camUpDir; this.nearBR = camPos + zNear * camViewDir + nHalfW * camXDir - nHalfH * camUpDir; this.nearTL = camPos + zNear * camViewDir - nHalfW * camXDir + nHalfH * camUpDir; this.nearTR = camPos + zNear * camViewDir + nHalfW * camXDir + nHalfH * camUpDir; // perspective projection float fHalfH = nHalfH * zFar / zNear; float fHalfW = nHalfW * zFar / zNear; if (camOrtho != null) { // orthographic projection fHalfH = nHalfH; fHalfW = nHalfW; } this.farBL = camPos + zFar * camViewDir - fHalfW * camXDir - fHalfH * camUpDir; this.farBR = camPos + zFar * camViewDir + fHalfW * camXDir - fHalfH * camUpDir; this.farTL = camPos + zFar * camViewDir - fHalfW * camXDir + fHalfH * camUpDir; this.farTR = camPos + zFar * camViewDir + fHalfW * camXDir + fHalfH * camUpDir; // calculate normals // near this.posOnBoundary[(int)ViewFrustumOrientation.VF_NEAR] = new Point3D(this.nearBL.X * 0.5 + this.nearTR.X * 0.5, this.nearBL.Y * 0.5 + this.nearTR.Y * 0.5, this.nearBL.Z * 0.5 + this.nearTR.Z * 0.5); this.normals[(int)ViewFrustumOrientation.VF_NEAR] = camViewDir; // far this.posOnBoundary[(int)ViewFrustumOrientation.VF_FAR] = new Point3D(this.farBL.X * 0.5 + this.farTR.X * 0.5, this.farBL.Y * 0.5 + this.farTR.Y * 0.5, this.farBL.Z * 0.5 + this.farTR.Z * 0.5); this.normals[(int)ViewFrustumOrientation.VF_FAR] = -camViewDir; // left this.posOnBoundary[(int)ViewFrustumOrientation.VF_LEFT] = new Point3D(this.nearBL.X * 0.499 + this.nearTL.X * 0.499 + this.farBL.X * 0.001 + this.farTL.X * 0.001, this.nearBL.Y * 0.499 + this.nearTL.Y * 0.499 + this.farBL.Y * 0.001 + this.farTL.Y * 0.001, this.nearBL.Z * 0.499 + this.nearTL.Z * 0.499 + this.farBL.Z * 0.001 + this.farTL.Z * 0.001); Vector3D normalL = Vector3D.CrossProduct((this.farBL - this.nearBL), (this.nearBL - this.nearTL)); Utils.CommonExtensions.NormalizeVector3D(ref normalL); this.normals[(int)ViewFrustumOrientation.VF_LEFT] = normalL; // right this.posOnBoundary[(int)ViewFrustumOrientation.VF_RIGHT] = new Point3D(this.nearBR.X * 0.499 + this.nearTR.X * 0.499 + this.farBR.X * 0.001 + this.farTR.X * 0.001, this.nearBR.Y * 0.499 + this.nearTR.Y * 0.499 + this.farBR.Y * 0.001 + this.farTR.Y * 0.001, this.nearBR.Z * 0.499 + this.nearTR.Z * 0.499 + this.farBR.Z * 0.001 + this.farTR.Z * 0.001); Vector3D normalR = Vector3D.CrossProduct((this.farBR - this.nearBR), (this.nearTR - this.nearBR)); Utils.CommonExtensions.NormalizeVector3D(ref normalR); this.normals[(int)ViewFrustumOrientation.VF_RIGHT] = normalR; // top this.posOnBoundary[(int)ViewFrustumOrientation.VF_TOP] = new Point3D(this.nearTR.X * 0.499 + this.nearTL.X * 0.499 + this.farTR.X * 0.001 + this.farTL.X * 0.001, this.nearTR.Y * 0.499 + this.nearTL.Y * 0.499 + this.farTR.Y * 0.001 + this.farTL.Y * 0.001, this.nearTR.Z * 0.499 + this.nearTL.Z * 0.499 + this.farTR.Z * 0.001 + this.farTL.Z * 0.001); Vector3D normalT = Vector3D.CrossProduct((this.farTR - this.nearTR), (this.nearTL - this.nearTR)); Utils.CommonExtensions.NormalizeVector3D(ref normalT); this.normals[(int)ViewFrustumOrientation.VF_TOP] = normalT; // bottom this.posOnBoundary[(int)ViewFrustumOrientation.VF_BOTTOM] = new Point3D(this.nearBR.X * 0.499 + this.nearBL.X * 0.499 + this.farBR.X * 0.001 + this.farBL.X * 0.001, this.nearBR.Y * 0.499 + this.nearBL.Y * 0.499 + this.farBR.Y * 0.001 + this.farBL.Y * 0.001, this.nearBR.Z * 0.499 + this.nearBL.Z * 0.499 + this.farBR.Z * 0.001 + this.farBL.Z * 0.001); Vector3D normalB = Vector3D.CrossProduct((this.farBR - this.nearBR), (this.nearBR - this.nearBL)); Utils.CommonExtensions.NormalizeVector3D(ref normalB); this.normals[(int)ViewFrustumOrientation.VF_BOTTOM] = normalB; }