public override void ReadFromFile(MemoryStream stream, bool isBigEndian) { base.ReadFromFile(stream, isBigEndian); NumFrames = stream.ReadInt32(isBigEndian); Frames = new FrameData[NumFrames]; for (int i = 0; i < NumFrames; i++) { FrameData frames = new FrameData(); frames.Unk01 = stream.ReadInt32(isBigEndian); frames.Unk02 = stream.ReadInt32(isBigEndian); frames.Unk03 = stream.ReadByte8(); frames.SoundFile = stream.ReadString16(isBigEndian); frames.Unk04 = stream.ReadByte8(); frames.Unk05 = stream.ReadSingle(isBigEndian); frames.Unk06 = stream.ReadSingle(isBigEndian); frames.Unk07 = stream.ReadSingle(isBigEndian); frames.Unk08 = stream.ReadInt32(isBigEndian); frames.Unk09 = stream.ReadSingle(isBigEndian); frames.Unk10 = stream.ReadInt32(isBigEndian); frames.Unk11 = stream.ReadSingle(isBigEndian); frames.Unk12 = stream.ReadInt32(isBigEndian); frames.Unk13 = stream.ReadSingle(isBigEndian); frames.Unk14 = stream.ReadSingle(isBigEndian); frames.Unk15 = stream.ReadByte8(); frames.Position = Vector3Utils.ReadFromFile(stream, isBigEndian); frames.Rotation = QuaternionExtensions.ReadFromFile(stream, isBigEndian); frames.Unk16 = stream.ReadByte8(); Frames[i] = frames; } Unk05 = stream.ReadUInt16(isBigEndian); }
void HandleThrowing(bool throwInput, bool previousThrowInput, ref bool canThrow, Transform handTrs, ref PhysicsObject grabbedPhysicsObject, Vector3 previousHandPosition, Vector3 previousHandEulerAngles) { if (grabbedPhysicsObject != null) { if (!throwInput && previousThrowInput && canThrow) { canThrow = false; grabbedPhysicsObject.trs.SetParent(null); grabbedPhysicsObject.trs.position = trs.position + GameCamera.Instance.trs.forward.SetY(0).normalized *grabbedPhysicsObjectDropDistance; Vector3 throwVelocity = (handTrs.position - previousHandPosition) / Time.deltaTime; if (InputManager._InputDevice == InputManager.InputDevice.KeyboardAndMouse) { throwVelocity += handTrs.forward * currentThrowSpeed; } grabbedPhysicsObject.rigid.velocity = throwVelocity; grabbedPhysicsObject.rigid.angularVelocity = QuaternionExtensions.GetAngularVelocity(Quaternion.Euler(previousHandEulerAngles), handTrs.rotation); StopCoroutine(UnignoreCollisionDelayRoutine(grabbedPhysicsObject.collider)); StartCoroutine(UnignoreCollisionDelayRoutine(grabbedPhysicsObject.collider)); grabbedPhysicsObject.rigid.isKinematic = false; grabbedPhysicsObject = null; } else if (throwInput && !previousThrowInput) { canThrow = true; } } }
private void CountertransformOffChainBones(RigidTransform[] preTotalTransforms, Vector3[] preCentersOfMass, RigidBoneSystemInputs inputs, RigidBone[] boneChain) { bool[] areOnChain = new bool[boneSystem.Bones.Length]; foreach (var bone in boneChain) { areOnChain[bone.Index] = true; } var rootTransform = RigidTransform.FromTranslation(inputs.RootTranslation); RigidTransform[] postTotalTransforms = new RigidTransform[preTotalTransforms.Length]; foreach (var bone in boneSystem.Bones) { if (!boneAttributes[bone.Index].IsIkable) { //don't even bother to update postTotalTransforms because non-Ikable bones never have Ikable children continue; } var parentPostTotalTransform = bone.Parent != null ? postTotalTransforms[bone.Parent.Index] : rootTransform; if (!areOnChain[bone.Index]) { var preTotalTransform = preTotalTransforms[bone.Index]; var postTotalTransform = bone.GetChainedTransform(inputs, parentPostTotalTransform); var preCenterOfRotation = preTotalTransform.Transform(bone.CenterPoint); var postCenterOfRotation = postTotalTransform.Transform(bone.CenterPoint); var originalWorldRotation = preTotalTransform.Rotation; Quaternion centerOfMassRestoringRotation; var preChildCenterOfMass = preCentersOfMass[bone.Index]; if (!float.IsNaN(preChildCenterOfMass.X)) { var counterRotationDelta = QuaternionExtensions.RotateBetween( Vector3.Normalize(preChildCenterOfMass - preCenterOfRotation), Vector3.Normalize(preChildCenterOfMass - postCenterOfRotation)); centerOfMassRestoringRotation = counterRotationDelta; } else { //no child center of mass to restore centerOfMassRestoringRotation = Quaternion.Identity; } var worldCounterRotation = originalWorldRotation.Chain(centerOfMassRestoringRotation); var counterRotation = worldCounterRotation.Chain(Quaternion.Invert(parentPostTotalTransform.Rotation)); var originalRotation = bone.GetRotation(inputs); float shrinkRatio = boneAttributes[bone.Index].MassMoment.Mass / boneAttributes[0].MassIncludingDescendants; var shrunkCounterRotation = Quaternion.Lerp(originalRotation, counterRotation, shrinkRatio); bone.SetRotation(inputs, shrunkCounterRotation, true); } var finalPostTotalTransform = bone.GetChainedTransform(inputs, parentPostTotalTransform); postTotalTransforms[bone.Index] = finalPostTotalTransform; } }
void Update() { DisplayInView(); if (!isFollowingPath) { return; } if (idleAtEachPoint) { if (!isStopped) { Vector3 tangent; MovePosition(curveMath.CalcPositionAndTangentByDistance(distanceDone, out tangent)); LerpRotation(QuaternionExtensions.LookRotation(tangent)); float currentDistanceDone = Time.deltaTime * movementSpeed; if (pointToPointDistanceDone + currentDistanceDone >= distanceToDo) { float pointToPointDistanceDoneBefore = pointToPointDistanceDone; pointToPointDistanceDone = distanceToDo; distanceDone += pointToPointDistanceDone - pointToPointDistanceDoneBefore; } else { distanceDone += currentDistanceDone; pointToPointDistanceDone += currentDistanceDone; } if (pointToPointDistanceDone >= distanceToDo) { isStopped = true; CurrentState = PathFollowerState.IDLE; UpdatePointIndexAndDistanceToDo(); currentIdleTween = DOVirtual.DelayedCall(idleTime, () => { CurrentState = PathFollowerState.MOVING; isStopped = false; currentIdleTween = null; }); } if (loop) { distanceDone %= distanceTotal; } } } else { Vector3 tangent; MovePosition(curveMath.CalcPositionAndTangentByDistance(distanceDone, out tangent)); LerpRotation(QuaternionExtensions.LookRotation(tangent)); distanceDone += Time.deltaTime * movementSpeed; if (loop) { distanceDone %= distanceTotal; } } }
public override void Tick(float dTime) { base.Tick(dTime); Sync += dTime; Mars.Orientation = QuaternionExtensions.FromAxisAngle(Vector3.UnitY, 15.0f / 180.0f * (float)Math.PI * Sync); }
/// <summary> /// Fetch a view from Google Street View API using current camera frustum. /// </summary> /// <param name="position"> /// Current position in 3D space. /// </param> /// <param name="orientation"> /// Current orientation in 3D space. /// </param> /// <returns> /// A Bitmap image representing the current view camera frustum. /// </returns> public Bitmap FetchView(Vector3 position, Quaternion orientation) { Vector3 orientationAngles; orientationAngles = QuaternionExtensions.ExtractPitchYawRoll(orientation); return(FetchView(position, orientationAngles.X, orientationAngles.Y)); }
public void UpdateDirection(Vector3 lookat, float dtime) { //left vector projected on plane Vector3 left = TargetActor.Left; left.Y = 0; left.Normalize(); //forward vector projected on plane Vector3 forward = TargetActor.Direction; forward.Y = 0; forward.Normalize(); //wanted direction vector Vector3 want; try { want = lookat - TargetActor.Position; want.Normalize(); } catch (DivideByZeroException) { System.Console.WriteLine("divide bug./%&$"); want = Vector3.UnitX; } float cos = Vector3.Dot(left, want); if (cos <= 1 && cos >= -1) { //float a = (float)Math.Acos((double)cos) * 180.0f / (float)Math.PI; //float a = -2 * cos; RotationSpeed = -2 * (float)Math.Sign(cos) * (float)Math.Sqrt(Math.Abs(cos)); Rotation += RotationSpeed * dtime; Roll = cos;// -RotationSpeed / 2; } else { RotationSpeed = 0; Roll = 0; } Quaternion q1 = QuaternionExtensions.FromAxisAngle(0, 1, 0, Rotation); TargetActor.Orientation = q1; Quaternion q2 = QuaternionExtensions.FromAxisAngle(TargetActor.Direction, Roll); TargetActor.Orientation = q1 * q2; Vector3 tmp = TargetActor.Position; tmp.Y = 0; TargetActor.Position = tmp; }
public void Strafe(float magnitude) { Vector3 lookat = QuaternionExtensions.Rotate(Orientation, Vector3.UnitZ); Vector3 forward = new Vector3(lookat.X, 0, lookat.Z).Normalized(); Vector3 up = Vector3.UnitY; Vector3 left = up.Cross(forward); Position += left * magnitude; }
public static Machine FromTag(H2vMap map, ScenarioTag scenario, ScenarioTag.MachineryInstance instance) { var scenery = new Machine(); scenery.FriendlyName = "Machine_" + instance.MachineryDefinitionIndex; if (instance.MachineryDefinitionIndex == ushort.MaxValue) { Console.WriteLine($"MACH index out of range"); return(scenery); } var id = scenario.MachineryDefinitions[instance.MachineryDefinitionIndex].Machinery; var tag = map.GetTag(id); scenery.FriendlyName = tag.Name; var orientation = QuaternionExtensions.FromH2vOrientation(instance.Orientation); var xform = new TransformComponent(scenery, instance.Position, orientation); var components = new List <Component>(); if (tag.Model != uint.MaxValue) { components.Add(new RenderModelComponent(scenery, new Model <BitmapTag> { Note = $"[{tag.Id}] {tag.Name}", Meshes = MeshFactory.GetRenderModel(map, tag.Model), Flags = ModelFlags.Diffuse | ModelFlags.CastsShadows | ModelFlags.ReceivesShadows })); components.Add(new RenderModelComponent(scenery, new Model <BitmapTag> { Note = $"[{tag.Id}] {tag.Name} bones", Meshes = MeshFactory.GetBonesModel(map, tag.Model), Flags = ModelFlags.Wireframe, RenderLayer = RenderLayers.Debug })); var body = PhysicsComponentFactory.CreateKinematicRigidBody(scenery, xform, map, tag.Model); if (body != null) { components.Add(body); components.Add(new RenderModelComponent(scenery, new Model <BitmapTag> { Meshes = MeshFactory.GetRenderModel(body.Collider, new Vector4(1f, 0f, 1f, 1f)), Flags = ModelFlags.Wireframe | ModelFlags.IsStatic, RenderLayer = RenderLayers.Collision })); } } scenery.SetComponents(xform, components.ToArray()); return(scenery); }
private BonePartialSolution SolveSingleBone( RigidBone bone, Vector3 worldSource, Vector3 worldTarget, MassMoment[] massMoments, Vector3 figureCenterOverride, RigidBoneSystemInputs inputs, RigidTransform[] boneTransforms) { if (bone.Parent == boneSystem.RootBone) { //skip the hip bone because it's the same as the root bone but with a different center return(BonePartialSolution.Zero); } var center = bone != boneSystem.RootBone ? boneTransforms[bone.Index].Transform(bone.CenterPoint) : figureCenterOverride; var parentTotalRotation = bone.Parent != null ? boneTransforms[bone.Parent.Index].Rotation : Quaternion.Identity; var boneToWorldSpaceRotation = bone.OrientationSpace.Orientation.Chain(parentTotalRotation); var worldToBoneSpaceRotation = Quaternion.Invert(boneToWorldSpaceRotation); var boneSpaceSource = Vector3.Transform(worldSource - center, worldToBoneSpaceRotation); var boneSpaceTarget = Vector3.Transform(worldTarget - center, worldToBoneSpaceRotation); var force = boneSpaceTarget - boneSpaceSource; var torque = Vector3.Cross(boneSpaceSource, force); float mass = boneAttributes[bone.Index].MassIncludingDescendants; Vector3 unnormalizedAxisOfRotation = Vector3.Cross(worldSource - center, worldTarget - center); float unnormalizedAxisOfRotationLength = unnormalizedAxisOfRotation.Length(); if (MathUtil.IsZero(unnormalizedAxisOfRotationLength)) { return(BonePartialSolution.Zero); } Vector3 axisOfRotation = unnormalizedAxisOfRotation / unnormalizedAxisOfRotationLength; float momentOfInertia = massMoments[bone.Index].GetMomentOfInertia(axisOfRotation, center); var angularVelocity = torque / momentOfInertia; var twistAxis = bone.RotationOrder.TwistAxis; var existingRotation = bone.GetOrientedSpaceRotation(inputs).AsQuaternion(twistAxis); var relaxedRotation = bone.Constraint.Center.AsQuaternion(twistAxis); float relaxationBias = InverseKinematicsUtilities.CalculateRelaxationBias(relaxedRotation, existingRotation, angularVelocity); angularVelocity *= relaxationBias; var linearVelocity = Vector3.Cross(angularVelocity, boneSpaceSource); var rotation = QuaternionExtensions.RotateBetween( Vector3.Normalize(boneSpaceSource), Vector3.Normalize(boneSpaceTarget)); var radius = boneSpaceSource.Length(); var distance = rotation.AccurateAngle() * radius; float time = distance == 0 ? 0 : distance / linearVelocity.Length(); DebugUtilities.AssertFinite(angularVelocity); return(new BonePartialSolution { angularVelocity = angularVelocity, time = time }); }
public void TestFromRotationVector() { Vector3 v = new Vector3(0.1f, 0.2f, 0.3f); var expected = Quaternion.RotationAxis(v, v.Length()); MathAssert.AreEqual(expected, QuaternionExtensions.FromRotationVector(v), 1e-4f); MathAssert.AreEqual(Quaternion.Invert(expected), QuaternionExtensions.FromRotationVector(-v), 1e-4f); }
/// <summary> /// Updates the transform and state of this object every frame, depending on /// manipulations and docking state. /// </summary> public void Update() { if (isDragging && overlappingPositions.Count > 0) { var closestPosition = GetClosestPosition(); if (closestPosition.IsOccupied) { closestPosition.GetComponentInParent <Dock>().TryMoveToFreeSpace(closestPosition); } } if (dockingState == DockingState.Docked || dockingState == DockingState.Docking) { Assert.IsNotNull(dockedPosition, "When a dockable is docked, its dockedPosition must be valid."); Assert.AreEqual(dockedPosition.DockedObject, this, "When a dockable is docked, its dockedPosition reference the dockable."); var lerpTime = dockingState == DockingState.Docked ? moveLerpTimeWhenDocked : moveLerpTime; if (!isDragging) { // Don't override dragging transform.position = Solver.SmoothTo(transform.position, dockedPosition.transform.position, Time.deltaTime, lerpTime); transform.rotation = Solver.SmoothTo(transform.rotation, dockedPosition.transform.rotation, Time.deltaTime, lerpTime); } transform.localScale = Solver.SmoothTo(transform.localScale, dockedPositionScale, Time.deltaTime, lerpTime); if (VectorExtensions.CloseEnough(dockedPosition.transform.position, transform.position, distanceTolerance) && QuaternionExtensions.AlignedEnough(dockedPosition.transform.rotation, transform.rotation, angleTolerance) && AboutTheSameSize(dockedPositionScale.x, transform.localScale.x)) { // Finished docking dockingState = DockingState.Docked; // Snap to position transform.position = dockedPosition.transform.position; transform.rotation = dockedPosition.transform.rotation; transform.localScale = dockedPositionScale; } } else if (dockedPosition == null && dockingState == DockingState.Undocking) { transform.localScale = Solver.SmoothTo(transform.localScale, originalScale, Time.deltaTime, moveLerpTime); if (AboutTheSameSize(originalScale.x, transform.localScale.x)) { // Finished undocking dockingState = DockingState.Undocked; // Snap to size transform.localScale = originalScale; } } }
public static Bloc FromTag(H2vMap map, ScenarioTag scenario, ScenarioTag.BlocInstance instance) { var scenery = new Bloc(); var components = new List <Component>(); var bloc = scenario.BlocDefinitions[instance.BlocDefinitionIndex].Bloc; var tag = map.GetTag(bloc); scenery.FriendlyName = tag.Name; components.Add(new RenderModelComponent(scenery, new Model <BitmapTag> { Note = $"[{tag.Id}] {tag.Name}", Flags = ModelFlags.Diffuse | ModelFlags.CastsShadows | ModelFlags.ReceivesShadows, Meshes = MeshFactory.GetRenderModel(map, tag.PhysicalModel), ColorChangeData = PackColorChange(instance) })); var orientation = QuaternionExtensions.FromH2vOrientation(instance.Orientation); var xform = new TransformComponent(scenery, instance.Position, orientation); var body = PhysicsComponentFactory.CreateDynamicRigidBody(scenery, xform, map, tag.PhysicalModel); if (body != null) { components.Add(body); components.Add(new RenderModelComponent(scenery, new Model <BitmapTag> { Note = $"bloc//{scenery.FriendlyName}-collision", Meshes = MeshFactory.GetRenderModel(body.Collider, new Vector4(0.19f, 0.47f, 0.15f, 1f)), Flags = ModelFlags.Wireframe | ModelFlags.IsStatic, RenderLayer = RenderLayers.Collision })); } var comOffset = Vector3.Zero; if (map.TryGetTag(tag.PhysicalModel, out var hlmt) && map.TryGetTag(hlmt.PhysicsModel, out var phmo) && phmo.BodyParameters.Length > 0) { comOffset = phmo.BodyParameters[0].CenterOfMass; } components.Add(new BoundsComponent(scenery, comOffset - new Vector3(0.02f), comOffset + new Vector3(0.02f), new Vector4(1f, 1f, 0, 1f))); components.Add(new BoundsComponent(scenery, new Vector3(-0.02f), new Vector3(0.02f), new Vector4(0, 1f, 0, 1f))); components.Add(new OriginalTagComponent(scenery, instance)); scenery.SetComponents(xform, components.ToArray()); return(scenery); }
private void UpdateEye(ChannelOutputs outputs, StagedSkinningTransform eyeParentTotalTransform, ChannelInputs inputs, Bone eyeBone, Vector3 targetPosition) { Vector3 targetPositionInRotationFreeEyeSpace = eyeParentTotalTransform.InverseTransform(targetPosition * 100) - eyeBone.CenterPoint.GetValue(outputs); var targetRotation = QuaternionExtensions.RotateBetween(Vector3.BackwardRH, targetPositionInRotationFreeEyeSpace); targetRotation = Quaternion.RotationAxis( targetRotation.Axis, TukeysBiweight(targetRotation.Angle, RotationAngleRejectionThreshold)); eyeBone.SetEffectiveRotation(inputs, outputs, targetRotation); }
public void Replace() { if (curveMath == null) { curveMath = curve.GetComponent <BGCcMath>(); } Vector3 tangent; transform.position = curveMath.CalcPositionAndTangentByDistance(0, out tangent); transform.rotation = QuaternionExtensions.LookRotation(tangent); }
private static List <Entity> CreateFromItemCollection(H2vMap map, ItemCollectionTag itmc, ScenarioTag.ItemCollectionPlacement instance) { var entities = new List <Entity>(); // I've only seen 1 item collections though foreach (var item in itmc.Items) { if (map.TryGetTag <BaseTag>(item.ItemTag, out var tag) == false) { throw new Exception("No tag found for weap/equip"); } TagRef <HaloModelTag> itemHlmt = default; if (tag is WeaponTag weap) { itemHlmt = weap.Hlmt; } if (tag is EquipmentTag eqip) { itemHlmt = eqip.Hlmt; } if (itemHlmt == default) { continue; } var entity = new Item(); entity.FriendlyName = tag.Name; var renderModel = new RenderModelComponent(entity, new Model <BitmapTag> { Note = $"[{itmc.Id}] {itmc.Name}", //Position = instance.Position, //Orientation = baseRotation, //Scale = new Vector3(1.3f), Flags = ModelFlags.Diffuse | ModelFlags.CastsShadows | ModelFlags.ReceivesShadows, Meshes = MeshFactory.GetRenderModel(map, itemHlmt) }); var xform = new TransformComponent(entity, instance.Position, QuaternionExtensions.FromH2vOrientation(instance.Orientation)); var body = PhysicsComponentFactory.CreateDynamicRigidBody(entity, xform, map, itemHlmt); entity.SetComponents(xform, renderModel, body); entities.Add(entity); } return(entities); }
public void TestRotateBetween() { Vector3 v1 = new Vector3(2, 3, 4); Vector3 v2 = new Vector3(7, 6, 5); Quaternion q = QuaternionExtensions.RotateBetween(v1, v2); Assert.AreEqual( 0, Vector3.Distance( Vector3.Normalize(Vector3.Transform(v1, q)), Vector3.Normalize(v2)), 1e-6); }
public void TestSwingBetween() { var rnd = new Random(0); Vector3 a = MakeRandomUnitVector(rnd); Vector3 b = MakeRandomUnitVector(rnd); Vector3 n = MakeRandomUnitVector(rnd); Quaternion q = QuaternionExtensions.SwingBetween(a, b, n); Vector3 rotatedA = Vector3.Transform(a, q); Assert.AreEqual(0, Vector3.Distance(b, rotatedA), 1e-4, "rotation takes a to b"); Assert.AreEqual(0, Vector3.Dot(q.Axis, n), 1e-4, "rotation axis lies in plane"); }
private void RenderQuads(RenderingContext rc) { if (_handle.NumVerticies4 > 0) { GL.UseProgram(quadShader.ShaderHandle); if (depthMask) { ApplyGeometricTransformations(rc, quadShader, this); } else { //REFACTOR!! Matrix4 mat4 = Matrix4.Identity; //Quaternion qRotFix = QuaternionExtensions.EulerToQuat(rc.cam.calibOrient.X, rc.cam.calibOrient.Y, rc.cam.calibOrient.Z); //mat4 *= Matrix4.CreateTranslation(rc.cam.calibTrans) * Matrix4.CreateFromQuaternion(qRotFix); Quaternion qRotFix = QuaternionExtensions.EulerToQuat(0.15f, 3.479997f, 0f); mat4 *= Matrix4.CreateTranslation(new Vector3(0f, 0f, -0.29f)) * Matrix4.CreateFromQuaternion(qRotFix); // test weapon/gun rendering fixed in front of player //TODO: port this to X3D quadShader.SetFieldValue("modelview", ref mat4); RefreshDefaultUniforms(quadShader); quadShader.SetFieldValue("bbox_x", bbox.Width); quadShader.SetFieldValue("bbox_y", bbox.Height); quadShader.SetFieldValue("bbox_z", bbox.Depth); quadShader.SetFieldValue("projection", ref rc.matricies.projection); quadShader.SetFieldValue("camscale", rc.cam.Scale.X); //GL.Uniform1(uniformCameraScale, rc.cam.Scale.X); quadShader.SetFieldValue("X3DScale", rc.matricies.Scale); //GL.Uniform3(uniformX3DScale, rc.matricies.Scale); quadShader.SetFieldValue("coloringEnabled", coloring ? 1 : 0); quadShader.SetFieldValue("texturingEnabled", texturingEnabled ? 1 : 0); //GL.Uniform1(uniforms.a_texturingEnabled, this.texturingEnabled ? 1 : 0); } quadShader.SetFieldValue("size", size); quadShader.SetFieldValue("scale", scale); ApplyMaterials(quadShader); GL.BindBuffer(BufferTarget.ArrayBuffer, _handle.vbo4); Buffering.ApplyBufferPointers(quadShader); GL.DrawArrays(PrimitiveType.Quads, 0, _handle.NumVerticies4); GL.UseProgram(0); } }
public void ReadFromFile(BinaryReader reader) { size = reader.ReadInt32(); actorTypeName = readString(reader); entityName = readString(reader); unkString = readString(reader); unk2String = readString(reader); definitionName = readString(reader); frameName = readString(reader); actortypeID = reader.ReadInt32(); entityHash = reader.ReadUInt64(); frameNameHash = reader.ReadUInt64(); position = Vector3Utils.ReadFromFile(reader); rotation = QuaternionExtensions.ReadFromFile(reader); scale = Vector3Utils.ReadFromFile(reader); unk3 = reader.ReadUInt16(); dataID = reader.ReadUInt16(); }
public static Vehicle CreateFromVehicleInstance(H2vMap map, ScenarioTag scenario, ScenarioTag.VehicleInstance instance) { var item = new Vehicle(); item.FriendlyName = "Vehicle_" + instance.Index; var def = scenario.VehicleDefinitions[instance.Index]; if (map.TryGetTag(def.Vehicle, out var vehi) == false) { throw new Exception("No tag found for vehi reference"); } var xform = new TransformComponent(item, instance.Position, QuaternionExtensions.FromH2vOrientation(instance.Orientation)); PopulateVehicle(item, map, xform, vehi); return(item); }
public void ReadFromFile(MemoryStream stream, bool isBigEndian) { Unk0 = stream.ReadUInt32(isBigEndian); NumRotations = stream.ReadUInt32(isBigEndian); RotationData = new QuaternionData[NumRotations]; for (int i = 0; i < NumRotations; i++) { QuaternionData RotationInfo = new QuaternionData(); RotationInfo.KeyFrameStart = stream.ReadUInt32(isBigEndian); RotationInfo.KeyFrameEnd = stream.ReadUInt32(isBigEndian); RotationInfo.Unk0 = stream.ReadUInt16(isBigEndian); RotationInfo.KeyType = stream.ReadUInt16(isBigEndian); RotationInfo.Unk01 = stream.ReadByte8(); RotationInfo.Rotation = QuaternionExtensions.ReadFromFile(stream, isBigEndian); RotationInfo.Unk03 = stream.ReadSingle(isBigEndian); RotationData[i] = RotationInfo; } }
// scene entity velocity, orientation, location public static Matrix4 ApplyX3DTransform ( Vector3 centerOffset, Vector3 rotation, Vector3 scale, Vector3 scaleOrientation, Vector3 translation, Matrix4?ParentTransform = null ) { Matrix4 PDerived; Matrix4 R; Matrix4 SR; Quaternion qR; Quaternion qSR; Matrix4 S; Matrix4 C; Matrix4 T; if (ParentTransform.HasValue == false) { ParentTransform = Matrix4.Identity; } qR = QuaternionExtensions.QuaternionFromEulerAnglesRad(rotation); qSR = QuaternionExtensions.QuaternionFromEulerAnglesRad(scaleOrientation); T = Matrix4.CreateTranslation(translation); C = Matrix4.CreateTranslation(centerOffset); R = Matrix4.CreateFromQuaternion(qR); SR = Matrix4.CreateFromQuaternion(qSR); S = Matrix4.CreateScale(scale); PDerived = T * C * R //* SR * S //* SR.Inverted() * C.Inverted() * ParentTransform.Value.Inverted(); return(PDerived); }
public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs) { headPositionForecaster.Update(updateParameters.Time, updateParameters.HeadPosition); var forecastHeadPosition = headPositionForecaster.Forecast; var outputs = channelSystem.Evaluate(null, inputs); var neckTotalTransform = headBone.Parent.GetChainedTransform(outputs); var figureEyeCenter = (leftEyeBone.CenterPoint.GetValue(outputs) + rightEyeBone.CenterPoint.GetValue(outputs)) / 2; var figureEyeWorldPosition = neckTotalTransform.Transform(figureEyeCenter); var lookPointWorldPosition = neckTotalTransform.Transform(figureEyeCenter + Vector3.BackwardRH); var lookWorldDirection = Vector3.Normalize(lookPointWorldPosition - figureEyeWorldPosition); var targetLookWorldDirection = Vector3.Normalize(forecastHeadPosition * 100 - figureEyeWorldPosition); var worldRotationCorrection = QuaternionExtensions.RotateBetween(lookWorldDirection, targetLookWorldDirection); var targetLocalRotationCorrection = Quaternion.Invert(neckTotalTransform.RotationStage.Rotation) * worldRotationCorrection * neckTotalTransform.RotationStage.Rotation; headBone.SetEffectiveRotation(inputs, outputs, targetLocalRotationCorrection); }
private static List <Entity> CreateFromVehicleCollection(H2vMap map, VehicleCollectionTag vehc, ScenarioTag.ItemCollectionPlacement instance) { var entities = new List <Entity>(); // I've only seen 1 item collections though foreach (var vehicle in vehc.VehicleReferences) { if (map.TryGetTag(vehicle.Vehicle, out var vehi) == false) { throw new Exception("No tag found for vehc reference"); } var entity = new Vehicle(); entity.FriendlyName = vehi.Name; var xform = new TransformComponent(entity, instance.Position, QuaternionExtensions.FromH2vOrientation(instance.Orientation)); PopulateVehicle(entity, map, xform, vehi); entities.Add(entity); } return(entities); }
private void ApplyPartialSolution(RigidBone bone, BonePartialSolution partialSolution, RigidTransform[] boneTransforms, Vector3 figureCenterOverride, RigidBoneSystemInputs inputs, float time) { var twistAxis = bone.RotationOrder.TwistAxis; var originalRotationQ = inputs.Rotations[bone.Index].AsQuaternion(twistAxis); var rotationDelta = QuaternionExtensions.FromRotationVector(time * partialSolution.angularVelocity); var newRotationQ = originalRotationQ.Chain(rotationDelta); var newRotation = TwistSwing.Decompose(twistAxis, newRotationQ); inputs.Rotations[bone.Index] = bone.Constraint.Clamp(newRotation); if (bone == boneSystem.RootBone) { var preTotalTransform = boneTransforms[bone.Index]; var postTotalTransform = bone.GetChainedTransform(inputs); var unposedFigureCenterOverride = preTotalTransform.InverseTransform(figureCenterOverride); var postFigureCenterOverride = postTotalTransform.Transform(unposedFigureCenterOverride); var centerDisplacement = figureCenterOverride - postFigureCenterOverride; inputs.RootTranslation += centerDisplacement; } }
/* * public override void Tick(float dtime) * { * MathUtil.Check(position.Original); * MathUtil.Check(orientation); * Matrix4 m = Matrix4.Rotate(orientation); * position.Tick(dtime, SmoothTime); * speed.Tick(dtime, SmoothTime); * position.Original += speed.Original * dtime; * position.Original += Vector3.Transform(localspeed,m) * dtime; * * MathUtil.Check(position.Original); * MathUtil.Check(orientation); * * orientation.Tick(dtime, SmoothTime); * Quaternion qx = QuaternionExtensions.FromAxisAngle(1, 0, 0, rotationspeed.X * dtime); * Quaternion qy = QuaternionExtensions.FromAxisAngle(0, 1, 0, rotationspeed.Y * dtime); * Quaternion qz = QuaternionExtensions.FromAxisAngle(0, 0, 1, rotationspeed.Z * dtime); * Quaternion q = qx * qy * qz; * * //q=Quaternion.Identity*Quaternion.Identity; * orientation.Original = q * orientation.Original; * //HACK * if (orientation.Original.W < -1.0f) * { * orientation.Original.W = -1.0f; * } * MathUtil.Check(position.Original); * MathUtil.Check(orientation); * * age += dtime; * * if (Attach != null && Attach.Kill) * Attach = null; * * if (Draw != null) * foreach (object o in Draw) * { * if (o is ITickable) * { * ((ITickable)o).Tick(dtime); * } * } * MathUtil.Check(position.Original); * MathUtil.Check(orientation); * }*/ public override void Tick(float dtime) { position.Original = Position; orientation.Original = Orientation; orientation.Tick(dtime, SmoothTime); position.Tick(dtime); age += dtime; Quaternion qx = QuaternionExtensions.FromAxisAngle(1, 0, 0, rotationspeed.X * dtime); Quaternion qy = QuaternionExtensions.FromAxisAngle(0, 1, 0, rotationspeed.Y * dtime); Quaternion qz = QuaternionExtensions.FromAxisAngle(0, 0, 1, rotationspeed.Z * dtime); Quaternion q = qx * qy * qz; orientation.Original = q * orientation.Original; //HACK if (orientation.Original.W < -1.0f) { orientation.Original.W = -1.0f; } Orientation = orientation.Original; if (Attach != null && Attach.Kill) { Attach = null; } if (Draw != null) { foreach (object o in Draw) { if (o is ITickable) { ((ITickable)o).Tick(dtime); } } } }
private void ApplyCorrection(RigidBoneSystemInputs inputs, RigidTransform[] boneTransforms, RigidBone bone, ref Vector3 sourcePosition, Vector3 targetPosition, float weight) { var centerPosition = GetCenterPosition(boneTransforms, bone); var rotationCorrection = QuaternionExtensions.RotateBetween( sourcePosition - centerPosition, targetPosition - centerPosition); var boneTransform = boneTransforms[bone.Index]; var baseLocalRotation = bone.GetRotation(inputs); var localRotationCorrection = Quaternion.Invert(boneTransform.Rotation) * rotationCorrection * boneTransform.Rotation; var lerpedRotation = Quaternion.Lerp( baseLocalRotation, baseLocalRotation * localRotationCorrection, weight); bone.SetRotation(inputs, lerpedRotation, true); var newBoneTransform = bone.GetChainedTransform(inputs, bone.Parent != null ? boneTransforms[bone.Parent.Index] : RigidTransform.Identity); var newSourcePosition = newBoneTransform.Transform(boneTransform.InverseTransform(sourcePosition)); sourcePosition = newSourcePosition; }
private Keyframe[][] GenerateRotationTrack(List <Assimp.QuaternionKey> keys, Bone bone) { Keyframe[] x_track = new Keyframe[keys.Count]; Keyframe[] y_track = new Keyframe[keys.Count]; Keyframe[] z_track = new Keyframe[keys.Count]; for (int i = 0; i < keys.Count; i++) { Assimp.QuaternionKey current_key = keys[i]; Quaternion value = new Quaternion(current_key.Value.X, current_key.Value.Y, current_key.Value.Z, current_key.Value.W); Vector3 quat_as_vec = QuaternionExtensions.ToEulerAngles(value); x_track[i].Key = quat_as_vec.X; x_track[i].Time = (float)current_key.Time; y_track[i].Key = quat_as_vec.Y; y_track[i].Time = (float)current_key.Time; z_track[i].Key = quat_as_vec.Z; z_track[i].Time = (float)current_key.Time; } return(new Keyframe[][] { x_track, y_track, z_track }); }
private void ReadM2TVersionTwo(BinaryReader reader) { //mesh name name = reader.ReadString(); isSkinned = reader.ReadBoolean(); if (isSkinned) { byte size = reader.ReadByte(); skeleton = new Skeleton(); skeleton.Joints = new Joint[size]; for (int i = 0; i < size; i++) { Joint joint = new Joint(); joint.Name = reader.ReadString8(); joint.ParentIndex = reader.ReadByte(); joint.Parent = (joint.ParentIndex != 0xFF) ? skeleton.Joints[joint.ParentIndex] : null; //may crash because root will not be in range Vector3 position = Vector3Extenders.ReadFromFile(reader); Quaternion rotation = QuaternionExtensions.ReadFromFile(reader); Vector3 scale = Vector3Extenders.ReadFromFile(reader); joint.WorldTransform = MatrixExtensions.SetMatrix(rotation, scale, position); skeleton.Joints[i] = joint; } } //Number of Lods Lods = new Lod[reader.ReadByte()]; for (int i = 0; i != Lods.Length; i++) { Lods[i] = new Lod { VertexDeclaration = 0 }; lods[i].VertexDeclaration = (VertexFlags)reader.ReadInt32(); //write length and then all vertices. lods[i].Vertices = new Vertex[reader.ReadInt32()]; for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = new Vertex(); vert.UVs = new Half2[4]; if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { vert.BoneIDs = reader.ReadBytes(4); vert.BoneWeights = new float[4]; for (int z = 0; z < 4; z++) { vert.BoneWeights[z] = reader.ReadSingle(); } } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { vert.Color0 = reader.ReadBytes(4); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { vert.Color1 = reader.ReadBytes(4); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3] = Half2Extenders.ReadFromFile(reader); } lods[i].Vertices[x] = vert; } //read mesh count and texture names. Lods[i].Parts = new ModelPart[reader.ReadInt32()]; for (int x = 0; x != Lods[i].Parts.Length; x++) { Lods[i].Parts[x] = new ModelPart(); Lods[i].Parts[x].Material = reader.ReadString(); Lods[i].Parts[x].StartIndex = reader.ReadUInt32(); Lods[i].Parts[x].NumFaces = reader.ReadUInt32(); var material = MaterialsManager.LookupMaterialByName(Lods[i].Parts[x].Material); if (material != null) { Lods[i].Parts[x].Hash = material.GetMaterialHash(); } } int numIndices = reader.ReadInt32(); Lods[i].Indices = new uint[numIndices]; for (int x = 0; x != Lods[i].Indices.Length; x++) { Lods[i].Indices[x] = reader.ReadUInt32(); } Lods[i].CalculatePartBounds(); } }