internal Bone(string name, int parent, ImmutableArray<int> boneControllers, Vector3f position, Quaternionf quaternion, Vector3f rotation, Vector3f positionScale, Vector3f rotationScale, Matrix4x4f poseToBone, Quaternionf alignment, int flags, int procType, int procIndex, int physicsBone, int surfacePropIdx, int contents) { Name = name; Parent = parent; BoneControllers = boneControllers; Position = position; Quaternion = quaternion; Rotation = rotation; PositionScale = positionScale; RotationScale = rotationScale; PoseToBone = poseToBone; Alignment = alignment; Flags = flags; ProcType = procType; ProcIndex = procIndex; PhysicsBone = physicsBone; SurfacePropIdx = surfacePropIdx; Contents = contents; }
public virtual void SetRotation(Quaternionf rotation) { camera.transform.rotation = rotation; }
static string edit_quaternion(Quaternionf q) { return("( " + q.w + ", " + q.x + ", " + q.y + ", " + q.z + " )"); }
static void test_func_call() { test_name("func_call"); // TVector Vec3f v31 = new Vec3f(1.0f, 2.0f, 3.0f); put("Vec3f: square ", "14.0", v31.square()); put("Vec3f: norm ", "3.7416574", v31.norm()); Vec3f v3u = v31; v3u.unitize(); Vec3f v3r = new Vec3f(0.2672612f, 0.5345225f, 0.8017837f); put2("Vec3f: unitize", edit_vector(v3r), edit_vector(v3u)); // TQuaternion System.Console.WriteLine(""); float pi = 3.1415927f; float rad90 = pi / 2; float rad45 = pi / 4; float cos45 = 0.7071069f; float sqrt3 = 1.7320508f; float sqrt3div3 = sqrt3 / 3; Quaternionf q1 = new Quaternionf(cos45, sqrt3div3, sqrt3div3, sqrt3div3); Quaternionf q2 = new Quaternionf(q1.W(), q1.X(), q1.Y(), q1.Z()); Vec3f qv1 = new Vec3f(sqrt3div3, sqrt3div3, sqrt3div3); put2("Quaternionf: W(),X(),Y(),Z()", edit_quaternion(q1), edit_quaternion(q2)); put2("Quaternionf: V", edit_vector(qv1), edit_vector(q1.V())); put2("Quaternionf: Axis", edit_vector(qv1), edit_vector(q1.Axis())); put("Quaternionf: Theta", rad90.ToString(), q1.Theta()); System.Console.WriteLine(""); float half = pi / (2 * sqrt3); Vec3f qv2 = new Vec3f(half, half, half); put2("Quaternionf: RotationHalf", edit_vector(qv2), edit_vector(q1.RotationHalf())); put2("Quaternionf: Rotation ", edit_vector(qv2), edit_vector(q1.Rotation())); float angle = rad90; float d = sqrt3; float s = (float)Math.Sin(angle / 2) / d; Quaternionf qr = new Quaternionf((float)Math.Cos(angle / 2), s, s, s); Quaternionf q3 = Quaternionf.Rot(angle, new Vec3f(1f, 1f, 1f)); put2("Quaternionf: Rot", edit_quaternion(qr), edit_quaternion(q3)); float c1 = (float)Math.Cos(angle / 2); float s1 = (float)Math.Sin(angle / 2); Quaternionf qs = new Quaternionf(c1, s1, 0f, 0f); Quaternionf q4 = Quaternionf.Rot(angle, (sbyte)'x'); put2("Quaternionf: Rot", edit_quaternion(qs), edit_quaternion(q4)); Vec3f qv3 = new Vec3f(1f, 1f, 1f); float c2 = (float)Math.Cos(sqrt3 / 2); float s2 = (float)Math.Sin(sqrt3 / 2); Vec3f qv4 = (s2 / sqrt3) * qv3; Quaternionf qt = new Quaternionf(c2, qv4[0], qv4[1], qv4[2]); Quaternionf q5 = Quaternionf.Rot(qv3); put2("Quaternionf: Rot", edit_quaternion(qt), edit_quaternion(q5)); Quaternionf qc1 = new Quaternionf(cos45, sqrt3div3, sqrt3div3, sqrt3div3); Quaternionf qc2 = new Quaternionf(cos45, sqrt3div3, sqrt3div3, sqrt3div3); Quaternionf qc = new Quaternionf(cos45, -sqrt3div3, -sqrt3div3, -sqrt3div3); qc1.Conjugate(); put2("Quaternionf: Conjugate", edit_quaternion(qc), edit_quaternion(qc1)); put2("Quaternionf: Conjugated", edit_quaternion(qc), edit_quaternion(qc2.Conjugated())); float qf1 = (float)(cos45 * cos45 + 3 * sqrt3div3 * sqrt3div3); Quaternionf qe = qc2.Conjugated() / qf1; put2("Quaternionf: Inv", edit_quaternion(qe), edit_quaternion(qc2.Inv())); // TPose System.Console.WriteLine(""); Posef p1 = new Posef(cos45, sqrt3, sqrt3, sqrt3, 1f, 2f, 3f); Posef p2 = new Posef(p1.W(), p1.X(), p1.Y(), p1.Z(), p1.Px(), p1.Py(), p1.Pz()); Vec3f pv31 = new Vec3f(1f, 2f, 3f); Quaternionf pq1 = new Quaternionf(cos45, sqrt3, sqrt3, sqrt3); Quaternionf pq2 = new Quaternionf(); Vec3f pv32 = new Vec3f(); Posef pp1 = new Posef(pq2.w, pq2.x, pq2.y, pq2.z, pv32.x, pv32.y, pv32.z); Posef pp2 = new Posef(pq2.w, pq2.x, pq2.y, pq2.z, 1f, 2f, 3f); put2("Posef: W(),X(),Y(),Z(),Px(),Py(),Pz()", edit_pose(p1), edit_pose(p2)); put2("Posef: Pos()", edit_vector(pv31), edit_vector(p1.Pos())); put2("Posef: Ori()", edit_quaternion(pq1), edit_quaternion(p1.Ori())); put2("Posef: Unit ", edit_pose(pp1), edit_pose(Posef.Unit())); put2("Posef: Trn ", edit_pose(pp2), edit_pose(Posef.Trn(1f, 2f, 3f))); put2("Posef: Trn ", edit_pose(pp2), edit_pose(Posef.Trn(pv31))); }
private static void GenerateEngineStruct(TypeTreeContext context, SerializableType origin, string name) { switch (origin.Name) { case SerializableType.Vector2Name: Vector2f.GenerateTypeTree(context, name); break; case SerializableType.Vector2IntName: Vector2i.GenerateTypeTree(context, name); break; case SerializableType.Vector3Name: Vector3f.GenerateTypeTree(context, name); break; case SerializableType.Vector3IntName: Vector3i.GenerateTypeTree(context, name); break; case SerializableType.Vector4Name: Vector4f.GenerateTypeTree(context, name); break; case SerializableType.RectName: Rectf.GenerateTypeTree(context, name); break; case SerializableType.BoundsName: AABB.GenerateTypeTree(context, name); break; case SerializableType.BoundsIntName: AABBi.GenerateTypeTree(context, name); break; case SerializableType.QuaternionName: Quaternionf.GenerateTypeTree(context, name); break; case SerializableType.Matrix4x4Name: Matrix4x4f.GenerateTypeTree(context, name); break; case SerializableType.ColorName: ColorRGBAf.GenerateTypeTree(context, name); break; case SerializableType.Color32Name: ColorRGBA32.GenerateTypeTree(context, name); break; case SerializableType.LayerMaskName: LayerMask.GenerateTypeTree(context, name); break; case SerializableType.AnimationCurveName: AnimationCurveTpl <Float> .GenerateTypeTree(context, name, Float.GenerateTypeTree); break; case SerializableType.GradientName: Gradient.GenerateTypeTree(context, name); break; case SerializableType.RectOffsetName: RectOffset.GenerateTypeTree(context, name); break; case SerializableType.GUIStyleName: GUIStyle.GenerateTypeTree(context, name); break; case SerializableType.PropertyNameName: PropertyName.GenerateTypeTree(context, name); break; default: throw new Exception($"Unknown engine struct {origin.Name}"); } }
private void AddTransformCurve(float time, TransformType transType, IReadOnlyList <float> curveValues, IReadOnlyList <float> inSlopeValues, IReadOnlyList <float> outSlopeValues, int offset, string path) { switch (transType) { case TransformType.Translation: { Vector3Curve curve = new Vector3Curve(path); if (!m_translations.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > transCurve)) { transCurve = new List <KeyframeTpl <Vector3f> >(); m_translations.Add(curve, transCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, Vector3f.DefaultWeight); transCurve.Add(transKey); } break; case TransformType.Rotation: { QuaternionCurve curve = new QuaternionCurve(path); if (!m_rotations.TryGetValue(curve, out List <KeyframeTpl <Quaternionf> > rotCurve)) { rotCurve = new List <KeyframeTpl <Quaternionf> >(); m_rotations.Add(curve, rotCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float w = curveValues[offset + 3]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float inW = inSlopeValues[3]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; float outW = outSlopeValues[3]; Quaternionf value = new Quaternionf(x, y, z, w); Quaternionf inSlope = new Quaternionf(inX, inY, inZ, inW); Quaternionf outSlope = new Quaternionf(outX, outY, outZ, outW); KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, value, inSlope, outSlope, Quaternionf.DefaultWeight); rotCurve.Add(rotKey); } break; case TransformType.Scaling: { Vector3Curve curve = new Vector3Curve(path); if (!m_scales.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > scaleCurve)) { scaleCurve = new List <KeyframeTpl <Vector3f> >(); m_scales.Add(curve, scaleCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, Vector3f.DefaultWeight); scaleCurve.Add(scaleKey); } break; case TransformType.EulerRotation: { Vector3Curve curve = new Vector3Curve(path); if (!m_eulers.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > eulerCurve)) { eulerCurve = new List <KeyframeTpl <Vector3f> >(); m_eulers.Add(curve, eulerCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, Vector3f.DefaultWeight); eulerCurve.Add(eulerKey); } break; default: throw new NotImplementedException(transType.ToString()); } }
public override void Generate() { int nRings = Curve.Length; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false) { nCapVertices = 0; } vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nSpanTris = (nRings - 1) * (2 * Slices); int nCapTris = (Capped) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); float fDelta = (float)((Math.PI * 2.0) / Slices); Frame3f f = Axis; // generate tube for (int ri = 0; ri < nRings; ++ri) { Vector3D v_along = Curve[ri]; Vector3F v_frame = f.ToFrameP((Vector3F)v_along); float uv_along = (float)ri / (float)(nRings - 1); // generate vertices int nStartR = ri * nRingSize; for (int j = 0; j < nRingSize; ++j) { float angle = (float)j * fDelta; // [TODO] this is not efficient...use Matrix3f? Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame; Vector3D v_new = f.FromFrameP(v_rot); int k = nStartR + j; vertices[k] = v_new; float uv_around = (float)j / (float)(nRingSize); uv[k] = new Vector2F(uv_along, uv_around); // [TODO] proper normal Vector3F n = (Vector3F)(v_new - f.Origin).Normalized; normals[k] = n; } } // generate triangles int ti = 0; for (int ri = 0; ri < nRings - 1; ++ri) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped) { // find avg start loop size Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero; for (int k = 0; k < Slices; ++k) { vAvgStart += vertices[k]; vAvgEnd += vertices[(nRings - 1) * nRingSize + k]; } vAvgStart /= (double)Slices; vAvgEnd /= (double)Slices; Frame3f fStart = f; fStart.Origin = (Vector3F)vAvgStart; Frame3f fEnd = f; fEnd.Origin = (Vector3F)vAvgEnd; // add endcap verts int nBottomC = nRings * nRingSize; vertices[nBottomC] = fStart.Origin; uv[nBottomC] = new Vector2F(0.5f, 0.5f); normals[nBottomC] = -fStart.Z; startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = fEnd.Origin; uv[nTopC] = new Vector2F(0.5f, 0.5f); normals[nTopC] = fEnd.Z; endCapCenterIndex = nTopC; if (NoSharedVertices) { // duplicate first loop and make a fan w/ bottom-center int nExistingB = 0; int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { vertices[nStartB + k] = vertices[nExistingB + k]; //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = normals[nBottomC]; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); // duplicate second loop and make fan int nExistingT = nRingSize * (nRings - 1); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { vertices[nStartT + k] = vertices[nExistingT + k]; //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartT + k] = normals[nTopC]; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti); } } }
public void UpdateTracking(Cockpit cockpit, fCamera camera) { fGameObject cockpitGO = cockpit.RootGameObject; if (!bInitialized) { currentFrame = cockpit.GetLevelViewFrame(CoordSpace.WorldCoords); currentFrame.ConstrainedAlignAxis(2, Vector3f.AxisZ, Vector3f.AxisY); bInitialized = true; } Vector3f vCamFW = camera.Forward(); vCamFW[1] = 0; vCamFW.Normalize(); // I don't think this is strictly necessary but // better to be safe for now... Vector3f vCamPos = camera.GetPosition(); //if (tracking_debug == null) // tracking_debug = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.green), false); //tracking_debug.transform.position = vCamPos + 15.0f * vCamFW; //if (tracking_avg == null) { // tracking_avg = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.blue), false); // tracking_avg.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f); //} //tracking_avg.transform.position = vCamPos + 10.0f * vSlowViewDirTrack; //tracking_debug.SetVisible(false); //tracking_avg.SetVisible(false); if (vSlowViewDirTrack == Vector3f.Zero) { vSlowViewDirTrack = vCamFW; } float slowTrackSpeed = 0.05f; vSlowViewDirTrack = VRUtil.AngleLerp(vSlowViewDirTrack, vCamFW, slowTrackSpeed); // head position tracking if (IsLocked == false) { cockpitGO.SetPosition(vCamPos); } //Vector3 vDelta = (camera.transform.position - RootGameObject.transform.position); //if (vDelta.magnitude > 0.2f) // RootGameObject.transform.position = camera.transform.position; ////else if ( vDelta.magnitude > 0.05f) //else // RootGameObject.transform.position = // (1.0f - TrackingSpeed) * RootGameObject.transform.position + // (TrackingSpeed) * camera.transform.position; float RotationSpeed = 200.0f; float WarmupTrackingAngleThresh = 55.0f; float ImmediateTrackingAngleThresh = 65.0f; float StopTrackingAngleThresh = 5.0f; float TrackingWarmupDelay = 2.0f; float TrackingCooldownDelay = 0.75f; //Vector3 vCockpitFW = cockpitGO.transform.forward; Vector3f vCockpitFW = currentFrame.Z; float fSlowHDeviation = VRUtil.PlaneAngle(vCockpitFW, vSlowViewDirTrack); float fActualViewDeviation = VRUtil.PlaneAngle(vCockpitFW, vCamFW); bool bDoTrack = false; if (eState == TrackingState.NotTracking) { //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.green); if (fSlowHDeviation > WarmupTrackingAngleThresh) { set_tracking_state(TrackingState.TrackingWarmup); stateChangeStartTime = FPlatform.RealTime(); } } else if (eState == TrackingState.TrackingWarmup) { //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.yellow); if (fSlowHDeviation > ImmediateTrackingAngleThresh) { set_tracking_state(TrackingState.Tracking); } else if (fSlowHDeviation > WarmupTrackingAngleThresh) { if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingWarmupDelay) { set_tracking_state(TrackingState.Tracking); } } else { set_tracking_state(TrackingState.NotTracking); } } else if (eState == TrackingState.Tracking) { bDoTrack = true; //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.red); if (fActualViewDeviation < StopTrackingAngleThresh) { set_tracking_state(TrackingState.TrackingCooldown); stateChangeStartTime = FPlatform.RealTime(); } } else if (eState == TrackingState.TrackingCooldown) { bDoTrack = true; //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.gray); if (fActualViewDeviation < StopTrackingAngleThresh) { if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingCooldownDelay) { set_tracking_state(TrackingState.NotTracking); bDoTrack = false; } } else { set_tracking_state(TrackingState.Tracking); } } if (IsLocked) { bDoTrack = false; set_tracking_state(TrackingState.NotTracking); } if (bDoTrack) { float dt = (float)(FPlatform.RealTime() - animation_last_time); float fDelta = RotationSpeed * dt; Vector3f vCurrent = new Vector3f(vCockpitFW[0], 0, vCockpitFW[2]).Normalized; Vector3f vTarget = new Vector3f(vSlowViewDirTrack[0], 0, vSlowViewDirTrack[2]).Normalized; //Vector3 vTarget = new Vector3(vCamFW[0], 0, vCamFW[2]).normalized; Vector3f c = Vector3f.Cross(vCurrent, vTarget); float a = Vector3f.AngleD(vCurrent, vTarget); float fSign = (c[1] < 0) ? -1.0f : 1.0f; float fRotAngle = Math.Min(a, fDelta) * fSign; currentFrame.Rotate(Quaternionf.AxisAngleD(Vector3f.AxisY, fRotAngle)); } cockpitGO.SetRotation(currentFrame.Rotation); animation_last_time = FPlatform.RealTime(); if (indicator == null) { indicator = new CockpitTrackingWidget(); indicator.Create(this, cockpit); cockpit.AddUIElement(indicator, false); } indicator.EnableIndicator = show_indicator; }
override public void BeginTransformation() { base.BeginTransformation(); objectFrame = target.GetLocalFrame(CoordSpace.ObjectCoords); curRotation = Quaternionf.Identity; }
private void AddComplexCurve(float time, BindingType bindType, IReadOnlyList <float> curveValues, int offset, string path) { switch (bindType) { case BindingType.Translation: { float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; if (!m_translations.TryGetValue(path, out Vector3Curve transCurve)) { transCurve = new Vector3Curve(path); } Vector3f trans = new Vector3f(x, y, z); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, trans, defWeight); transCurve.Curve.Curve.Add(transKey); m_translations[path] = transCurve; } break; case BindingType.Rotation: { float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float w = curveValues[offset + 3]; if (!m_rotations.TryGetValue(path, out QuaternionCurve rotCurve)) { rotCurve = new QuaternionCurve(path); } Quaternionf rot = new Quaternionf(x, y, z, w); Quaternionf defWeight = new Quaternionf(1.0f / 3.0f); KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, rot, defWeight); rotCurve.Curve.Curve.Add(rotKey); m_rotations[path] = rotCurve; } break; case BindingType.Scaling: { float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; if (!m_scales.TryGetValue(path, out Vector3Curve scaleCurve)) { scaleCurve = new Vector3Curve(path); } Vector3f scale = new Vector3f(x, y, z); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, scale, defWeight); scaleCurve.Curve.Curve.Add(scaleKey); m_scales[path] = scaleCurve; } break; case BindingType.EulerRotation: { float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; if (!m_eulers.TryGetValue(path, out Vector3Curve eulerCurve)) { eulerCurve = new Vector3Curve(path); } Vector3f euler = new Vector3f(x, y, z); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, euler, defWeight); eulerCurve.Curve.Curve.Add(eulerKey); m_eulers[path] = eulerCurve; } break; case BindingType.Floats: { float value = curveValues[offset]; if (!m_floats.TryGetValue(path, out FloatCurve floatCurve)) { floatCurve = new FloatCurve(path); } Float @float = new Float(value); Float defWeight = new Float(1.0f / 3.0f); KeyframeTpl <Float> floatKey = new KeyframeTpl <Float>(time, @float, defWeight); floatCurve.Curve.Curve.Add(floatKey); m_floats[path] = floatCurve; } break; default: throw new NotImplementedException(bindType.ToString()); } }
/// <summary> /// Solve for Translate/Rotate update, based on current From and To /// Note: From and To are invalidated, will need to be re-computed after calling this /// </summary> void update_transformation() { int N = From.Length; // normalize weights double wSum = 0; for (int i = 0; i < N; ++i) { wSum += Weights[i]; } double wSumInv = 1.0 / wSum; // compute means Vector3D MeanX = Vector3D.Zero; Vector3D MeanY = Vector3D.Zero; for (int i = 0; i < N; ++i) { MeanX += (Weights[i] * wSumInv) * From[i]; MeanY += (Weights[i] * wSumInv) * To[i]; } // subtract means for (int i = 0; i < N; ++i) { From[i] -= MeanX; To[i] -= MeanY; } // construct matrix 3x3 Matrix From*Transpose(To) // (vectors are columns) double[] M = new double[9]; for (int k = 0; k < 3; ++k) { int r = 3 * k; for (int i = 0; i < N; ++i) { double lhs = (Weights[i] * wSumInv) * From[i][k]; M[r + 0] += lhs * To[i].x; M[r + 1] += lhs * To[i].y; M[r + 2] += lhs * To[i].z; } } // compute SVD of M SingularValueDecomposition svd = new SingularValueDecomposition(3, 3, 100); uint ok = svd.Solve(M, -1); // sort in decreasing order, like Eigen Debug.Assert(ok < 9999999); double[] U = new double[9], V = new double[9], Tmp = new double[9];; svd.GetU(U); svd.GetV(V); // this is our rotation update double[] RotUpdate = new double[9]; // U*V gives us desired rotation double detU = NGonsCore.geometry3Sharp.math.MatrixUtil.Determinant3x3(U); double detV = NGonsCore.geometry3Sharp.math.MatrixUtil.Determinant3x3(V); if (detU * detV < 0) { double[] S = NGonsCore.geometry3Sharp.math.MatrixUtil.MakeDiagonal3x3(1, 1, -1); NGonsCore.geometry3Sharp.math.MatrixUtil.Multiply3x3(V, S, Tmp); NGonsCore.geometry3Sharp.math.MatrixUtil.Transpose3x3(U); NGonsCore.geometry3Sharp.math.MatrixUtil.Multiply3x3(Tmp, U, RotUpdate); } else { NGonsCore.geometry3Sharp.math.MatrixUtil.Transpose3x3(U); NGonsCore.geometry3Sharp.math.MatrixUtil.Multiply3x3(V, U, RotUpdate); } // convert matrix to quaternion Matrix3f RotUpdateM = new Matrix3f(RotUpdate); Quaternionf RotUpdateQ = new Quaternionf(RotUpdateM); // [TODO] is this right? We are solving for a translation and // rotation of the current From points, but when we fold these // into Translation & Rotation variables, we have essentially // changed the order of operations... // figure out translation update Vector3D TransUpdate = MeanY - RotUpdateQ * MeanX; Translation += TransUpdate; // and rotation Rotation = RotUpdateQ * Rotation; // above was ported from this code...still not supporting weights though. // need to figure out exactly what this code does (like, what does // transpose() do to a vector??) // /// Normalize weight vector //Eigen::VectorXd w_normalized = w/w.sum(); ///// De-mean //Eigen::Vector3d X_mean, Y_mean; //for(int i=0; i<3; ++i) { // X_mean(i) = (X.row(i).array()*w_normalized.transpose().array()).sum(); // Y_mean(i) = (Y.row(i).array()*w_normalized.transpose().array()).sum(); //Eigen::Matrix3d sigma = X * w_normalized.asDiagonal() * Y.transpose(); }
/// <summary> /// Converts an ovrQuatf to a SharpDX Quaternion. /// </summary> public static Quaternion ToQuaternion(Quaternionf ovrQuatf) { return(new Quaternion(ovrQuatf.X, ovrQuatf.Y, ovrQuatf.Z, ovrQuatf.W)); }
public Quaternionf[] Unpack() { int bitIndex = 0; int byteIndex = 0; Quaternionf[] buffer = new Quaternionf[NumItems]; for (int i = 0; i < NumItems; i++) { int flags = 0; int bitOffset = 0; while (bitOffset < 3) { flags |= Data[byteIndex] >> bitIndex << bitOffset; int read = Math.Min(3 - bitOffset, 8 - bitIndex); bitIndex += read; bitOffset += read; if (bitIndex == 8) { byteIndex++; bitIndex = 0; } } flags &= 7; float sum = 0; Quaternionf quaternion = new Quaternionf(); for (int j = 0; j < 4; j++) { if ((flags & 3) != j) { int bitSize = ((flags & 3) + 1) % 4 == j ? 9 : 10; float halfMaxValue = 0.5f * ((1 << bitSize) - 1); int value = 0; bitOffset = 0; while (bitOffset < bitSize) { value |= Data[byteIndex] >> bitIndex << bitOffset; int num = Math.Min(bitSize - bitOffset, 8 - bitIndex); bitIndex += num; bitOffset += num; if (bitIndex == 8) { byteIndex++; bitIndex = 0; } } value &= (1 << bitSize) - 1; // final value's range is [-1.0f : 1.0f] quaternion[j] = value / halfMaxValue - 1.0f; sum += quaternion[j] * quaternion[j]; } } int lastComponent = flags & 3; quaternion[lastComponent] = (float)Math.Sqrt(1.0f - sum); if ((flags & 4) != 0) { quaternion[lastComponent] = -quaternion[lastComponent]; } buffer[i] = quaternion; } return(buffer); }
public static void SwapUpDirection(FScene scene, List <PrintMeshSO> objects) { AxisAlignedBox3f sceneBounds = AxisAlignedBox3f.Empty; Vector3f sharedOrigin = Vector3f.Zero; foreach (var meshSO in objects) { sharedOrigin += meshSO.GetLocalFrame(CoordSpace.SceneCoords).Origin; sceneBounds.Contain(meshSO.GetBoundingBox(CoordSpace.SceneCoords).ToAABB()); } sharedOrigin /= objects.Count; foreach (var so in objects) { Frame3f curF = so.GetLocalFrame(CoordSpace.SceneCoords); UpDirection from = so.UpDirection; UpDirection to = (from == UpDirection.YUp) ? UpDirection.ZUp : UpDirection.YUp; Quaternionf rotate = Quaternionf.AxisAngleD(Vector3f.AxisX, (to == UpDirection.YUp) ? -90 : 90); Frame3f newF = curF; newF.RotateAround(sharedOrigin, rotate); TransformSOChange upChange = new TransformSOChange(so, newF, CoordSpace.SceneCoords) { OnApplyF = (x) => { so.UpDirection = to; }, OnRevertF = (x) => { so.UpDirection = from; } }; scene.History.PushChange(upChange, false); } AxisAlignedBox3f newSceneBounds = AxisAlignedBox3f.Empty; foreach (var meshSO in objects) { newSceneBounds.Contain(meshSO.GetBoundingBox(CoordSpace.SceneCoords).ToAABB()); } Vector3f startBase = sceneBounds.Center; startBase.y = 0; Vector3f newBase = newSceneBounds.Center; newBase.y = newSceneBounds.Min.y; Vector3f df = startBase - newBase; foreach (var so in objects) { Frame3f curF = so.GetLocalFrame(CoordSpace.SceneCoords); Frame3f newF = curF.Translated(df); TransformSOChange centerChange = new TransformSOChange(so, newF, CoordSpace.SceneCoords); scene.History.PushChange(centerChange, false); } // reposition pivots at base of List <Frame3f> setF = new List <Frame3f>(); foreach (var so in objects) { Frame3f objF = so.GetLocalFrame(CoordSpace.ObjectCoords); Vector3f center = so.GetBoundingBox(CoordSpace.SceneCoords).Center; center.y = 0; Frame3f sceneF = new Frame3f(center); setF.Add(sceneF); } for (int k = 0; k < objects.Count; ++k) { RepositionPivotChangeOp change = new RepositionPivotChangeOp(setF[k], objects[k], CoordSpace.SceneCoords); scene.History.PushChange(change, false); } }
public static void test_basic_generators() { TrivialDiscGenerator disc_gen = new TrivialDiscGenerator(); WriteGeneratedMesh(disc_gen, "meshgen_Disc.obj"); TrivialRectGenerator rect_gen = new TrivialRectGenerator(); WriteGeneratedMesh(rect_gen, "meshgen_Rect.obj"); GriddedRectGenerator gridrect_gen = new GriddedRectGenerator(); WriteGeneratedMesh(gridrect_gen, "meshgen_GriddedRect.obj"); PuncturedDiscGenerator punc_disc_gen = new PuncturedDiscGenerator(); WriteGeneratedMesh(punc_disc_gen, "meshgen_PuncturedDisc.obj"); TrivialBox3Generator box_gen = new TrivialBox3Generator(); Frame3f f = Frame3f.Identity; f.Rotate(Quaternionf.AxisAngleD(Vector3f.AxisY, 45.0f)); f.Rotate(Quaternionf.AxisAngleD(Vector3f.AxisZ, 45.0f)); box_gen.Box = new Box3d(f.Origin, f.X, f.Y, f.Z, new Vector3d(3, 2, 1)); WriteGeneratedMesh(box_gen, "meshgen_TrivialBox_shared.obj"); box_gen.NoSharedVertices = true; WriteGeneratedMesh(box_gen, "meshgen_TrivialBox_noshared.obj"); RoundRectGenerator roundrect_gen = new RoundRectGenerator(); roundrect_gen.Width = 2; WriteGeneratedMesh(roundrect_gen, "meshgen_RoundRect.obj"); GridBox3Generator gridbox_gen = new GridBox3Generator(); WriteGeneratedMesh(gridbox_gen, "meshgen_GridBox_shared.obj"); gridbox_gen.NoSharedVertices = true; WriteGeneratedMesh(gridbox_gen, "meshgen_GridBox_noshared.obj"); Sphere3Generator_NormalizedCube normcube_gen = new Sphere3Generator_NormalizedCube(); WriteGeneratedMesh(normcube_gen, "meshgen_Sphere_NormalizedCube_shared.obj"); normcube_gen.NoSharedVertices = true; normcube_gen.Box = new Box3d(new Frame3f(Vector3f.One, Vector3f.One), Vector3d.One * 1.3); WriteGeneratedMesh(normcube_gen, "meshgen_Sphere_NormalizedCube_noshared.obj"); TubeGenerator tube_gen = new TubeGenerator() { Vertices = new List <Vector3d>() { Vector3d.Zero, Vector3d.AxisX, 2 * Vector3d.AxisX, 3 * Vector3d.AxisX }, Polygon = Polygon2d.MakeCircle(1, 16) }; WriteGeneratedMesh(tube_gen, "meshgen_TubeGenerator.obj"); tube_gen.Polygon.Translate(Vector2d.One); tube_gen.CapCenter = Vector2d.One; WriteGeneratedMesh(tube_gen, "meshgen_TubeGenerator_shifted.obj"); }
public void update(Frame3f handF, SnapSet snap) { curHandF = handF; // [RMS] this function updates the position of object based on hand frame // Not clear how this should work, there are lots of options... // [1] scaled relative motion of hand inherited by object (lags ray though) //Vector3 dt = startHandF.ToFrameP(handF.Origin); //dt *= 10.0f; //Frame3 fNew = new Frame3(startObjFW); //fNew.Origin += dt; // [2] object stays on ray, inherits a bit of xform // - resulting orientation is weird. works well for rotate in-place around ray, // but up/down/left/right tilts are impossible w/o moving object Frame3f fNew = handF.FromFrame(this.startObjRelF); if (RotationSpeed != 1.0f) { fNew.Rotation = Quaternionf.Slerp(startObjFW.Rotation, fNew.Rotation, RotationSpeed); } if (TranslationSpeed != 1.0f) { fNew.Origin = Vector3f.Lerp(startObjFW.Origin, fNew.Origin, TranslationSpeed); } // [3] object stays on ray but no rotation // - weird if you rotate left/right, because distance stays same but it // keeps pointing in same direction // - we have gizmo for this kind of translation. //Frame3 fNew = handF.FromFrame(this.startObjRelF); //fNew.Rotation = startObjFW.Rotation; // [4] object stays in place, rotate by hand rotation // - pretty hard to control, but would be good for approx orienting... // - definitely needs damping!! //Frame3 fNew = startObjFW; //Quaternion relative = handF.Rotation * Quaternion.Inverse(startHandF.Rotation); //fNew.Rotation = relative * fNew.Rotation; // apply stick rotation DOESN"T WORK //Quaternion stickY = Quaternion.AngleAxis(stickDelta[1], startHandF.X); //fNew.Rotation = fNew.Rotation * stickY; // shift in/out along hand-ray by Z fNew.Origin += 0.1f * stickDelta[1] * handF.Z * cockpit.Scene.GetSceneScale(); curHandTargetF = fNew; curUseTargetF = new Frame3f(curHandTargetF); if (snap != null) { if (snapSolver == null) { snapSolver = new DynamicSnapSolver(grabbedSO); } snapSolver.SnapOrientation = (cockpit.Context.TransformManager.ActiveFrameType == FrameType.LocalFrame); curUseTargetF = snapSolver.UpdateSnapW(curUseTargetF, snap); } // update so grabbedSO.SetLocalFrame(curUseTargetF, CoordSpace.WorldCoords); }
private void AddComplexCurve(float time, BindingType bindType, IReadOnlyList <float> curveValues, IReadOnlyList <float> inSlopeValues, IReadOnlyList <float> outSlopeValues, int offset, string path) { switch (bindType) { case BindingType.Translation: { if (!m_translations.TryGetValue(path, out List <KeyframeTpl <Vector3f> > transCurve)) { transCurve = new List <KeyframeTpl <Vector3f> >(); m_translations.Add(path, transCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, defWeight); transCurve.Add(transKey); m_translations[path] = transCurve; } break; case BindingType.Rotation: { if (!m_rotations.TryGetValue(path, out List <KeyframeTpl <Quaternionf> > rotCurve)) { rotCurve = new List <KeyframeTpl <Quaternionf> >(); m_rotations.Add(path, rotCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float w = curveValues[offset + 3]; float inX = 0; //inSlopeValues[0]; float inY = 0; //inSlopeValues[1]; float inZ = 0; //inSlopeValues[2]; float inW = 0; //inSlopeValues[3]; float outX = 0; //outSlopeValues[0]; float outY = 0; //outSlopeValues[1]; float outZ = 0; //outSlopeValues[2]; float outW = 0; //outSlopeValues[3]; Quaternionf value = new Quaternionf(x, y, z, w); Quaternionf inSlope = new Quaternionf(inX, inY, inZ, inW); Quaternionf outSlope = new Quaternionf(outX, outY, outZ, outW); Quaternionf defWeight = new Quaternionf(1.0f / 3.0f); KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, value, inSlope, outSlope, defWeight); rotCurve.Add(rotKey); m_rotations[path] = rotCurve; } break; case BindingType.Scaling: { if (!m_scales.TryGetValue(path, out List <KeyframeTpl <Vector3f> > scaleCurve)) { scaleCurve = new List <KeyframeTpl <Vector3f> >(); m_scales.Add(path, scaleCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, defWeight); scaleCurve.Add(scaleKey); m_scales[path] = scaleCurve; } break; case BindingType.EulerRotation: { if (!m_eulers.TryGetValue(path, out List <KeyframeTpl <Vector3f> > eulerCurve)) { eulerCurve = new List <KeyframeTpl <Vector3f> >(); m_eulers.Add(path, eulerCurve); } float x = curveValues[offset + 0]; float y = curveValues[offset + 1]; float z = curveValues[offset + 2]; float inX = inSlopeValues[0]; float inY = inSlopeValues[1]; float inZ = inSlopeValues[2]; float outX = outSlopeValues[0]; float outY = outSlopeValues[1]; float outZ = outSlopeValues[2]; Vector3f value = new Vector3f(x, y, z); Vector3f inSlope = new Vector3f(inX, inY, inZ); Vector3f outSlope = new Vector3f(outX, outY, outZ); Vector3f defWeight = new Vector3f(1.0f / 3.0f); KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, defWeight); eulerCurve.Add(eulerKey); m_eulers[path] = eulerCurve; } break; case BindingType.Floats: { if (!m_floats.TryGetValue(path, out List <KeyframeTpl <Float> > floatCurve)) { floatCurve = new List <KeyframeTpl <Float> >(); m_floats.Add(path, floatCurve); } float x = curveValues[offset]; float inX = inSlopeValues[0]; float outX = outSlopeValues[0]; Float value = new Float(x); Float inSlope = new Float(inX); Float outSlope = new Float(outX); Float defWeight = new Float(1.0f / 3.0f); KeyframeTpl <Float> floatKey = new KeyframeTpl <Float>(time, value, inSlope, outSlope, defWeight); floatCurve.Add(floatKey); m_floats[path] = floatCurve; } break; default: throw new NotImplementedException(bindType.ToString()); } }
/// <summary> /// This is the action we give to the trim-scan tool, to run on accept /// </summary> public static void CropScanFromSelection(DMeshSO so, MeshFaceSelection selection, object tool) { DMesh3 beforeMesh = new DMesh3(so.Mesh); DMesh3 mesh = so.Mesh; // [RMS] if we are using the two-point tool, then we can use the user input points to // try to figure out an up axis, by assuming the first point is on the base of the scan. Steps are: // 1) guess a midpoint. Currently centroid of upper-half of geodesic selection. // 2) construct up axis as (midpoint-basepoint). this axis to Y-up. Vector3f upAxisS = Vector3f.AxisY; TwoPointFaceSelectionTool ptool = tool as TwoPointFaceSelectionTool; if (ptool != null) { var cache = ptool.SelectionCache; Interval1d range = new Interval1d(cache.CurrentScalarThreshold / 2, cache.CurrentScalarThreshold); List <int> triangles = new List <int>(selection.Count); cache.FindTrianglesInScalarInterval(range, triangles); Vector3d c = MeshMeasurements.Centroid(triangles, mesh.GetTriCentroid); Vector3d cS = SceneTransforms.ObjectToSceneP(so, c); Vector3d basePosS = ptool.SourcePositionS.Origin; upAxisS = (Vector3f)(cS - basePosS).Normalized; } // crop scan and fill top hole List <int> borderTris = selection.FindBorderTris(); MeshEditor editor = new MeshEditor(mesh); editor.RemoveTriangles((tid) => { return(selection.IsSelected(tid) == false); }, true); if (OGActions.FillHoleInScan) { SmoothedHoleFill fill = new SmoothedHoleFill(mesh) { TargetEdgeLength = 2.5f, SmoothAlpha = 0.5f, BorderHintTris = borderTris, OffsetDirection = SceneTransforms.SceneToObjectN(so, upAxisS), OffsetDistance = (ptool != null) ? 25.0 : 0.0 }; fill.Apply(); } so.NotifyMeshEdited(); DMesh3 afterMesh = new DMesh3(so.Mesh); so.GetScene().History.PushChange(new ReplaceEntireMeshChange(so, beforeMesh, afterMesh), true); mesh = so.Mesh; // Now we auto-align the scan so it points upwards, and then // recenter pivot and shift to above ground plane if (ptool != null) { Vector3d basePosS = ptool.SourcePositionS.Origin; Quaternionf alignUp = Quaternionf.FromTo(upAxisS, Vector3f.AxisY); // rotate part so that axis points up Frame3f curF = so.GetLocalFrame(CoordSpace.SceneCoords); Frame3f newF = curF.Rotated(alignUp); TransformSOChange alignUpChange = new TransformSOChange(so, curF, newF, CoordSpace.SceneCoords); basePosS = newF.FromFrameP(curF.ToFrameP(basePosS)); // map to new frame so.GetScene().History.PushChange(alignUpChange, false); // recenter pivot at bbox center // [RMS] previously was using vertex centroid, but this is then affected by mesh density // (maybe tri centroid? but bbox makes more sense...and below we assume box center) Vector3d centerL = mesh.CachedBounds.Center; Vector3d centerO = newF.FromFrameP(centerL); Frame3f newPivotO = new Frame3f(centerO); so.GetScene().History.PushChange(new RepositionPivotChangeOp(newPivotO, so), false); // position above ground plane AxisAlignedBox3d bounds = so.Mesh.CachedBounds; float h = (float)bounds.Height; Vector3f o = newPivotO.Origin; Vector3f translateO = new Vector3f(-o.x, h * 0.5f - o.y + BaseHeightAboveGroundPlaneMM, -o.z); //Vector3f translateO = new Vector3f(0, h * 0.5f - o.y + BaseHeightAboveGroundPlaneMM, 0); newPivotO.Translate(translateO); so.GetScene().History.PushChange(new TransformSOChange(so, newPivotO, CoordSpace.ObjectCoords), false); // save base point in frame of scan basePosS += translateO; Vector3d basePosL = SceneTransforms.SceneToObjectP(so, basePosS); OG.Scan.UserBasePoint = basePosL; } so.GetScene().History.PushInteractionCheckpoint(); }
public virtual void SetLocalRotation(Quaternionf rotation) { go.transform.localRotation = rotation; }
// Use this for initialization public void Initialize(FContext controller) { this.controller = controller; // find main camera GameObject[] mainCameras = GameObject.FindGameObjectsWithTag("MainCamera"); if (mainCameras.Length == 0) { throw new MissingComponentException("CameraTracking.Initialize: could not find camera with tag MainCamera"); } var mainCameraObj = mainCameras[0]; if (mainCameras.Length > 1) { DebugUtil.Log(2, "CameraTracking.Initialize: there are multiple objects with tag MainCamera. Using the one named " + mainCameraObj.GetName()); } mainCamera = new fCamera(mainCameraObj.GetComponent <Camera> () as Camera); // on Vive the MainCamera will have some child cameras that are a problem, // so get rid of them if (gs.VRPlatform.CurrentVRDevice == gs.VRPlatform.Device.HTCVive) { List <GameObject> children = new List <GameObject>(mainCameraObj.Children()); foreach (var child in children) { mainCameraObj.RemoveChild(child); child.Destroy(); } } List <Camera> newCameras = new List <Camera>(); Vector3f mainPos = mainCamera.GetPosition(); Quaternionf mainRot = mainCamera.GetRotation(); // create camera for 3D widgets layer widgetCamera = new fCamera(Camera.Instantiate((Camera)mainCamera, mainPos, mainRot)); widgetCamera.SetName("WidgetCamera"); newCameras.Add(widgetCamera); // create camera for HUD layer hudCamera = new fCamera(Camera.Instantiate((Camera)mainCamera, mainPos, mainRot)); hudCamera.SetName("HUDCamera"); newCameras.Add(hudCamera); // create camera for UI uiCamera = new fCamera(Camera.Instantiate((Camera)mainCamera, mainPos, mainRot)); uiCamera.SetName("UICamera"); ((Camera)uiCamera).orthographic = true; ((Camera)uiCamera).orthographicSize = 0.5f; newCameras.Add(uiCamera); // create camera for cursor cursorCamera = new fCamera(Camera.Instantiate((Camera)mainCamera, mainPos, mainRot)); cursorCamera.SetName("CursorCamera"); newCameras.Add(cursorCamera); // configure these cameras // - must disable audio listener if it exists // - do depth clear so we can draw on top of other layers foreach (Camera cam in newCameras) { AudioListener listener = cam.GetComponent <AudioListener>(); if (listener != null) { listener.enabled = false; } cam.clearFlags = CameraClearFlags.Depth; cam.tag = "Untagged"; } // set up camera masks // this camera only renders 3DWidgetOverlay layer, and mainCam does not! int nWidgetLayer = FPlatform.WidgetOverlayLayer; int nHUDLayer = FPlatform.HUDLayer; int nUILayer = FPlatform.UILayer; int nCursorLayer = FPlatform.CursorLayer; ((Camera)widgetCamera).cullingMask = (1 << nWidgetLayer); ((Camera)hudCamera).cullingMask = (1 << nHUDLayer); ((Camera)uiCamera).cullingMask = (1 << nUILayer); ((Camera)cursorCamera).cullingMask = (1 << nCursorLayer); ((Camera)mainCamera).cullingMask &= ~(1 << nWidgetLayer); ((Camera)mainCamera).cullingMask &= ~(1 << nHUDLayer); ((Camera)mainCamera).cullingMask &= ~(1 << nUILayer); ((Camera)mainCamera).cullingMask &= ~(1 << nCursorLayer); // attach camera animation object to main camera CameraAnimator anim = mainCamera.AddComponent <CameraAnimator>(); anim.UseCamera = mainCamera; anim.UseScene = this.controller.Scene; // add target point to camera CameraTarget target = mainCamera.AddComponent <CameraTarget>(); target.TargetPoint = new Vector3f(0.0f, mainCamera.GetPosition().y, 0.0f); target.context = this.controller; // add camera manipulator to camera // TODO: this does not need to be a monobehavior... var manipulator = mainCamera.AddComponent <CameraManipulator>(); manipulator.Camera = mainCamera; // initialize FPlatform FPlatform.MainCamera = mainCamera; FPlatform.WidgetCamera = widgetCamera; FPlatform.HUDCamera = hudCamera; FPlatform.OrthoUICamera = uiCamera; FPlatform.CursorCamera = cursorCamera; }
static void test_operator() { test_name("operator"); // TVector Vec3f v3a = new Vec3f(0.1f, 0.2f, 0.3f); Vec3f v3b = new Vec3f(0.4f, 0.5f, 0.6f); Vec3f v3c = new Vec3f(0.1f, 0.2f, 0.3f); // v3c == v3a Vec3f v3d; put("vector unary -", "(-0.1, -0.2, -0.3)", -v3a); put("vector binary +", "( 0.5, 0.7, 0.9)", v3a + v3b); put("vector binary -", "(-0.3, -0.3, -0.3)", v3a - v3b); put("vector binary *", "( 0.2, 0.4, 0.6)", v3a * 2); put("vector binary *", "( 0.8, 1.0, 1.2)", 2 * v3b); put("vector binary /", "( 0.05, 0.10, 0.15)", v3a / 2); put("vector binary *", " 0.32", v3a * v3b); put("vector binary %", "(-0.03, 0.06, -0.03)", v3a % v3b); put("vector binary ^", "(-0.03, 0.06, -0.03)", v3a ^ v3b); v3d = v3a; v3d += v3b; put("vector binary +=", "( 0.5, 0.7, 0.9)", v3d); v3d = v3a; v3d -= v3b; put("vector binary -=", "(-0.3, -0.3, -0.3)", v3d); v3d = v3a; v3d *= 2; put("vector binary *=", "( 0.2, 0.4, 0.6)", v3d); v3d = v3a; v3d /= 2; put("vector binary /=", "(0.05, 0.10, 0.15)", v3d); put("vector binary ==", "True ", v3a == v3c); put("vector binary ==", "False", v3a == v3b); put("vector binary !=", "True ", v3a != v3b); put("vector binary !=", "False", v3a != v3c); // TMatrix Matrix3f m3a = new Matrix3f(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f); Matrix3f m3b = new Matrix3f(1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f); Matrix3f m3c = new Matrix3f(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f); // m3c == m3a Matrix3f m3d; Matrix3f m3r = new Matrix3f(-0.1f, -0.2f, -0.3f, -0.4f, -0.5f, -0.6f, -0.7f, -0.8f, -0.9f); Matrix3f m3s = new Matrix3f(1.2f, 1.4f, 1.6f, 1.8f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f); Matrix3f m3t = new Matrix3f(-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f); Matrix3f m3u = new Matrix3f(0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.4f, 1.6f, 1.8f); put2("matrix unary -", edit_matrix(m3r), edit_matrix(-m3a)); put2("matrix binary +", edit_matrix(m3s), edit_matrix(m3a + m3b)); put2("matrix binary -", edit_matrix(m3t), edit_matrix(m3a - m3b)); put2("matrix binary *", edit_matrix(m3u), edit_matrix(m3a * 2)); put2("matrix binary *", edit_matrix(m3u), edit_matrix(2 * m3a)); put2("matrix binary *", new Vec3d(0.14, 0.32, 0.50), (m3a * v3a)); put2("matrix binary *", new Vec3d(2.16, 2.31, 2.46), (v3b * m3b)); m3d = m3a; m3d += m3b; put2("matrix binary +=", edit_matrix(m3s), edit_matrix(m3d)); m3d = m3a; m3d -= m3b; put2("matrix binary +=", edit_matrix(m3t), edit_matrix(m3d)); m3d = m3a; m3d *= 2; put2("matrix binary +=", edit_matrix(m3u), edit_matrix(m3d)); // TQuaternion Quaternionf q1 = new Quaternionf(1.0f, 2.0f, 3.0f, 4.0f); Quaternionf q2 = new Quaternionf(5.0f, 6.0f, 7.0f, 8.0f); Vec3f qv1 = new Vec3f(1.0f, 2.0f, 3.0f); Matrix3f qm1 = new Matrix3f(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f); Quaternionf qr = new Quaternionf(-60.0f, 12.0f, 30.0f, 24.0f); Vec3f qvs = new Vec3f(54f, 60f, 78f); Matrix3f qmt = new Matrix3f(150f, 156f, 162f, 120f, 150f, 180, 150f, 192f, 234f); put2("quaternion binary *", edit_quaternion(qr), edit_quaternion(q1 * q2)); put2("quaternion binary *", edit_vector(qvs), edit_vector(q1 * qv1)); put2("quaternion binary *", edit_matrix(qmt), edit_matrix(q1 * qm1)); // TPose Posef pp1 = new Posef(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f); Posef pp2 = new Posef(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f); Vec3f pv1 = new Vec3f(1.0f, 2.0f, 3.0f); Posef pr1 = new Posef(-36.0f, 12.0f, 42.0f, 24.0f, -25.0f, 66.0f, 97.0f); put2("pose binary *", edit_pose(pr1), edit_pose(pp1 * pp2)); put2("pose binary *", "(59, 66, 85)", (pp1 * pv1)); // indexing System.Console.WriteLine(""); Vec3f v31 = new Vec3f(0.1f, 0.2f, 0.3f); Vec3f v32 = new Vec3f(1.0f, 1.0f, 1.0f); Vec3f v3e = v31 + v32; for (int i = 0; i < 3; i++) { v31[i] += v32[i]; } put("indexing []", edit_vector(v3e), edit_vector(v31)); Matrix3f m31 = new Matrix3f(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f); Matrix3f m32 = new Matrix3f(1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f); Matrix3f m3e = m31 + m32; put("indexing [] ref", "(0.1, 0.2, 0.3)", edit_vector(m31[0])); put(" ref", "(0.4, 0.5, 0.6)", edit_vector(m31[1])); put(" ref", "(0.7, 0.8, 0.9)", edit_vector(m31[2])); for (int i = 0; i < 3; i++) { m31[i] += v32; } for (int i = 1; i < 3; i++) { m31[i] += v32; } for (int i = 2; i < 3; i++) { m31[i] += v32; } put2("indexing [] set", edit_matrix(m3e), edit_matrix(m31)); }
ImmutableArray<Bone> LoadBones(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Bone[] bones = new Bone[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int parent = reader.ReadInt32(); ImmutableArray<int> boneControllers = new ImmutableArray<int>(new int[] { reader.ReadInt32(),reader.ReadInt32(),reader.ReadInt32(), reader.ReadInt32(),reader.ReadInt32(),reader.ReadInt32()}); Vector3f position = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Quaternionf quaternion = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotation = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f positionScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotationScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Matrix4x4f poseToBone = new Matrix4x4f( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0, 0, 0, 1); Quaternionf alignment = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int flags = reader.ReadInt32(); int procType = reader.ReadInt32(); int procIndex = reader.ReadInt32(); int physicsBone = reader.ReadInt32(); int surfacePropIdx = reader.ReadInt32(); int contents = reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); bones[i] = new Bone(name, parent, boneControllers, position, quaternion, rotation, positionScale, rotationScale, poseToBone, alignment, flags, procType, procIndex, physicsBone, surfacePropIdx, contents); } return new ImmutableArray<Bone>(bones); }