/// <summary> /// Pan the Camera around the Up vector by <c>theta_degrees</c> degrees. /// </summary> /// <param name="theta_degrees"> /// A <see cref="System.Double"/> /// </param> public void RotatecAboutAxis(Vec3f axis, double theta_degrees) { double theta = theta_degrees * Math.PI / 180; Vec3f tar = Quatf.AxisAngleToQuatf(axis, (float)theta).Rotate(Forward.Val * dist) + Position.Val; Set(tar, qrot * Quatf.AxisAngleToQuatf(axis, (float)theta), dist); }
public ViewerControl(ModelingHistory history) : base(new GraphicsMode(m_GLColorFormat, m_GLDepth, m_GLStencil, m_GLSamples, 48, 2, m_GLStereo), 3, 0, GraphicsContextFlags.Debug) { hist = history; //clusters = hist.Layers.GetClusters(); clusters = hist.Layers.GetClusteringLayer(currentClusterLayer).clusters; this.SuspendLayout(); this.BackColor = System.Drawing.Color.DimGray; this.ResumeLayout(false); base.CreateControl(); this.Cursor = Cursors.Cross; VSync = false; //setup viewables SetCluster(); //setup camera m_Camera.Width = Width; m_Camera.Height = Height; m_Camera.Set(new Vec3f(), Quatf.AxisAngleToQuatf(Vec3f.Z, -45), 10, false); //m_RefreshTimer.Elapsed += delegate { RefreshControl(); }; }
private void Synchronize(object obj, PropertyChangedEventArgs e) { if (SyncToCamera.Synchronizing) { return; } Synchronizing = true; Properties.DeferPropertyChanged = true; Position.Val = SyncToCamera.Position.Val; Forward.Val = SyncToCamera.Forward.Val; Up.Val = SyncToCamera.Up.Val; NaturalUp.Val = SyncToCamera.NaturalUp.Val; Target.Val = SyncToCamera.Target.Val; Ortho.Val = SyncToCamera.Ortho.Val; Near.Val = SyncToCamera.Near.Val; Far.Val = SyncToCamera.Far.Val; Width.Val = SyncToCamera.Width.Val; Height.Val = SyncToCamera.Height.Val; FOV.Val = SyncToCamera.FOV.Val; Scale.Val = SyncToCamera.Scale.Val; qrot = SyncToCamera.qrot; dist = SyncToCamera.dist; Properties.DeferPropertyChanged = false; Synchronizing = false; }
public void Set(Vec3f tar, Quatf rot, float dist, bool ortho) { Properties.DeferPropertyChanged = true; Set(tar, rot, dist); Ortho.Set(ortho); Properties.DeferPropertyChanged = false; }
/// <summary> /// Orbit Camera Position around Target, maintaining distance to Target and the Up vector /// </summary> /// <param name="theta_degrees"> /// A <see cref="System.Double"/> /// </param> public void OrbitTarget(double theta_degrees) { double theta = theta_degrees * Math.PI / 180.0; Quatf newrot = qrot * Quatf.AxisAngleToQuatf(NaturalUp.Val, (float)theta); Set(Target.Val, newrot, dist); }
public static Vec3f Quat_RotPt(Vec3f pt, Vec3f rotaxis, float theta) { Quatf qrot = new Quatf(FMath.Cos(theta * 0.5f), rotaxis * FMath.Sin(theta * 0.5f)); Quatf qpt = new Quatf(0.0f, pt); Quatf qconj = qrot.Conjugate(); return(Quat_PointMult(qrot * qpt, qconj)); }
public static Vec3f Quat_PointMult(Quatf q1, Quatf q2) { return(new Vec3f() { x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w }); }
public static CameraProperties SmoothBilateral(CameraProperties[] cams, int t0, float sigmatime, float sigmax) { int l = cams.Length; float wsumt = 0; float wsumr = 0; float wsumd = 0; float sigtimesq = sigmatime * sigmatime; float sigxsq = sigmax * sigmax; Vec3f tar0 = cams[t0].GetTarget(); Quatf rot0 = cams[t0].qrot; float dis0 = cams[t0].dist; Vec3f t = new Vec3f(); Quatf r = new Quatf(0, 0, 0, 0); float d = 0; // window to ~99% float siglg = Math.Max(sigmatime, sigmax); int s = Math.Max(0, (int)((float)t0 - siglg * 3.0f)); int e = Math.Min(l - 1, (int)((float)t0 + siglg * 3.0f)); for (int ti = s; ti <= e; ti++) { CameraProperties cam = cams[ti]; float dtim = (ti - t0); float dtar = (cam.GetTarget() - tar0).Length; float drot = (cam.qrot - rot0).Length; float ddis = (cam.dist - dis0); float wg = (float)Math.Exp(-dtim * dtim / sigtimesq); float wt = wg * (float)Math.Exp(-dtar * dtar / sigxsq); float wr = wg * (float)Math.Exp(-drot * drot / sigxsq); float wd = wg * (float)Math.Exp(-ddis * ddis / sigxsq); wsumt += wt; wsumr += wr; wsumd += wd; t += cam.Target.Val * wt; r += cam.qrot * wr; d += cam.dist * wd; } t *= 1.0f / wsumt; r *= 1.0f / wsumr; d *= 1.0f / wsumd; return(new CameraProperties(t, r, d, cams[t0].Ortho.Val)); }
//private Matrix DoubleArrayToMatrix(double[] m) //{ // return new Matrix(new double[,] { // { m[00], m[04], m[08], m[12] }, // { m[01], m[05], m[09], m[13] }, // { m[02], m[06], m[10], m[14] }, // { m[03], m[07], m[11], m[15] } // }); //} //public Matrix GetGLModelMatrix() //{ // double[] m = new double[16]; // GL.GetDouble(GetPName.ModelviewMatrix, m); // return DoubleArrayToMatrix(m); //} //public Matrix GetGLProjectionMatrix() //{ // double[] m = new double[16]; // GL.GetDouble(GetPName.ProjectionMatrix, m); // return DoubleArrayToMatrix(m); //} #endregion public void Set(Vec3f tar, Quatf rot, float dist) { rot = rot.Normalize(); this.qrot = rot; this.dist = dist; Vec3f _forward = rot.Rotate(Vec3f.Y); Vec3f _up = rot.Rotate(Vec3f.Z); Position = tar - _forward * dist; Scale = 50.0f / dist; Forward = Vec3f.Normalize(_forward); Target = tar; Up = _up; }
public static Quatf Slerp_NoInvert(Quatf q0, Quatf q1, float t) { float dot = q0 % q1; if (dot > -0.95f && dot < 0.95f) { float ang = FMath.Acos(dot); return((q0 * FMath.Sin(ang * (1.0f - t)) + q1 * FMath.Sin(ang * t)) / FMath.Sin(ang)); } else { return(Lerp(q0, q1, t)); } }
public void OrbitTargetUpDown(double theta_degrees, bool clampflips = false) { double theta = theta_degrees * Math.PI / 180.0; Quatf newrot = qrot * Quatf.AxisAngleToQuatf(GetRight(), (float)theta); //if (clampflips) //{ // Vec3f newup = Vec3f.Normalize(newrot.Rotate(Vec3f.Y)); // float dot = FMath.PI / 2.0f - Vec3f.AngleBetween(newup, NaturalUp); // if (dot < 0) // { // Vec3f newforward = Vec3f.Normalize(newrot.Rotate(-Vec3f.Z)); // Vec3f newright = newforward ^ newup; // float sign = -Math.Sign(newforward % NaturalUp); // newrot = newrot * Quatf.RotAxisAngleToQuatf(newright, dot * sign); // } //} Set(Target, newrot, dist); }
/*public void OrbitTargetUpDownNatural( double theta_degrees ) * { * float fn = Forward.Val % NaturalUp.Val; * if( ( theta_degrees < 0.0 && fn >= 0.95f ) || ( theta_degrees > 0.0 && fn <= -0.95f ) ) return; * * double theta = theta_degrees * Math.PI / 180.0; * Vec3f posreltar = Position.Val - Target.Val; * Vec3f right = Forward.Val ^ NaturalUp.Val; * float dist = (Target.Val - Position.Val).Length; * * Properties.DeferPropertyChanged = true; * bIgnoreChanges = true; * Position.Set( Target.Val + Vec3f.Normalize( VecExtensions.RotateVectorAroundAxis( posreltar, right, (float) theta ) ) * dist ); * Up.Set( VecExtensions.RotateVectorAroundAxis( Up.Val, right, (float) theta ) ); * bIgnoreChanges = false; * Target.Set( Target.Val ); * Properties.DeferPropertyChanged = false; * }*/ public void OrbitTargetUpDown(double theta_degrees, bool clampflips) { double theta = theta_degrees * Math.PI / 180.0; Quatf newrot = qrot * Quatf.AxisAngleToQuatf(GetRight(), (float)theta); if (clampflips) { // prevent camera from flipping over! Vec3f newup = Vec3f.Normalize(newrot.Rotate(Vec3f.Y)); float dot = FMath.PI / 2.0f - Vec3f.AngleBetween(newup, NaturalUp.Val); if (dot < 0) { Vec3f newforward = Vec3f.Normalize(newrot.Rotate(-Vec3f.Z)); Vec3f newright = newforward ^ newup; float sign = -Math.Sign(newforward % NaturalUp.Val); newrot = newrot * Quatf.RotAxisAngleToQuatf(newright, dot * sign); } } Set(Target.Val, newrot, dist); }
public static CameraProperties SmoothGaussian(CameraProperties[] cams, int t0, float sigma) { int l = cams.Length; float wsum = 0; float ss = sigma * sigma; Vec3f t = new Vec3f(); Quatf r = new Quatf(0, 0, 0, 0); float d = 0; t0 = Math.Max(0, Math.Min(cams.Length - 1, t0)); // window to ~99% int s = Math.Max(0, (int)((float)t0 - sigma * 3.0f)); int e = Math.Min(l - 1, (int)((float)t0 + sigma * 3.0f)); for (int ti = s; ti <= e; ti++) { CameraProperties cam = cams[ti]; float dtim = (ti - t0); float w = (float)Math.Exp(-dtim * dtim / ss); wsum += w; t += cam.Target.Val * w; r += cam.qrot * w; d += cam.dist * w; } t *= 1.0f / wsum; r *= 1.0f / wsum; d *= 1.0f / wsum; if (t0 < 0 || t0 >= l) { System.Console.WriteLine("t0 = " + t0 + ", l = " + l); } return(new CameraProperties(t, r, d, cams[t0].Ortho.Val)); }
public void Set(Vec3f tar, Quatf rot, float dist) { rot = rot.Normalize(); /*if( AlwaysUp ) * { * // prevent camera from rolling * Vec3f newright = Vec3f.Normalize( rot.Rotate( Vec3f.X ) ); * Vec3f newup = Vec3f.Normalize( rot.Rotate( Vec3f.Y ) ); * Vec3f newforward = Vec3f.Normalize( rot.Rotate( -Vec3f.Z ) ); * * if( Math.Abs( newforward % NaturalUp ) < 0.95f ) { * Vec3f goodright = Vec3f.Normalize( newforward ^ Vec3f.Z ); * float dot = Vec3f.AngleBetween( goodright, newright ); * System.Console.WriteLine( newup.ToStringFormatted() + " " + newright.ToStringFormatted() + " " + goodright.ToStringFormatted() ); * float sign = -Math.Sign( newright % NaturalUp ); * //rot = rot * Quatf.RotAxisAngleToQuatf( newforward, dot * sign ); * } * }*/ this.qrot = rot; this.dist = dist; Properties.DeferPropertyChanged = true; bIgnoreChanges = true; Vec3f fwd = rot.Rotate(-Vec3f.Z); Vec3f up = rot.Rotate(Vec3f.Y); Position.Set(tar - fwd * dist); Scale.Set(50.0f / dist); Target.Set(tar); Forward.Set(Vec3f.Normalize(fwd)); Up.Set(up); bIgnoreChanges = false; Properties.DeferPropertyChanged = false; }
public static Quatf Slerp(Quatf q0, Quatf q1, float t) { Quatf q2; float dot = q0 % q1; if (dot < 0.00f) { dot = -dot; q2 = q1 * -1.0f; } else { q2 = q1; } if (dot < 0.95f) { float ang = FMath.Acos(dot); return((q0 * FMath.Sin(ang * (1.0f - t)) + q2 * FMath.Sin(ang * t)) / FMath.Sin(ang)); } else { return(Lerp(q0, q2, t)); } }
public void Reset() { Set(new Vec3f(), Quatf.AxisAngleToQuatf(Vec3f.Z, -45) * Quatf.AxisAngleToQuatf(Vec3f.Y, -45), 10, false); }
public CameraProperties[] GetCameras() { ModelingHistory history = ModelingHistory.history; CameraProperties artist = null; CameraProperties bestview = null; Vec3f tar = new Vec3f(); Quatf rot = new Quatf(); float dist = 0.0f; float ortho = 0.0f; List <Vec3f> selverts = new List <Vec3f>(); Vec3f anorm = new Vec3f(); foreach (int isnapshot in snapshots) { SnapshotScene scene = history[isnapshot]; CameraProperties cam = scene.GetCamera(); tar += cam.GetTarget(); rot += cam.GetRotation(); dist += cam.GetDistance(); ortho += (cam.GetOrtho() ? 1.0f : 0.0f); foreach (SnapshotModel model in scene.GetSelectedModels()) { Vec3f[] verts = model.GetVerts(); Vec3f[] vnorms = model.GetVertNormals(); foreach (int ind in model.selinds) { selverts.Add(verts[ind]); anorm += vnorms[ind]; } } } int nsnapshots = snapshots.Count; if (nsnapshots == 0) { rot = new Quatf(0.5f, -0.5f, -0.5f, -0.5f); dist = 10.0f; System.Console.WriteLine("Cluster with no snapshots " + start + ":" + end); } else { tar /= (float)nsnapshots; rot /= (float)nsnapshots; dist /= (float)nsnapshots; ortho /= (float)nsnapshots; } artist = new CameraProperties(tar, rot, dist, (ortho >= 0.5f)) { Name = "Artist" }; bestview = artist; return(new CameraProperties[] { artist, bestview }); }
public CameraProperties(Vec3f tar, Quatf rot, float dist, bool ortho) : this() { Set(tar, rot, dist, ortho); }
public Quatf(Quatf q) { x = q.x; y = q.y; z = q.z; w = q.w; }
public static Quatf Lerp(Quatf q0, Quatf q1, float t) { return((q0 * (1.0f - t) + q1 * t).Normalize()); }
public SnapshotScene(string sPLYFilename, int timeindex, string command, string opts, SnapshotScene prev, bool nochange, bool cmdobjlist) { this.file = MiscFileIO.GetFileNameOnly(sPLYFilename); this.timeindex = timeindex; this.command = command; this.opts = opts; this.prevscene = prev; cselected = 0; cedited = 0; string[] objnames; bool[] objvisibles; bool[] objselecteds; bool[] objactives; bool[] objedits; string[] objplyfilenames; using (Stream s = new FileStream(sPLYFilename, FileMode.Open)) { string plyline = FileIOFunctions.ReadTextString(s); if (plyline != "ply") { throw new ArgumentException("SnapshotScene: Specified file is not .ply file"); } ncameras = 0; nmodels = 0; bool header = true; while (header) { string cmd = FileIOFunctions.ReadTextString(s); switch (cmd) { case "format": case "property": while (s.ReadByte() != 10) { ; // ignore the rest of the line } break; case "comment": string str = FileIOFunctions.ReadTextLine(s); if (str.StartsWith("Created")) { switch (str.Split(new char[] { ' ' })[2]) { case "Blender": ApplicationType = ApplicationTypes.BLENDER; break; } } break; case "element": string variable = FileIOFunctions.ReadTextString(s); int val = FileIOFunctions.ReadTextInteger(s); switch (variable) { case "views": ncameras = val; break; case "objects": nmodels = val; break; default: throw new Exception("SnapshotScene: Unhandled element type " + variable); } break; case "end_header": header = false; break; default: throw new Exception("SnapshotScene: Unhandled command type " + cmd); } } if (ApplicationType == ApplicationTypes.UNKNOWN) { throw new Exception("SnapshotScene: PLY was created by an unknown application"); } cameras = new CameraProperties[ncameras]; for (int i = 0; i < ncameras; i++) { // read viewing info Vec3f loc = new Vec3f(FileIOFunctions.ReadTextFloat(s), FileIOFunctions.ReadTextFloat(s), FileIOFunctions.ReadTextFloat(s)); float w = FileIOFunctions.ReadTextFloat(s); float x = FileIOFunctions.ReadTextFloat(s); float y = FileIOFunctions.ReadTextFloat(s); float z = FileIOFunctions.ReadTextFloat(s); Quatf qua = (new Quatf(w, x, y, z)).Normalize(); float dis = FileIOFunctions.ReadTextFloat(s); String per = FileIOFunctions.ReadTextString(s); cameras[i] = new CameraProperties(loc, qua, dis, (per == "ORTHO")); } int istart = 0, iend = 0, iinc = 0; switch (ApplicationType) { case ApplicationTypes.BLENDER: // blender writes list of objects "backwards"; new objects are at beginning of list! istart = nmodels - 1; iend = 0; iinc = -1; break; default: throw new Exception("SnapshotScene: Unimplemented ApplicationType"); } objnames = new string[nmodels]; objvisibles = new bool[nmodels]; objselecteds = new bool[nmodels]; objactives = new bool[nmodels]; objedits = new bool[nmodels]; objplyfilenames = new string[nmodels]; for (int i = istart; i != iend + iinc; i += iinc) { objnames[i] = FileIOFunctions.ReadTextQuotedString(s); objvisibles[i] = (FileIOFunctions.ReadTextInteger(s) == 1); objselecteds[i] = (FileIOFunctions.ReadTextInteger(s) == 1); objactives[i] = (FileIOFunctions.ReadTextInteger(s) == 1); objedits[i] = (FileIOFunctions.ReadTextInteger(s) == 1); objplyfilenames[i] = FileIOFunctions.ReadTextString(s); if (objselecteds[i]) { cselected++; } if (objedits[i]) { cedited++; } } } if (cedited > 1) { throw new Exception("more than one object being edited"); } bool loadall = (prev == null || cmdobjlist); // need to load every object? models = new SnapshotModel[nmodels]; modelscached = new SnapshotModel[nmodels]; SnapshotModel[] pmodels = null; if (prev != null) { pmodels = prev.Models; } for (int i = 0; i < nmodels; i++) { bool prevsel = !cmdobjlist && (pmodels != null && pmodels[i] != null && pmodels[i].objselected); if (loadall || (objselecteds[i] && !nochange) || objselecteds[i] != prevsel || pmodels == null || pmodels[i] == null) { models[i] = new SnapshotModel(objplyfilenames[i]); models[i].objind = i; models[i].objname = objnames[i]; models[i].objvisible = objvisibles[i]; models[i].objselected = objselecteds[i]; models[i].objactive = objactives[i]; models[i].objedit = objedits[i]; modelscached[i] = models[i]; } else { models[i] = null; modelscached[i] = pmodels[i]; } } }
public void Set(Vec3f tar, Quatf rot, float dist, bool ortho) { Set(tar, rot, dist); Ortho = ortho; }
public static CameraProperties SmoothBinary(CameraProperties[] cams, int t0, float epsilon, bool fromt0, float wtar, float wrot, float wdis) { int total = cams.Length; int left = t0 - 1; bool lcdone = (left < 0); Vec3f lctar = cams[t0].GetTarget(); Quatf lcrot = cams[t0].GetRotation(); float lcdis = cams[t0].GetDistance(); float leftdiff = -1; int right = t0 + 1; bool rcdone = (right > total - 1); Vec3f rctar = cams[t0].GetTarget(); Quatf rcrot = cams[t0].GetRotation(); float rcdis = cams[t0].GetDistance(); float rightdiff = -1; Vec3f avgtar = cams[t0].GetTarget(); Quatf avgrot = cams[t0].GetRotation(); float avgdis = cams[t0].GetDistance(); float maxdis = cams[t0].GetDistance(); float avgortho = (cams[t0].GetOrtho() ? 1.0f : 0.0f); int count = 1; while (!lcdone || !rcdone) { if (!lcdone) { Vec3f ltar = cams[left].GetTarget(); Quatf lrot = cams[left].GetRotation(); float ldis = cams[left].GetDistance(); leftdiff = (ltar - lctar).Length * wtar + (lrot - lcrot).Length * wrot + Math.Abs(ldis - lcdis) * wdis; if (leftdiff < epsilon) { avgtar += ltar; avgrot += lrot; avgdis += ldis; maxdis = Math.Max(maxdis, ldis); avgortho += (cams[left].GetOrtho() ? 1.0f : 0.0f); count++; if (!fromt0) { lctar = ltar; lcrot = lrot; lcdis = ldis; } left--; lcdone = (left < 0); } else { lcdone = true; } } if (!rcdone) { Vec3f rtar = cams[right].GetTarget(); Quatf rrot = cams[right].GetRotation(); float rdis = cams[right].GetDistance(); rightdiff = (rtar - rctar).Length * wtar + (rrot - rcrot).Length * wrot + Math.Abs(rdis - rcdis) * wdis; if (rightdiff < epsilon) { avgtar += rtar; avgrot += rrot; avgdis += rdis; maxdis = Math.Max(maxdis, rdis); avgortho += (cams[right].GetOrtho() ? 1.0f : 0.0f); count++; if (!fromt0) { rctar = rtar; rcrot = rrot; rcdis = rdis; } right++; rcdone = (right > total - 1); } else { rcdone = true; } } } avgtar /= (float)count; avgrot /= (float)count; avgdis /= (float)count; avgortho /= (float)count; avgdis = maxdis; return(new CameraProperties(avgtar, avgrot, avgdis, (avgortho >= 0.5f))); }