public virtual void FreeLookAt(Vector3 targetAbsRef, Vector3 upRelRef) { //Vector v1 = new Vector3(0, 0, -1); //Vector moveV = _staticModel.Position - vector; //Vector v2 = moveV.RotateBy(_staticModel.Orientation.W, 0, 1, 0); /*Vector forward = lookAt.Normalized(); Vector right = Vector::Cross(up.Normalized(), forward); Vector up = Vector::Cross(forward, right);*/ Vector3 forward ; if (_mainModel.IsChild) { //Normalizing target and transforming it to local system forward = Geometric.Quaternion_Rotate(_mainModel.ParentModel.Orientation.Inverted(), targetAbsRef.Normalized()) - _mainModel.ParentModel.Position; } else { //Normalizing target.. local system is the same as world system forward = targetAbsRef.Normalized(); } //Normalizing upVector (we are assuming it is expressed in local system) Vector3 eye = _mainModel.PositionRelative.Normalized(); Vector3 up = upRelRef.Normalized(); //Insert manual imprecision to avoid singularity if( Vector3.Dot(forward,up) == 1 ) { forward.X += 0.001f; forward.Y += 0.001f; forward.Z += 0.001f; } //float angle = (float)Math.Acos( Vector3.DotProduct(current,targetAbsRef) ); //Vector3 rotAxis = Vector3.CrossProduct(current, forward).Normalize(); //Vector3 right = Vector3.CrossProduct(forward, up); Matrix4 lookAt_result = Matrix4.LookAt( eye.X, eye.Y, eye.Z, forward.X, forward.Y, forward.Z, up.X, up.Y, up.Z ); Matrix3 targetRelOrientation_matrix = new Matrix3(lookAt_result); Quaternion targetRelOrientation_quaternion = Quaternion.FromMatrix(targetRelOrientation_matrix); /* Quaternion targetRelOrientation_quaternion = new Quaternion(); targetRelOrientation_quaternion.W = (float)Math.Sqrt((double)(1.0f + right.X + up.Y + forward.Z)) * 0.5f; float w4_recip = 1.0f / (4.0f * targetRelOrientation_quaternion.W); targetRelOrientation_quaternion.X = (forward.Y - up.Z) * w4_recip; targetRelOrientation_quaternion.Y = (right.Z - forward.X) * w4_recip; targetRelOrientation_quaternion.Z = (up.X - right.Y) * w4_recip; */ _mainModel.OrientationRelative = Quaternion.Slerp(_mainModel.OrientationRelative, targetRelOrientation_quaternion, Game.DeltaTime * 0.001f); }
public Camera(Vector3 pos, Vector3 forward, Vector3 up, float fieldOfView) { _position = pos; _forward = forward.Normalized(); _up = up.Normalized(); _fieldOfView = fieldOfView; }
public void Update(ISteering steering, float frametime) { Position += Velocity * frametime; Velocity += steering.GetLinearAcceleration() * frametime; if (Velocity.Length > MaxSpeed) { Velocity = Velocity.Normalized() * MaxSpeed; } }
public Camera(Vector3 position, Vector3 forward, Vector3 worldUp, float fieldOfView, Size renderSize) : base(position) { this.ReflectionDepth = 5; this.forward = forward.Normalized(); this.right = Util.CrossProduct(worldUp, forward).Normalized(); this.up = -Util.CrossProduct(right, forward).Normalized(); this.fieldOfView = fieldOfView; this.RenderSize = renderSize; RecalculateFieldOfView(); }
public Camera(Vector3 position, Vector3 forward, Vector3 worldUp, float fieldOfView, Size renderSize) : base(position) { this.ReflectionDepth = 5; this.forward = forward.Normalized(); //this.up = up; this.right = Vector3.Normalize(Vector3.Cross(worldUp, forward)); this.up = Vector3.Normalize(-Vector3.Cross(right, forward)); this.fieldOfView = fieldOfView; this.RenderSize = renderSize; RecalculateFieldOfView(); }
/// <summary> /// Constructs a plane with the properties provided /// </summary> /// <param name="position">The position of the plane's center</param> /// <param name="material">The plane's material</param> /// <param name="normalDirection">The normal direction of the plane</param> /// <param name="cellWidth">The width of a cell in the plane, used for texture coordinate mapping.</param> public InfinitePlane(Vector3 position, Material material, Vector3 normalDirection, float cellWidth) : base(position, material) { this.normalDirection = normalDirection.Normalized(); if (normalDirection == Util.ForwardVector) { this.uDirection = -Util.RightVector; } else if (normalDirection == -Util.ForwardVector) { this.uDirection = Util.RightVector; } else { this.uDirection = Util.CrossProduct(normalDirection, Util.ForwardVector).Normalized(); } this.vDirection = -Util.CrossProduct(normalDirection, uDirection).Normalized(); this.cellWidth = cellWidth; }
/// <summary> /// Angle between vectors. /// </summary> public static float AngleTo(this Vector3 vector, Vector3 other) { return((float)System.Math.Acos(vector.Normalized().Dot(other.Normalized()))); }
private void _MovementControl(float delta) { Transform camera = ((Camera)GetNode("Camera")).GetGlobalTransform(); Vector3 charRot = new Vector3(); Vector3 direction = new Vector3(); Vector2 joystick = new Vector2(Input.GetJoyAxis(0, 0), Input.GetJoyAxis(0, 1)); bool isMoving = false; if (joystick.Length() > 0.25) { direction.x = joystick.x; direction.z = joystick.y; isMoving = true; } else { if (Input.IsActionPressed("ui_up")) { direction += -camera.basis[0]; isMoving = true; } if (Input.IsActionPressed("ui_left")) { direction += camera.basis[2]; isMoving = true; } if (Input.IsActionPressed("ui_right")) { direction += -camera.basis[2]; isMoving = true; } if (Input.IsActionPressed("ui_down")) { direction += camera.basis[0]; isMoving = true; } } direction.y = 0; direction = direction.Normalized(); velocity.y += gravity * delta; Vector3 hv = new Vector3(velocity.x, 0, velocity.z); var newPos = direction * speed; var accel = deAcceleration; if (direction.Dot(hv) > 0) { accel = acceleration; } hv = hv.LinearInterpolate(newPos, accel * delta); velocity.x = hv.x; velocity.z = hv.z; if (isMoving) { Spatial node = (Spatial)GetNode("Mesh"); float angle = Mathf.Atan2(hv.z, hv.x); charRot = node.GetRotation(); charRot.z = angle; node.SetRotation(charRot); } velocity = MoveAndSlide(velocity, new Vector3(0, 1, 0)); if (IsOnFloor() && Input.IsActionPressed("ui_accept")) { velocity.y = 10; } RpcUnreliable("OnMove", GetGlobalTransform().origin, Id, isMoving, charRot); }
//constructors public Camera(Vector3 cameraPos, Vector3 cameraDir, Vector3 cameraUp) { this.cameraPos = cameraPos; this.cameraUp = cameraUp.Normalized(); this.cameraDir = cameraDir.Normalized(); }
public Ray(Vector3 origin, Vector3 direction) { Direction = direction.Normalized(); Origin = origin; }
public override void Render() { int culled = 0; foreach (PointLight light in Entity.GetAll <PointLight>()) { if (Entity.Has <Transform>(light.Id)) { light.CachedPosition = Entity.Get <Transform>(light.Id).Position.Value; } } foreach (Camera cam in Entity.GetAll <Camera>()) { Matrix4 camMatrix = Matrix4.Identity; Vector3 camFwd = Vector3.UnitZ; Vector3 camPos = Vector3.Zero; if (Entity.Has <Transform>(cam.Id)) { Transform camTrans = Entity.Get <Transform>(cam.Id); cam.Begin(camTrans.ViewMatrix); camMatrix = camTrans.ViewMatrix; camFwd = camTrans.Forward; camPos = camTrans.Position.Value; } else { cam.Begin(Matrix4.Identity); } foreach (Renderer r in Entity.GetAll <Renderer>()) { if ((r.LayerMask.Value & cam.LayerMask.Value) == 0) { continue; //If the camera and renderer use different layers, don't draw } Matrix4 viewMatrix = Matrix4.Identity; Matrix4 normalMatrix = Matrix4.Identity; if (Entity.Has <Transform>(r.Id)) { Transform t = Entity.Get <Transform>(r.Id); viewMatrix = t.ViewMatrix; normalMatrix = t.ScalingMatrix * t.RotationMatrix; } if (Entity.Has <MeshFilter>(r.Id)) //If there is a Mesh component, draw that { MeshFilter mf = Entity.Get <MeshFilter>(r.Id); if (mf.Mesh.Value != null) { bool cull = true; Bounds b = mf.Mesh.Value.GetBounds(); GL.PushMatrix(); GL.Translate(b.Min + (b.Max - b.Min) / 2f); //new Sphere(((b.Max - b.Min)/2f).LengthFast).Draw(viewMatrix, normalMatrix, OpenTK.Graphics.Color4.Magenta); //Draw bounding boxes as spheres GL.PopMatrix(); foreach (Vector3 corner in b.GetCorners()) { Vector3 t = Vector3.Transform(corner, viewMatrix); Vector3 diff = (t - camPos); if (cam.IsPerspective && diff.LengthFast > cam.ViewDistance.Value) { continue; //Out of viewing range, no need to check against FoV } double angle = Math.Acos(Vector3.Dot(camFwd, diff.Normalized())); //Get angle between camera forward direction and direction to bound corner if (cam.IsPerspective && angle < MathHelper.DegreesToRadians(cam.FieldOfView.Value)) //If angle is inside field of view, don't cull { cull = false; break; } } if (!cull) { mf.Mesh.Value.Draw(viewMatrix, normalMatrix, mf.Color.Value); } else { culled++; } } } else //Otherwise, draw an XYZ axis gizmo so we can see where it is { GL.PushMatrix(); GL.MultMatrix(ref viewMatrix); GL.Begin(PrimitiveType.Lines); GL.Color3(1f, 0f, 0f); GL.Vertex3(0f, 0f, 0f); GL.Color3(1f, 0f, 0f); GL.Vertex3(1f, 0f, 0f); GL.Color3(0f, 1f, 0f); GL.Vertex3(0f, 0f, 0f); GL.Color3(0f, 1f, 0f); GL.Vertex3(0f, 1f, 0f); GL.Color3(0f, 0f, 1f); GL.Vertex3(0f, 0f, 0f); GL.Color3(0f, 0f, 1f); GL.Vertex3(0f, 0f, 1f); GL.End(); GL.PopMatrix(); } } cam.End(); } Debug.AddMsg("Culled: " + culled); }
public static float Angle(Vector3 A, Vector3 B) { return(Mathf.Acos(A.Normalized().Dot(B.Normalized())) * Rad2Deg); }
public override void Update(float delta) { base.Update(delta); Vector3 finalMove = Vector3.Zero; Vector3 snapDown = Vector3.Zero; //All things that happen when the player is on the ground if (groundColliding) { //For when the player stops moving. if (!controller.inputs.moved) { if (currentSpeed < .1f) { switch (controller.ability.GetCurrentState()) { case PlayerState.sprinting: case PlayerState.walking: Stop(); SetState(PlayerState.standing); break; case PlayerState.crouch: Stop(); break; } } if (controller.ability.GetCurrentState() != PlayerState.slide) { if (currentSpeed < .1f) { currentSpeed = 0; } else { currentSpeed -= currentSpeed * time * PlayerOptions.walkingDeceleration; } } } else //This is what happens when they do move { //This section is for changing the players state if (controller.size.crouched) { if (accelerate > 1.1f) { SetState(PlayerState.slide); } else { SetState(PlayerState.crouch); } } else { if (maxSpeed == PlayerOptions.playerMaxWalkingSpeed) { SetState(PlayerState.walking); } else { SetState(PlayerState.sprinting); } } } //Testing whether we need to modify the angle that the player walks if (!groundData.colliding || controller.ability.GetNoCollide()) { finalMove += stableMove.Normalized() * currentSpeed * accelerate; //This is the mod that allows walking up slopes needs to be zero'd out when not in use verticalAddition *= 0; } else { //The mod being calculated verticalAddition = groundData.normal.Cross(stableMove.Rotated(Vector3.Up, NinetyDegreesToRad)).Normalized(); finalMove += verticalAddition * currentSpeed * accelerate; } //Used primarely quick bursts of speed but drops when on the ground horizontalAcc -= horizontalAcc * time * .9f; //Universal knockback that only starts to slow when on the ground if (knockback.Length() < .1f) { knockback *= 0; } else { knockback -= knockback * time * 2f; } if (verticalMove.Length() < 0.01f) { snapDown = Vector3.Down; } } else //No longer on the ground { //This sets the state to falling up and down so long as the player isnt' wall running or gliding if (controller.ability.GetCurrentState() != PlayerState.wallRunning && controller.ability.GetCurrentState() != PlayerState.glide) { if (verticalMove.y > 0) { SetState(PlayerState.fallingUp); } else { SetState(PlayerState.fallingDown); } } //For when the player is in the air and is moving finalMove += stableMove * accelerate; //Controlling the vertical movement of the player depending on the state they are currently in switch (controller.ability.GetCurrentState()) { case PlayerState.wallRunning: verticalMove += Vector3.Down * time * PlayerOptions.wallRunningGravity; break; case PlayerState.glide: verticalMove = Vector3.Down * PlayerOptions.glideFallSpeed; break; default: verticalMove += Vector3.Down * time * PlayerOptions.gravity; break; } } //Some edge cases where the player is on the ground and gets hit with knockback or something that modifies vertical move if (PlayerAreaSensor.GetArea(AreaSensorDirection.Above) && verticalMove.y > 0) { verticalMove = Vector3.Zero; } finalMove += horizontalAcc + verticalMove + pushing + knockback; //Moves the player finally controller.MoveAndSlideWithSnap(finalMove, snapDown, Vector3.Up, true); //Will only work if you have a force applying downward to the character? if (controller.IsOnFloor() != onFloor) { onFloor = controller.IsOnFloor(); controller.GroundChanging(onFloor); floorMovement.y = controller.GetFloorVelocity().y; } if (currentAccelerationTime < PlayerOptions.slideMaxTime) { currentAccelerationTime += time; } else { accelerate = Mathf.Clamp(accelerate - PlayerOptions.slideDeceleration * time, 1, accelerate); } pushing = Vector3.Zero; if (controller.ability.GetCurrentState() != PlayerState.slide) { if (moved) { movedBuffer += 1; if (movedBuffer > 60f - Engine.GetFramesPerSecond()) { moved = false; movedBuffer = 0f; } } } }
private void GenerateNormal(IVertex vertex, List<IFace> faces) { var accumulatedNormal = new Vector3(); foreach (var face in faces) { accumulatedNormal += GetFaceNormal(face); } vertex.Normal = accumulatedNormal.Normalized(); }
public Ray(Vector3 origin, Vector3 direction, float estimatedLength) { Origin = origin; Direction = direction.Normalized(); EstimatedLength = estimatedLength; }
public void Assign(Vector3 n, Vector3 pos) { Normal = n.Normalized(); Dot = Normal.Dot(pos); }
public override void _PhysicsProcess(float delta) { if (IsNetworkMaster()) { direction = new Vector3(); moved = false; if (Input.IsActionPressed("move_forward")) { direction -= Transform.basis.z; if (!characterAnimationPlayer.IsPlaying()) { characterAnimationPlayer.Play("Running"); if (GetTree().NetworkPeer != null) { ObjectBroker.Instance.NetworkService.toServer(new ClientAnimationStateUpdate("Running", false)); } moved = true; } } if (Input.IsActionPressed("move_backward")) { direction += Transform.basis.z; if (!characterAnimationPlayer.IsPlaying()) { characterAnimationPlayer.PlayBackwards("Running"); if (GetTree().NetworkPeer != null) { ObjectBroker.Instance.NetworkService.toServer(new ClientAnimationStateUpdate("Running", true)); } moved = true; } } if (Input.IsActionPressed("move_left")) { direction -= Transform.basis.x; moved = true; } if (Input.IsActionPressed("move_right")) { direction += Transform.basis.x; moved = true; } if (Input.IsActionPressed("jump") && IsOnFloor()) { cc.y = jump; moved = true; } if (Input.IsActionPressed("move_sprint") && IsOnFloor()) { speed = 35; moved = true; } else { speed = 10; } direction.y -= gravity * delta; cc.y -= gravity * delta; cc = MoveAndSlide(cc, Vector3.Up, true); direction = direction.Normalized(); velocity = velocity.LinearInterpolate(direction * speed, acceleration * delta); velocity = MoveAndSlide(velocity, Vector3.Up, true); if (GetTree().NetworkPeer != null && (moved || (velocity.Length() > 0))) { ObjectBroker.Instance.NetworkService.toServer(new ClientPositionUpdate(Translation, Rotation)); } } }
protected Vector3 SetControlPoint(float gap, Vector3 controlPoint) { return(controlPoint.Normalized() * gap * 0.7f); }
public void DoStuff(float timeStep) { foreach (Rigidbody rb in Entity.GetAll <Rigidbody>()) { if (!Entity.Has <Transform>(rb.Id)) { continue; } Transform t = Entity.Get <Transform>(rb.Id); foreach (Attractor atr in Entity.GetAll <Attractor>()) { Vector3 pos = Vector3.Zero; Vector3 normal = atr.Normal.Value; if (Entity.Has <Transform>(atr.Id)) { pos = Entity.Get <Transform>(atr.Id).Position.Value; normal = Entity.Get <Transform>(atr.Id).ToWorldNormal(normal); } if (atr.Type.Value == Attractor.AttractionType.World) { rb.Velocity.Value += atr.Normal.Value * atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) * timeStep; } else if (atr.Type.Value == Attractor.AttractionType.Point) { Vector3 diff = (t.Position.Value - pos); float dist = diff.Length; if (dist > 0f) { dist = Math.Max(dist, 1f); } if (dist < 0f) { dist = Math.Min(dist, -1f); } rb.Velocity.Value += diff.Normalized() * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep; Console.WriteLine(diff.Normalized() * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep); } else if (atr.Type.Value == Attractor.AttractionType.Plane) { float dist = Vector3.Dot(normal, pos - t.Position.Value); float sign = (dist > 0f ? 1f : 0f); dist = Math.Abs(dist); rb.Velocity.Value += normal * sign * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep; } } t.Position.Value += rb.Velocity.Value * timeStep; t.Rotation.Value *= Quaternion.FromMatrix(Matrix3.CreateRotationZ(rb.AngularVelocity.Value.Z * timeStep) * Matrix3.CreateRotationX(rb.AngularVelocity.Value.X * timeStep) * Matrix3.CreateRotationY(rb.AngularVelocity.Value.Y * timeStep)); if (Entity.Has <Constraint>(rb.Id)) { Constraint c = Entity.Get <Constraint>(rb.Id); Vector3 pos = t.Position.Value; pos.X = Math.Max(c.MinPosition.Value.X, Math.Min(c.MaxPosition.Value.X, pos.X)); pos.Y = Math.Max(c.MinPosition.Value.Y, Math.Min(c.MaxPosition.Value.Y, pos.Y)); pos.Z = Math.Max(c.MinPosition.Value.Z, Math.Min(c.MaxPosition.Value.Z, pos.Z)); t.Position.Value = pos; } } }
// Token: 0x06000139 RID: 313 RVA: 0x000095FE File Offset: 0x000077FE public static bool IsParallelTo(this Vector3 vector, Vector3 other, float tolerance = 1E-06f) { return(Math.Abs(1.0 - (double)Math.Abs(vector.Normalized().Dot(other.Normalized()))) <= (double)tolerance); }
/// <summary> /// /// </summary> /// <returns></returns> private void ProcessMesh(IOScene scene, IOMesh mesh, HSD_JOBJ rootnode) { HSD_JOBJ parent = rootnode; if (mesh.ParentBone != null && _cache.NameToJOBJ.ContainsKey(mesh.ParentBone.Name)) { parent = _cache.NameToJOBJ[mesh.ParentBone.Name]; } HSD_DOBJ root = null; HSD_DOBJ prev = null; var skeleton = rootnode.BreathFirstList; Console.WriteLine("Processing " + mesh.Name); bool singleBinded = mesh.Name.Contains("SINGLE"); foreach (var poly in mesh.Polygons) { // Skip Empty Polygon if (poly.Indicies.Count == 0) { continue; } // convert to triangles poly.ToTriangles(mesh); if (poly.PrimitiveType != IOPrimitive.TRIANGLE) { continue; } // Generate DOBJ HSD_DOBJ dobj = new HSD_DOBJ(); if (Settings.ImportMeshNames) { dobj.ClassName = mesh.Name; } if (root == null) { root = dobj; } else { prev.Next = dobj; } prev = dobj; // generate material var material = scene.Materials.Find(e => e.Name == poly.MaterialName); dobj.Mobj = GenerateMaterial(material); Console.WriteLine(mesh.Name + " " + material?.Name); // reflective mobjs do not use uvs var hasReflection = false; // bump maps need tangents and bitangents var hasBump = false; // Assess needed attributes based on the material MOBJ if (mesh.Name.Contains("REFLECTIVE")) { hasReflection = true; } if (mesh.Name.Contains("BUMP")) { hasBump = true; } if (dobj.Mobj.Textures != null) { foreach (var t in dobj.Mobj.Textures.List) { if (t.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION)) { hasReflection = true; } if (t.Flags.HasFlag(TOBJ_FLAGS.BUMP)) { hasBump = true; } } } // assess attributes List <GXAttribName> Attributes = new List <GXAttribName>(); if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded) { Attributes.Add(GXAttribName.GX_VA_PNMTXIDX); if (hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX0MTXIDX); } if (hasReflection && dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1) { Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX); } } Attributes.Add(GXAttribName.GX_VA_POS); if (hasBump) { Attributes.Add(GXAttribName.GX_VA_NBT); } else if (mesh.HasNormals && Settings.ImportNormals) { Attributes.Add(GXAttribName.GX_VA_NRM); } if (mesh.HasColorSet(0) && Settings.ImportVertexColor) { Attributes.Add(GXAttribName.GX_VA_CLR0); } if (mesh.HasColorSet(1) && Settings.ImportVertexColor) { Attributes.Add(GXAttribName.GX_VA_CLR1); } if (mesh.HasUVSet(0) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX0); } if ((mesh.HasUVSet(1) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX1); } if ((mesh.HasUVSet(2) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 2)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX2); } if ((mesh.HasUVSet(3) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 3)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX3); } if ((mesh.HasUVSet(4) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 4)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX4); } if ((mesh.HasUVSet(5) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 5)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX5); } if ((mesh.HasUVSet(6) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 6)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX6); } if ((mesh.HasUVSet(7) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 7)) && !hasReflection) { Attributes.Add(GXAttribName.GX_VA_TEX7); } var vertices = new List <GX_Vertex>(); var jobjList = new List <HSD_JOBJ[]>(); var weightList = new List <float[]>(); foreach (var face in poly.Indicies) { var v = mesh.Vertices[face]; GX_Vertex vertex = new GX_Vertex(); var tkvert = new Vector3(v.Position.X, v.Position.Y, v.Position.Z); var tknrm = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z); var tktan = new Vector3(v.Tangent.X, v.Tangent.Y, v.Tangent.Z); var tkbitan = new Vector3(v.Binormal.X, v.Binormal.Y, v.Binormal.Z); var parentTransform = _cache.jobjToWorldTransform[parent].Inverted(); tkvert = Vector3.TransformPosition(tkvert, parentTransform); tknrm = Vector3.TransformNormal(tknrm, parentTransform).Normalized(); tktan = Vector3.TransformNormal(tktan, parentTransform).Normalized(); tkbitan = Vector3.TransformNormal(tkbitan, parentTransform).Normalized(); if (mesh.HasEnvelopes() && Settings.ImportRigging) { // create weighting lists jobjList.Add(v.Envelope.Weights.Select(e => _cache.NameToJOBJ[e.BoneName]).ToArray()); weightList.Add(v.Envelope.Weights.Select(e => e.Weight).ToArray()); // indicate enveloped jobjs foreach (var bw in v.Envelope.Weights) { if (!_cache.EnvelopedJOBJs.Contains(_cache.NameToJOBJ[bw.BoneName])) { _cache.EnvelopedJOBJs.Add(_cache.NameToJOBJ[bw.BoneName]); } } // invert single binds if (v.Envelope.Weights.Count == 1) { var inv = _cache.jobjToWorldTransform[_cache.NameToJOBJ[v.Envelope.Weights[0].BoneName]].Inverted(); tkvert = Vector3.TransformPosition(tkvert, inv); tknrm = Vector3.TransformNormal(tknrm, inv).Normalized(); tktan = Vector3.TransformNormal(tknrm, inv).Normalized(); tkbitan = Vector3.TransformNormal(tknrm, inv).Normalized(); } } vertex.POS = GXTranslator.fromVector3(tkvert); vertex.NRM = GXTranslator.fromVector3(tknrm.Normalized()); vertex.TAN = GXTranslator.fromVector3(tktan); vertex.BITAN = GXTranslator.fromVector3(tkbitan); if (Settings.InvertNormals) { vertex.NRM.X *= -1; vertex.NRM.Y *= -1; vertex.NRM.Z *= -1; vertex.TAN.X *= -1; vertex.TAN.Y *= -1; vertex.TAN.Z *= -1; vertex.BITAN.X *= -1; vertex.BITAN.Y *= -1; vertex.BITAN.Z *= -1; } if (mesh.HasUVSet(0)) { vertex.TEX0 = new GXVector2(v.UVs[0].X, v.UVs[0].Y); } if (mesh.HasUVSet(1)) { vertex.TEX1 = new GXVector2(v.UVs[1].X, v.UVs[1].Y); } if (mesh.HasUVSet(2)) { vertex.TEX2 = new GXVector2(v.UVs[2].X, v.UVs[2].Y); } if (mesh.HasUVSet(3)) { vertex.TEX3 = new GXVector2(v.UVs[3].X, v.UVs[3].Y); } if (mesh.HasUVSet(4)) { vertex.TEX4 = new GXVector2(v.UVs[4].X, v.UVs[4].Y); } if (mesh.HasUVSet(5)) { vertex.TEX5 = new GXVector2(v.UVs[5].X, v.UVs[5].Y); } if (mesh.HasUVSet(6)) { vertex.TEX6 = new GXVector2(v.UVs[6].X, v.UVs[6].Y); } if (mesh.HasUVSet(7)) { vertex.TEX7 = new GXVector2(v.UVs[7].X, v.UVs[7].Y); } if (mesh.HasColorSet(0)) { vertex.CLR0 = new GXColor4( v.Colors[0].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1), v.Colors[0].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1), v.Colors[0].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1), Settings.ImportVertexAlpha ? v.Colors[0].W : 1); } if (mesh.HasColorSet(1)) { vertex.CLR1 = new GXColor4( v.Colors[1].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1), v.Colors[1].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1), v.Colors[1].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1), Settings.ImportVertexAlpha ? v.Colors[1].W : 1); } vertices.Add(vertex); } // generate pobjs HSD_POBJ pobj = null; if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded) { pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), jobjList, weightList); } else { pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), null); } if (singleBinded && jobjList.Count > 0 && jobjList[0].Length > 0) { parent = jobjList[0][0]; } if (pobj != null) { if (dobj.Pobj == null) { dobj.Pobj = pobj; } else { dobj.Pobj.Add(pobj); } } } if (parent.Dobj == null) { parent.Dobj = root; } else { parent.Dobj.Add(root); } }
//Solves for the ik chain private void solveIk() { if (_isRunning) { //Makes the Targetnode play nice with the skeleton by making it's values local Transform targetTransform = new Transform(new Basis(_targetNode.GlobalTransform.basis.Quat() * _targetSkeleton.GlobalTransform.basis.Quat()), _targetSkeleton.ToLocal(_targetNode.GlobalTransform.origin)); //Resets the bones to the base bones in case there is a bug so that the solver doesn't stay broken _targetSkeleton.SetBonePose(_boneIds[0], _boneBasePose[0]); _targetSkeleton.SetBonePose(_boneIds[1], _boneBasePose[1]); _targetSkeleton.SetBonePose(_boneIds[2], _boneBasePose[2]); //Float to get the distance to the target from the root bone Global pose origin float targetDistanceSquared = targetTransform.origin.DistanceSquaredTo(LocalPoseToGlobalPose(_boneIds[0], _boneBasePose[0]).origin); //Checks whether the bone is in range or not if (targetDistanceSquared >= _maxChainLength || targetDistanceSquared <= _minChainLength) //Out of range Solver { for (int i = 0; i < 2; i++) { //Uses Normal math to point the chain at the target if it is out of range Vector3 boneNormal = _targetSkeleton.GetBoneGlobalPose(_boneIds[i + 1]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[i]).origin; Vector3 targetNormal = targetTransform.origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[i]).origin; Transform boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[i]); boneTransform.basis = boneTransform.basis.Rotated(boneNormal.Cross(targetNormal).Normalized(), boneNormal.AngleTo(targetNormal)); _targetSkeleton.SetBonePose(_boneIds[i], GlobalPoseToLocalPose(_boneIds[i], boneTransform)); } } else //Solve for Two Bone { //Makes a target vector based on the target and the root bone Vector3 targetVector = targetTransform.origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin; //Variable to hold lengths needed for law of cosigns float[,] lengths = new float[2, 3]; //Target Triangle lengths lengths[0, 0] = _boneLengths[0]; lengths[0, 1] = _boneLengths[1]; lengths[0, 2] = targetVector.Length(); //Current Triangle Lengths lengths[1, 0] = _boneLengths[0]; lengths[1, 1] = _boneLengths[1]; lengths[1, 2] = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin).Length(); //Get Bone Vectors Vector3[] boneVector = new Vector3[2]; boneVector[0] = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin; boneVector[1] = _targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin; //Get angles need for rotation float currentBoneAngle = LawOfCosigns(lengths[1, 2], lengths[1, 1], lengths[1, 0]); float targetBoneAngle = LawOfCosigns(lengths[0, 2], lengths[0, 1], lengths[0, 0]); //Solve for the inner angle of the elbow bone by subtracting the targetAngle by the elbow's current inner angle float angleToRotate = targetBoneAngle - currentBoneAngle; //Get elbow axis of upper arm and lower arm Vector3 elbowAxis = (boneVector[0].Cross(boneVector[1])).Normalized(); //Set elbow inner angle of the second bone transform with the elbowAxis Transform boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[1]); boneTransform.basis = boneTransform.basis.Rotated(elbowAxis, angleToRotate); //Set Pose of the elbow with the new transform _targetSkeleton.SetBonePose(_boneIds[1], GlobalPoseToLocalPose(_boneIds[1], boneTransform)); //settings up total chain vector (Vector from the root bone to the tip bone) Vector3 chainVector = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin); //Get the root bone transform and rotate so that it aligns with the target Vector boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]); boneTransform.basis = boneTransform.basis.Rotated(chainVector.Cross(targetVector).Normalized(), chainVector.AngleTo(targetVector)); //Set Shoulder rotation _targetSkeleton.SetBonePose(_boneIds[0], GlobalPoseToLocalPose(_boneIds[0], boneTransform)); //Solve for magnet if (_useMagnet) { //Find the arm chain normal and use it for the normal of the plane chainVector = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin); Vector3 chainNormal = chainVector.Normalized(); Plane magnetPlane = new Plane(chainNormal, 0); //Project both the magnet and the elbow to said plane and return their positions; Vector3 elbowProject = magnetPlane.Project(_targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin); Vector3 magnetProject = magnetPlane.Project(magnetVector - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin); //Find the signed rotation between the positions float rotation = SignedAngle(elbowProject, magnetProject, chainNormal); //Rotate and apply bone rotations boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]); boneTransform.basis = boneTransform.basis.Rotated(chainNormal, rotation); _targetSkeleton.SetBonePose(_boneIds[0], GlobalPoseToLocalPose(_boneIds[0], boneTransform)); } } //SetEnd to be target rotation Transform endBoneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[2]); endBoneTransform.basis = new Basis(targetTransform.basis.Quat()); _targetSkeleton.SetBonePose(_boneIds[2], GlobalPoseToLocalPose(_boneIds[2], endBoneTransform)); } }
public static Vector3 Projection(Vector3 projectedVector, Vector3 directionVector) { var mag = Vector3.Dot(projectedVector, directionVector.Normalized()); return directionVector * new Vector3(mag); }
/// <summary>Call this method to update a single track follower on an absolute basis</summary> /// <param name="NewTrackPosition">The new absolute track position of the follower</param> /// <param name="UpdateWorldCoordinates">Whether to update the world co-ordinates</param> /// <param name="AddTrackInaccuracy">Whether to add track innacuracy</param> public void UpdateAbsolute(float NewTrackPosition, bool UpdateWorldCoordinates, bool AddTrackInaccuracy) { if (TrackIndex == 0 && (currentHost.Tracks[0].Elements == null || currentHost.Tracks[TrackIndex].Elements.Length == 0)) { /* * Used for displaying trains in Object Viewer * As we have no track, just update the Z value with the new pos */ WorldPosition.z = NewTrackPosition; return; } if (!currentHost.Tracks.ContainsKey(TrackIndex) || currentHost.Tracks[TrackIndex].Elements.Length == 0) { return; } int i = System.Math.Min(currentHost.Tracks[TrackIndex].Elements.Length - 1, LastTrackElement); while (i >= 0) { if (currentHost.Tracks[TrackIndex].Elements[i].InvalidElement) { var prevTrackEnded = currentHost.Tracks[TrackIndex].Elements.Select((x, j) => new { Index = j, Element = x }).Take(i + 1).LastOrDefault(x => !x.Element.InvalidElement); if (prevTrackEnded == null) { break; } i = prevTrackEnded.Index; if (i == 0) { break; } } if (NewTrackPosition >= currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition) { break; } double ta = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition; const double tb = -0.01; CheckEvents(i, -1, ta, tb); i--; } if (i >= 0) { while (i < currentHost.Tracks[TrackIndex].Elements.Length - 1) { if (currentHost.Tracks[TrackIndex].Elements[i + 1].InvalidElement) { var nextTrackStarted = currentHost.Tracks[TrackIndex].Elements.Select((x, j) => new { Index = j, Element = x }).Skip(i + 1).FirstOrDefault(x => !x.Element.InvalidElement); if (nextTrackStarted == null) { break; } i = nextTrackStarted.Index; if (i == currentHost.Tracks[TrackIndex].Elements.Length - 1) { break; } } if (NewTrackPosition < currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition) { break; } double ta = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition; double tb = currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition + 0.01; CheckEvents(i, 1, ta, tb); i++; } } else { i = 0; } float da = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition; float db = NewTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition; // track if (UpdateWorldCoordinates) { if (db != 0.0) { if (currentHost.Tracks[TrackIndex].Elements[i].CurveRadius != 0.0) { // curve float r = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius; float p = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.y / Godot.Mathf.Sqrt(currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x + currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z); float s = db / Godot.Mathf.Sqrt(1.0f + p * p); float h = s * p; float b = s / System.Math.Abs(r); float f = 2.0f * r * r * (1.0f - Godot.Mathf.Cos(b)); float c = (float)System.Math.Sign(db) * Godot.Mathf.Sqrt(f >= 0.0f ? f : 0.0f); // todo math float a = (float)(0.5f * (double)System.Math.Sign(r) * b); Vector3 D = new Vector3(currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x, 0.0f, currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z); D = D.Normalized(); D = D.Rotated(Vector3.Down, a); WorldPosition.x = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.x + c * D.x; WorldPosition.y = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.y + h; WorldPosition.z = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.z + c * D.z; D = D.Rotated(Vector3.Down, a); WorldDirection.x = D.x; WorldDirection.y = (float)p; WorldDirection.z = D.z; WorldDirection = WorldDirection.Normalized(); WorldSide = currentHost.Tracks[TrackIndex].Elements[i].WorldSide; WorldSide = WorldSide.Rotated(Vector3.Down, 2.0f * a); WorldUp = WorldDirection.Cross(WorldSide); } else { // straight WorldPosition = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition + db * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection; WorldDirection = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection; WorldUp = currentHost.Tracks[TrackIndex].Elements[i].WorldUp; WorldSide = currentHost.Tracks[TrackIndex].Elements[i].WorldSide; CurveRadius = 0.0; } // cant if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1) { float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition); if (t < 0.0) { t = 0.0f; } else if (t > 1.0) { t = 1.0f; } float t2 = t * t; float t3 = t2 * t; CurveCant = (2.0f * t3 - 3.0f * t2 + 1.0f) * currentHost.Tracks[TrackIndex].Elements[i].CurveCant + (t3 - 2.0f * t2 + t) * currentHost.Tracks[TrackIndex].Elements[i].CurveCantTangent + (-2.0f * t3 + 3.0f * t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCant + (t3 - t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCantTangent; CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius; } else { CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant; } } else { WorldPosition = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition; WorldDirection = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection; WorldUp = currentHost.Tracks[TrackIndex].Elements[i].WorldUp; WorldSide = currentHost.Tracks[TrackIndex].Elements[i].WorldSide; CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius; CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant; } } else { if (db != 0.0) { CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius != 0.0 ? currentHost.Tracks[TrackIndex].Elements[i].CurveRadius : 0.0; if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1) { float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition); if (t < 0.0) { t = 0.0f; } else if (t > 1.0) { t = 1.0f; } float t2 = t * t; float t3 = t2 * t; CurveCant = (2.0f * t3 - 3.0f * t2 + 1.0f) * currentHost.Tracks[TrackIndex].Elements[i].CurveCant + (t3 - 2.0f * t2 + t) * currentHost.Tracks[TrackIndex].Elements[i].CurveCantTangent + (-2.0f * t3 + 3.0f * t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCant + (t3 - t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCantTangent; } else { CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant; } } else { CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius; CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant; } } AdhesionMultiplier = currentHost.Tracks[TrackIndex].Elements[i].AdhesionMultiplier; RainIntensity = currentHost.Tracks[TrackIndex].Elements[i].RainIntensity; SnowIntensity = currentHost.Tracks[TrackIndex].Elements[i].SnowIntensity; //Pitch added for Plugin Data usage //Mutliply this by 1000 to get the original value Pitch = currentHost.Tracks[TrackIndex].Elements[i].Pitch * 1000; // inaccuracy if (AddTrackInaccuracy) { float x, y, c; if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1) { float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition); if (t < 0.0) { t = 0.0f; } else if (t > 1.0) { t = 1.0f; } float x1, y1, c1; float x2, y2, c2; currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i].CsvRwAccuracyLevel, out x1, out y1, out c1); currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i + 1].CsvRwAccuracyLevel, out x2, out y2, out c2); x = (1.0f - t) * x1 + t * x2; y = (1.0f - t) * y1 + t * y2; c = (1.0f - t) * c1 + t * c2; } else { currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i].CsvRwAccuracyLevel, out x, out y, out c); } WorldPosition += (float)x * WorldSide + (float)y * WorldUp; CurveCant += c; CantDueToInaccuracy = c; } else { CantDueToInaccuracy = 0.0; } // events CheckEvents(i, System.Math.Sign(db - da), da, db); //Update the odometer if (TrackPosition != NewTrackPosition) { //HACK: Reset the odometer if we've moved more than 10m this frame if (System.Math.Abs(NewTrackPosition - TrackPosition) > 10) { Odometer = 0; } else { Odometer += NewTrackPosition - TrackPosition; } } // finish TrackPosition = NewTrackPosition; LastTrackElement = i; }
public Ray (Vector3 position, Vector3 direction) { Position = position; Direction = direction.Normalized(); }
/// <summary> /// /// </summary> /// <param name="targetID"></param> /// <param name="attackerID"></param> /// <param name="damage"></param> /// <param name="kickImpulse"></param> /// <param name="kickPoint"></param> /// <param name="damageType"></param> public override bool Damage(uint targetID, uint attackerID, short damage, Vector3 kickImpulse, Vector3 kickPoint, DamageType damageType) { if (damage <= 0) { return(false); } var c = controller; var e = Entity; c.SupportFinder.ClearSupportData(); var i = MathConverter.Convert(kickImpulse); var p = MathConverter.Convert(kickPoint); c.Body.ApplyImpulse(p, i); /************************************************** * * 1. Accumulate damage and emit FX according to * maximum inflicted damage. * Probably we have to add new controller stage * for FX processing (e.g. Update and UpdateFX). * * 2. Do not scream at each damage. * Screams should not overlap! * **************************************************/ // // calc health : // var health = e.GetItemCount(Inventory.Health); health -= damage; var dir = kickImpulse.Normalized(); if (health > 75) { World.SpawnFX("PlayerPain25", targetID, kickPoint, dir); } else if (health > 50) { World.SpawnFX("PlayerPain50", targetID, kickPoint, dir); } else if (health > 25) { World.SpawnFX("PlayerPain75", targetID, kickPoint, dir); } else if (health > 0) { World.SpawnFX("PlayerPain100", targetID, kickPoint, dir); } else if (health > -25) { World.SpawnFX("PlayerDeath", targetID, e.Position, dir); } else { World.SpawnFX("PlayerDeathMeat", targetID, e.Position, kickImpulse, dir); } if (health <= 0) { World.Kill(targetID); return(true); } e.SetItemCount(Inventory.Health, health); return(false); }
/// <summary> /// Sets the target and current rotation points of the entity to a set of yaw, pitch, and /// roll values extracted from a direction vector. The rotation itself occurs in the /// Update method. /// </summary> /// <param name="direction">A vector representing the direction to face.</param> /// <param name="roll">The angle in degrees to rotate to around the Z axis.</param> void RotateImmediate(Vector3 direction, float roll) { Vector3 vec = direction.Normalized(); float yawDot = Vector3.Dot(vec, Vector3.UnitZ); float pitchDot = Vector3.Dot(vec, Vector3.UnitY); float yaw = 1.0F / (float)System.Math.Cos(yawDot); float pitch = 1.0F / (float)System.Math.Cos(pitchDot); _Yaw = yaw; _Pitch = pitch; _Roll = roll; _TargetYaw = yaw; _TargetPitch = pitch; _TargetRoll = roll; }
public Vector3 Move(Vector3 Momentum, float Delta, int MaxSlideCount, float MaxAngle, float Snap) { Vector3 Movement = Momentum * Delta; if (Momentum.y <= 0) { Vector3 OriginalTranslation = Translation; var SnapVec = new Vector3(0, (-Snap - 0.1f) * Delta, 0); KinematicCollision SnapCollision = MoveAndCollide(SnapVec); if (SnapCollision != null && Acos(SnapCollision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle)) { float TargetHLength = Movement.Flattened().Length(); Movement = Movement.Slide(SnapCollision.Normal); float NewHLength = Movement.Flattened().Length(); if (TargetHLength != 0 && NewHLength != 0) //Protect against division by zero { Movement *= TargetHLength / Movement.Flattened().Length(); } OnFloor = true; if (Momentum.Flattened().Length() <= 0.5f) { Translation = OriginalTranslation; Momentum.y = 0; //On floor so zero out vertical momentum return(Momentum); } } else { Translation = OriginalTranslation; OnFloor = false; } } else { OnFloor = false; } int SlideCount = 0; float Traveled = 0f; while (SlideCount <= MaxSlideCount) { Movement = Movement.Normalized() * (Movement.Length() - Traveled); KinematicCollision Collision = MoveAndCollide(Movement); if (Collision == null) { break; //No collision, reached destination } Traveled += Collision.Travel.Length(); if (Traveled >= Movement.Length()) { break; //Reached destination } SlideCount += 1; Movement = Movement.Slide(Collision.Normal); if (Acos(Collision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle)) { OnFloor = true; } else { Momentum = Momentum.Slide(Collision.Normal); } } if (OnFloor) { Momentum.y = 0; //On floor so zero out vertical momentum } return(Momentum); }
public void CreateFromPanorama(string file) { int texSize = 1024; var src = new ImageTexture(file); ImageTexture Create(int faceIndex) { var data = new Byte[texSize * texSize * 3]; void SetPixel(int u, int v, Color32 color) { var p = texSize * 3 * v + u * 3; data[p] = (byte)(color.r * 255 + 0.5f); data[p + 1] = (byte)(color.g * 255 + 0.5f); data[p + 2] = (byte)(color.b * 255 + 0.5f); } Vector3[] vDirA = new Vector3[4]; if (faceIndex == FACE_FRONT) { vDirA[0] = new Vector3(-1.0f, -1.0f, -1.0f); vDirA[1] = new Vector3(1.0f, -1.0f, -1.0f); vDirA[2] = new Vector3(-1.0f, 1.0f, -1.0f); vDirA[3] = new Vector3(1.0f, 1.0f, -1.0f); } else if (faceIndex == FACE_BACK) { vDirA[0] = new Vector3(1.0f, -1.0f, 1.0f); vDirA[1] = new Vector3(-1.0f, -1.0f, 1.0f); vDirA[2] = new Vector3(1.0f, 1.0f, 1.0f); vDirA[3] = new Vector3(-1.0f, 1.0f, 1.0f); } else if (faceIndex == FACE_LEFT) { vDirA[0] = new Vector3(1.0f, -1.0f, -1.0f); vDirA[1] = new Vector3(1.0f, -1.0f, 1.0f); vDirA[2] = new Vector3(1.0f, 1.0f, -1.0f); vDirA[3] = new Vector3(1.0f, 1.0f, 1.0f); } else if (faceIndex == FACE_RIGHT) { vDirA[0] = new Vector3(-1.0f, -1.0f, 1.0f); vDirA[1] = new Vector3(-1.0f, -1.0f, -1.0f); vDirA[2] = new Vector3(-1.0f, 1.0f, 1.0f); vDirA[3] = new Vector3(-1.0f, 1.0f, -1.0f); } else if (faceIndex == FACE_UP) { vDirA[0] = new Vector3(-1.0f, 1.0f, -1.0f); vDirA[1] = new Vector3(1.0f, 1.0f, -1.0f); vDirA[2] = new Vector3(-1.0f, 1.0f, 1.0f); vDirA[3] = new Vector3(1.0f, 1.0f, 1.0f); } else if (faceIndex == FACE_DOWN) { vDirA[0] = new Vector3(-1.0f, -1.0f, 1.0f); vDirA[1] = new Vector3(1.0f, -1.0f, 1.0f); vDirA[2] = new Vector3(-1.0f, -1.0f, -1.0f); vDirA[3] = new Vector3(1.0f, -1.0f, -1.0f); } Vector3 rotDX1 = (vDirA[1] - vDirA[0]) / (float)texSize; Vector3 rotDX2 = (vDirA[3] - vDirA[2]) / (float)texSize; float dy = 1.0f / (float)texSize; float fy = 0.0f; for (int y = 0; y < texSize; y++) { Vector3 xv1 = vDirA[0]; Vector3 xv2 = vDirA[2]; for (int x = 0; x < texSize; x++) { Vector3 v = ((xv2 - xv1) * fy) + xv1; v = v.Normalized(); SetPixel(x, y, Spherical(v)); xv1 += rotDX1; xv2 += rotDX2; } fy += dy; } return(new ImageTexture(data, texSize, texSize)); } Color32 Spherical(Vector3 vDir) { float theta = Mathf.Atan2(vDir.z, vDir.x); float phi = Mathf.Acos(vDir.y); var m_direction = 0; theta += m_direction * Mathf.PI / 180.0f; while (theta < -Mathf.PI) { theta += Mathf.PI + Mathf.PI; } while (theta > Mathf.PI) { theta -= Mathf.PI + Mathf.PI; } float dx = theta / Mathf.PI; float dy = phi / Mathf.PI; dx = dx * 0.5f + 0.5f; int px = (int)(dx * src.w); if (px < 0) { px = 0; } if (px >= src.w) { px = src.w - 1; } int py = (int)(dy * src.w); if (py < 0) { py = 0; } if (py >= src.w) { py = src.w - 1; } //Console.WriteLine(px+"-"+ (src.w - py - 1)+"--"+src.w+"-"+py); Color32 col = src.GetPixel(px, src.w - py - 1); return(col); } buffer[0] = Create(FACE_FRONT); buffer[1] = Create(FACE_UP); buffer[2] = Create(FACE_LEFT); buffer[3] = Create(FACE_BACK); buffer[4] = Create(FACE_DOWN); buffer[5] = Create(FACE_RIGHT); for (int i = 0; i < 6; i++) { buffer[i].Save("sky" + i); } }
private RootEntity ParseTmd(BinaryReader reader, string fileTitle) { var flags = reader.ReadUInt32(); if (flags != 0 && flags != 1) { return(null); } var nObj = reader.ReadUInt32(); if (nObj == 0 || nObj > Program.MaxTMDObjects) { return(null); } var models = new List <ModelEntity>(); var objBlocks = new ObjBlock[nObj]; var objOffset = reader.BaseStream.Position; for (var o = 0; o < nObj; o++) { var vertTop = reader.ReadUInt32(); var nVert = reader.ReadUInt32(); var normalTop = reader.ReadUInt32(); var nNormal = reader.ReadUInt32(); var primitiveTop = reader.ReadUInt32(); var nPrimitive = reader.ReadUInt32(); var scale = reader.ReadInt32(); if (flags == 0) { vertTop += (uint)objOffset; normalTop += (uint)objOffset; primitiveTop += (uint)objOffset; } if (nPrimitive > Program.MaxTMDPrimitives) { return(null); } objBlocks[o] = new ObjBlock { VertTop = vertTop, NVert = nVert, NormalTop = normalTop, NNormal = nNormal, PrimitiveTop = primitiveTop, NPrimitive = nPrimitive, Scale = scale }; } for (uint o = 0; o < objBlocks.Length; o++) { var objBlock = objBlocks[o]; var vertices = new Vector3[objBlock.NVert]; if (Program.IgnoreTmdVersion && objBlock.VertTop < _offset) { return(null); } reader.BaseStream.Seek(objBlock.VertTop, SeekOrigin.Begin); for (var v = 0; v < objBlock.NVert; v++) { var vx = reader.ReadInt16(); var vy = reader.ReadInt16(); var vz = reader.ReadInt16(); var pad = reader.ReadInt16(); if (pad != 0) { if (Program.Debug) { Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{v}"); } } var vertex = new Vector3 { X = vx, Y = vy, Z = vz }; vertices[v] = vertex; } var normals = new Vector3[objBlock.NNormal]; if (Program.IgnoreTmdVersion && objBlock.NormalTop < _offset) { return(null); } reader.BaseStream.Seek(objBlock.NormalTop, SeekOrigin.Begin); for (var n = 0; n < objBlock.NNormal; n++) { var nx = TMDHelper.ConvertNormal(reader.ReadInt16()); var ny = TMDHelper.ConvertNormal(reader.ReadInt16()); var nz = TMDHelper.ConvertNormal(reader.ReadInt16()); var pad = reader.ReadInt16(); if (pad != 0) { if (Program.Debug) { Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{n}"); } } var normal = new Vector3 { X = nx, Y = ny, Z = nz }; normals[n] = normal.Normalized(); } var groupedTriangles = new Dictionary <uint, List <Triangle> >(); reader.BaseStream.Seek(objBlock.PrimitiveTop, SeekOrigin.Begin); if (Program.IgnoreTmdVersion && objBlock.PrimitiveTop < _offset) { return(null); } if (Program.Debug) { Program.Logger.WriteLine($"Primitive count:{objBlock.NPrimitive} {fileTitle}"); } for (var p = 0; p < objBlock.NPrimitive; p++) { var olen = reader.ReadByte(); var ilen = reader.ReadByte(); var flag = reader.ReadByte(); var mode = reader.ReadByte(); var offset = reader.BaseStream.Position; var packetStructure = TMDHelper.CreateTMDPacketStructure(flag, mode, reader, p); if (packetStructure != null) { TMDHelper.AddTrianglesToGroup(groupedTriangles, packetStructure, delegate(uint index) { if (index >= vertices.Length) { if (Program.IgnoreTmdVersion) { return(new Vector3(index, 0, 0)); } Program.Logger.WriteErrorLine("Vertex index error : " + fileTitle); throw new Exception("Vertex index error: " + fileTitle); } return(vertices[index]); }, delegate(uint index) { if (index >= normals.Length) { if (Program.IgnoreTmdVersion) { return(new Vector3(index, 0, 0)); } Program.Logger.WriteErrorLine("Vertex index error: " + fileTitle); throw new Exception("Vertex index error: " + fileTitle); } return(normals[index]); }); } var newOffset = offset + ilen * 4; if (Program.IgnoreTmdVersion && newOffset < _offset) { return(null); } reader.BaseStream.Seek(newOffset, SeekOrigin.Begin); } foreach (var kvp in groupedTriangles) { var triangles = kvp.Value; if (triangles.Count > 0) { var model = new ModelEntity { Triangles = triangles.ToArray(), TexturePage = kvp.Key, TMDID = o }; models.Add(model); } } } if (models.Count > 0) { var entity = new RootEntity(); foreach (var model in models) { model.ParentEntity = entity; } entity.ChildEntities = models.ToArray(); entity.ComputeBounds(); return(entity); } return(null); }
public FPlane(Vector3 normal, Vector3 pointOnPlane) { Normal = normal.Normalized(); Distance = -Vector3.Dot(normal, pointOnPlane); }
public void updateExecution(float timeElapsed) { if (timeElapsed <= 0f) { return; } var mParams = _missile.cluster.parameters; var target = _missile.cluster.target; // basic proportional navigation. see wikipedia Vector3 Vr = target.velocity - _missile.velocity; Vector3 R = target.position - _missile.position; Vector3 omega = Vector3.Cross(R, Vr) / R.LengthSquared; Vector3 latax = mParams.pursuitNavigationGain * Vector3.Cross(Vr, omega); if (mParams.pursuitAugmentedPN == true) { // this code is not tested as there are currently no targets with well defined accelerations Vector3 losDir = R.Normalized(); float targetAccLos = Vector3.Dot(target.acceleration, losDir); Vector3 targetLatAx = target.acceleration - targetAccLos * losDir; latax += mParams.pursuitNavigationGain * targetLatAx / 2f; } _missile._lataxDebug = latax; // apply latax var oldVelMag = _missile.velocity.LengthFast; _missile.velocity += latax * timeElapsed; float tempVelMag = _missile.velocity.LengthFast; if (oldVelMag != 0f) { float r = tempVelMag / oldVelMag; if (r > 1f) { _missile.velocity /= r; } } if (mParams.pursuitHitTimeCorrection) { // apply pursuit hit time correction float dist = R.LengthFast; if (dist != 0f) { Vector3 targetDir = R / dist; float v0 = -Vector3.Dot(Vr, targetDir); float t = _missile.cluster.timeToHit; float correctionAccMag = 2f * (dist - v0 * t) / t / t; Vector3 corrAcc = correctionAccMag * targetDir; _missile.velocity += corrAcc * timeElapsed; _missile._hitTimeCorrAccDebug = corrAcc; } } else { // hit time correction inactive. allow accelerating to achieve optimal velocity or forever oldVelMag = _missile.velocity.LengthFast; float velDelta = mParams.pursuitMaxAcc * timeElapsed; float newVelMag = Math.Min(oldVelMag + velDelta, mParams.pursuitMaxVelocity); if (oldVelMag != 0f) { _missile.velocity *= (newVelMag / oldVelMag); } } // make visual direction "lean into" velocity Vector3 axis; float angle; OpenTKHelper.neededRotation(_missile.visualDirection, _missile.velocity.Normalized(), out axis, out angle); float abs = Math.Abs(angle); if (abs > mParams.pursuitVisualRotationRate && abs > 0f) { angle = angle / abs * mParams.pursuitVisualRotationRate; } Quaternion quat = Quaternion.FromAxisAngle(axis, angle); _missile.visualDirection = Vector3.Transform(_missile.visualDirection, quat); }
public FRay(Vector3 startPosition, Vector3 direction) { StartPosition = startPosition; Direction = direction.Normalized(); }
public void Normalize() { Vector3 v1 = new Vector3(-10.5f, 0.2f, 1000.0f); Vector3 v2 = new Vector3(-10.5f, 0.2f, 1000.0f); v1.Normalize(); var expectedResult = new Vector3(-0.0104994215f, 0.000199988979f, 0.999944866f); Assert.That(expectedResult, Is.EqualTo(v1).Using(Vector3Comparer.Epsilon)); var normalizedV2 = Vector3.Normalize(v2); Assert.That(expectedResult, Is.EqualTo(normalizedV2).Using(Vector3Comparer.Epsilon)); Assert.That(expectedResult, Is.EqualTo(v2.Normalized()).Using(Vector3Comparer.Epsilon)); Assert.That(expectedResult, Is.Not.EqualTo(v2).Using(Vector3Comparer.Epsilon)); }
protected void moveShips(float timeElapsed) { if (timeElapsed <= 0f) { return; } // make the target drone move from side to side localTime += timeElapsed; //localTime += timeElapsed * 0.3f; Vector3 pos = targetDrone.Pos; pos.Z = 30f * (float)Math.Sin(localTime); targetDrone.Pos = pos; // make the vandal ship orbit missile target Vector3 desiredPos; Vector3 desiredDir; float angle = localTime * 0.5f; //float angle = localTime * 0.01f; #if true float desiredXOffset = 100f * (float)Math.Cos(angle); float desiredYOffset = 20f * (float)Math.Sin(angle * 0.77f); float desiredZOffset = 80f * (float)Math.Sin(angle * 0.88f); #else float desiredXOffset = 100f * (float)Math.Cos(angle); float desiredYOffset = 100f * (float)Math.Sin(angle); float desiredZOffset = 0f; #endif Vector3 desiredOffset = new Vector3(desiredXOffset, desiredYOffset, desiredZOffset); var target = getTargetObject(); if (missileLauncher != MissileLaunchers.VandalShip || target == null || target == vandalShip) { desiredPos = new Vector3(100f, 0f, 0f); desiredDir = -Vector3.UnitX; } else if (target == main3dScene.ActiveCamera) { desiredPos = main3dScene.ActiveCamera.Pos + -main3dScene.ActiveCamera.Dir * 300f; Quaternion cameraOrient = OpenTKHelper.neededRotationQuat(Vector3.UnitZ, -main3dScene.ActiveCamera.Up); desiredPos += Vector3.Transform(desiredOffset * 0.1f, cameraOrient); desiredDir = (target.Pos - vandalShip.Pos).Normalized(); } else { //float desiredZOffset = 5f * (float)Math.Sin(angle + 0.2f); desiredPos = target.Pos + desiredOffset; desiredDir = (target.Pos - vandalShip.Pos).Normalized(); } Vector3 desiredMotion = desiredPos - vandalShip.Pos; const float vel = 100f; float displacement = vel * timeElapsed; Vector3 vandalNewPos; if (displacement > desiredMotion.LengthFast) { vandalNewPos = desiredPos; } else { vandalNewPos = vandalShip.Pos + desiredMotion.Normalized() * displacement; } vandalVelocity = (vandalNewPos - vandalShip.Pos) / timeElapsed; vandalShip.Pos = vandalNewPos; Quaternion vandalOrient = OpenTKHelper.neededRotationQuat(Vector3.UnitZ, desiredDir); vandalShip.Orient(desiredDir, Vector3.Transform(Vector3.UnitY, vandalOrient)); }
static TriangleIntersection RayIntersectsTriangle(Ray r, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 n0, Vector3 n1, Vector3 n2) { Vector3 e1, e2, h, s, q; float a, f, u, v; e1 = v1 - v0; e2 = v2 - v0; h = Vector3.Cross(r.dir, e2); a = Vector3.Dot(e1, h); if (a > -0.00001 && a < 0.00001) { return(new TriangleIntersection(false)); } f = 1 / a; s = r.pos - v0; u = f * (Vector3.Dot(s, h)); if (u < 0.0 || u > 1.0) { return(new TriangleIntersection(false)); } q = Vector3.Cross(s, e1); v = f * Vector3.Dot(r.dir, q); if (v < 0.0 || u + v > 1.0) { return(new TriangleIntersection(false)); } // at this stage we can compute t to find out where // the intersection point is on the line float t = f * Vector3.Dot(e2, q); Vector3 normal = new Vector3(); if (t <= 0.00001) // ray intersection { return(new TriangleIntersection(false, t, normal)); } Vector3 p = r.pos + r.dir * t; float area; float w0, w1, w2; area = edgeFunction(v0, v1, v2, 0); w0 = edgeFunction(v1, v2, p, 0); w1 = edgeFunction(v2, v0, p, 0); w2 = edgeFunction(v0, v1, p, 0); w0 /= area; w1 /= area; w2 /= area; if (float.IsNaN(w0) || float.IsNaN(w1) || float.IsNaN(w2) || float.IsInfinity(w0) || float.IsInfinity(w1) || float.IsInfinity(w2)) { area = edgeFunction(v0, v1, v2, 1); w0 = edgeFunction(v1, v2, p, 1); w1 = edgeFunction(v2, v0, p, 1); w2 = edgeFunction(v0, v1, p, 1); w0 /= area; w1 /= area; w2 /= area; if (float.IsNaN(w0) || float.IsNaN(w1) || float.IsNaN(w2) || float.IsInfinity(w0) || float.IsInfinity(w1) || float.IsInfinity(w2)) { area = edgeFunction(v0, v1, v2, 2); w0 = edgeFunction(v1, v2, p, 2); w1 = edgeFunction(v2, v0, p, 2); w2 = edgeFunction(v0, v1, p, 2); w0 /= area; w1 /= area; w2 /= area; } } normal[0] = w0 * n0[0] + w1 * n1[0] + w2 * n2[0]; normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1]; normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2]; return(new TriangleIntersection(true, t, normal.Normalized())); }
public static bool CheckAndCleanMeshIssues(ref List <DTriangle> triangle, List <Vector3> vertex, bool removeSmallInvalidTriangles, out string issues) { const float kLengthEpsilon = 0.0001f; const float kDotEpsilon = 0.99999f; const double kUVEpsilon = 0.000001; const double kMaxAreaForAutoRemoval = 0.0003; Vector3[] verts = new Vector3[3]; bool result = false; System.Text.StringBuilder builder = new System.Text.StringBuilder(); List <BadTriangle> badTriangleIndices = new List <BadTriangle>(); foreach (int triIdx in Enumerable.Range(0, triangle.Count)) { var tri = triangle[triIdx]; if (tri.vert.Length != 3) { builder.AppendFormat("-- Polygon is not 3 verts\n"); result = true; badTriangleIndices.Add(new BadTriangle() { index = triIdx, reason = BadTriangleReason.ZeroArea }); continue; } for (int i = 0; i < 3; ++i) { verts[i] = vertex[tri.vert[i]]; } Vector3 edge0 = verts[0] - verts[1]; Vector3 edge1 = verts[2] - verts[1]; Vector3 edge2 = verts[0] - verts[2]; bool isZeroAreaTriangle = false; bool isBadUVTriangle = false; if (edge0.Length <= kLengthEpsilon) { builder.AppendFormat("-- triangle in polygon {3} edge0 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString()); isZeroAreaTriangle = true; } if (edge1.Length <= kLengthEpsilon) { builder.AppendFormat("-- triangle in polygon {3} edge1 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString()); isZeroAreaTriangle = true; } if (edge2.Length <= kLengthEpsilon) { builder.AppendFormat("-- triangle in polygon {3} edge2 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString()); isZeroAreaTriangle = true; } if (!isZeroAreaTriangle) { float edge_dot = Math.Abs(Vector3.Dot(edge0.Normalized(), edge1.Normalized())); if (edge_dot >= kDotEpsilon) { builder.AppendFormat("-- triangle has no area {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString()); isZeroAreaTriangle = true; } } // Check UVs to make sure there is a gradient Vector2 w1 = tri.tex_uv[0]; Vector2 w2 = tri.tex_uv[1]; Vector2 w3 = tri.tex_uv[2]; double s1 = w2.X - w1.X; double s2 = w3.X - w1.X; double t1 = w2.Y - w1.Y; double t2 = w3.Y - w1.Y; double den = (s1 * t2 - s2 * t1); if (Math.Abs(den) <= kUVEpsilon) { double area = CalculateTriangleArea(edge0, edge1, edge2); if (area <= kMaxAreaForAutoRemoval) { builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (REMOVING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area); isZeroAreaTriangle = true; } else { builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (FIXING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area); isBadUVTriangle = true; } } if (isZeroAreaTriangle) { result = true; // Calculate the area of the triangle double triangleArea = CalculateTriangleArea(edge0, edge1, edge2); if (triangleArea < kMaxAreaForAutoRemoval) { badTriangleIndices.Add(new BadTriangle() { index = triIdx, reason = BadTriangleReason.ZeroArea }); } } else if (isBadUVTriangle) { result = true; badTriangleIndices.Add(new BadTriangle() { index = triIdx, reason = BadTriangleReason.BadUV }); } } if (removeSmallInvalidTriangles && badTriangleIndices.Count > 0) { List <DTriangle> newTriangles = new List <DTriangle>(); int numRemoved = 0; int numBadTriangles = badTriangleIndices.Count; int badIndex = 0; foreach (int srcTriIndex in Enumerable.Range(0, triangle.Count)) { if (badIndex < numBadTriangles && badTriangleIndices[badIndex].index == srcTriIndex) { bool skipThis = false; switch (badTriangleIndices[badIndex++].reason) { case BadTriangleReason.ZeroArea: { skipThis = true; } break; case BadTriangleReason.BadUV: { DTriangle tri = triangle[srcTriIndex]; tri.tex_uv[1] = tri.tex_uv[1] + new Vector2(0.1f, 0.1f); tri.tex_uv[2] = tri.tex_uv[2] - new Vector2(0.1f, 0.1f); } break; } if (skipThis) { ++numRemoved; continue; } } newTriangles.Add(triangle[srcTriIndex]); } triangle = newTriangles; builder.AppendFormat("Removed {0} triangles\n", numRemoved); } issues = builder.ToString(); return(result); }
protected override void onClickOculusTrigger(ref VREvent_t vrEvent) { primaryDeviceIndex = vrEvent.trackedDeviceIndex; if (currentState != State.READY || targetPRhObjID == Guid.Empty) { return; } pointOnObjRef = new ObjRef(targetPRhObjID); //chage to only raycasting to the obj where we draw, if not snap to the origin if (!(projectP.X == 0 && projectP.Y == 0 && projectP.Z == 0)) { rayCastingObjs.Clear(); rayCastingObjs.Add(pointOnObjRef); } //testing Vector3 projectPVR = UtilOld.platformToVRPoint(ref mScene, UtilOld.RhinoToOpenTKPoint(projectP)); mScene.iPointList.Add(UtilOld.platformToVRPoint(ref mScene, projectPVR)); //not use at the current version, point is VR coordinate pointsList.Add(projectP); //render edit points in VR Geometry.Geometry geo = new Geometry.DrawPointMarker(new Vector3(0, 0, 0)); Material.Material m = new Material.SingleColorMaterial(0, 1, 0, 1); SceneNode editPointSN; UtilOld.MarkPointVR(ref mScene, projectPVR, ref geo, ref m, out editPointSN); pointMarkers.Add(editPointSN); //TODO-hide two other design plane if (pointMarkers.Count == 1) { if (pointOnObjRef != null && drawnType == DrawnType.Plane) { if (!(projectP.X == 0 && projectP.Y == 0 && projectP.Z == 0)) { UtilOld.hideOtherPlanes(ref mScene, pointOnObjRef.Object().Attributes.Name); } computeContourCurve(); } //TODO- how to find the curvePlane on the surface like teapot body, using the normal of first point? //do we need to use different ways for patch surface and other generated surface else if (pointOnObjRef != null && drawnType == DrawnType.Surface) { computeContourCurve(); } } if (maxNumPoint == pointMarkers.Count) { //Assume we always can find a curvePlane sicnce we use a huge tolerance NurbsCurve modelcurve = null; Brep modelBrep; string modelName = ""; if (shapeType == ShapeType.Circle) { float radius = (float)Math.Sqrt(Math.Pow(pointsList[1].X - pointsList[0].X, 2) + Math.Pow(pointsList[1].Y - pointsList[0].Y, 2) + Math.Pow(pointsList[1].Z - pointsList[0].Z, 2)); Circle circle = new Rhino.Geometry.Circle(curvePlane, pointsList[0], radius); modelcurve = circle.ToNurbsCurve(); modelName = "Circle"; } else if (shapeType == ShapeType.Rect) { Vector3 rectDiagonalV = new Vector3((float)(pointsList[0].X - pointsList[1].X), (float)(pointsList[0].Y - pointsList[1].Y), (float)(pointsList[0].Z - pointsList[1].Z)); float lenDiagonal = rectDiagonalV.Length; Vector3 rectLeftTop = new Vector3((float)pointsList[0].X, (float)pointsList[0].Y, (float)pointsList[0].Z) + lenDiagonal * rectDiagonalV.Normalized(); Point3d topLeftP = new Point3d(rectLeftTop.X, rectLeftTop.Y, rectLeftTop.Z); Rectangle3d rect = new Rectangle3d(curvePlane, topLeftP, pointsList[1]); //using top-left cornel and bottom right //Rectangle3d rect = new Rectangle3d(curvePlane, pointsList[0], pointsList[1]); modelcurve = rect.ToNurbsCurve(); modelName = "Rect"; } /* * Brep[] shapes = Brep.CreatePlanarBreps(modelcurve); * modelBrep = shapes[0]; * Guid guid = Util.addRhinoObjectSceneNode(ref mScene, ref modelBrep, ref profile_m, modelName, out renderObjSN); */ //generate new curveOnObj for mvoingPlane cases sicne and move the XYZPlanes to origial positons if (drawnType == DrawnType.Plane) { Rhino.Geometry.Vector3d newNormal = new Rhino.Geometry.Vector3d();; Point3d newOrigin = new Point3d(); String planeName = pointOnObjRef.Object().Attributes.Name; Point3d planeOrigin = pointOnObjRef.Object().Geometry.GetBoundingBox(true).Center; if (planeName.Contains("planeXY")) { newNormal = new Rhino.Geometry.Vector3d(0, 0, 1); newOrigin = new Point3d(0, 0, planeOrigin.Z); } else if (planeName.Contains("planeYZ")) { newNormal = new Rhino.Geometry.Vector3d(1, 0, 0); newOrigin = new Point3d(planeOrigin.X, 0, 0); } else if (planeName.Contains("planeXZ")) { newNormal = new Rhino.Geometry.Vector3d(0, 1, 0); newOrigin = new Point3d(0, planeOrigin.Y, 0); } Plane newPlane = new Plane(newOrigin, newNormal); int size = 240; PlaneSurface plane_surface = new PlaneSurface(newPlane, new Interval(-size, size), new Interval(-size, size)); Brep newPlaneBrep = Brep.CreateFromSurface(plane_surface); Guid newPlaneID = UtilOld.addRhinoObject(ref mScene, ref newPlaneBrep, "MoveP"); //might be better to use Replace(), just need to be careful about the referece count pointOnObjRef = null; pointOnObjRef = new ObjRef(newPlaneID); modelcurve.SetUserString(CurveData.CurveOnObj.ToString(), newPlaneID.ToString()); modelcurve.SetUserString(CurveData.PlaneOrigin.ToString(), newPlane.Origin.ToString()); modelcurve.SetUserString(CurveData.PlaneNormal.ToString(), newPlane.Normal.ToString()); } else if (drawnType == DrawnType.Surface) { modelcurve.SetUserString(CurveData.CurveOnObj.ToString(), pointOnObjRef.ObjectId.ToString()); modelcurve.SetUserString(CurveData.PlaneOrigin.ToString(), curvePlane.Origin.ToString()); modelcurve.SetUserString(CurveData.PlaneNormal.ToString(), curvePlane.Normal.ToString()); } mScene.iCurveList.Add(modelcurve); //call next interaction in the chain afterCurveCount = mScene.iCurveList.Count; mScene.pushInteractionFromChain(); currentState = State.READY; } }
protected override void OnRenderFrame(FrameEventArgs e) { #region Shader updates float renderTime = (float)e.Time; //TODO e.Time accuracy Shader.diffuseShaderCompiled.SetUniform("worldTime", worldTime); Shader.unlitShaderCompiled.SetUniform("worldTime", worldTime); Shader.wireframeShaderCompiled.SetUniform("worldTime", worldTime); Shader.collisionShaderCompiled.SetUniform("worldTime", worldTime); Shader.hudShaderCompiled.SetUniform("worldTime", worldTime); Shader.fboShaderCompiled.SetUniform("worldTime", worldTime); Shader.blurShaderCompiled.SetUniform("worldTime", worldTime); Shader.crtShaderCompiled.SetUniform("worldTime", worldTime); Shader.ditherShaderCompiled.SetUniform("worldTime", worldTime); Shader.diffuseShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration); Shader.unlitShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration); Shader.wireframeShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration); Shader.collisionShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration); Vector3 velocityDelta = Camera.Instance.velocity - smoothedVelocity; smoothedVelocity += velocityDelta - Vector3.Divide(velocityDelta, (float)Math.Pow(smoothFactor, renderTime)); //TODO: time dilation v = smoothedVelocity.Length; b = v / c; lf = 1f / (float)Math.Sqrt(1.0 - b * b); Shader.diffuseShaderCompiled.SetUniform("bW", b); Shader.unlitShaderCompiled.SetUniform("bW", b); Shader.wireframeShaderCompiled.SetUniform("bW", b); Shader.collisionShaderCompiled.SetUniform("bW", b); Vector3 vDir = smoothedVelocity.Normalized(); Shader.diffuseShaderCompiled.SetUniform("vdirW", vDir); Shader.unlitShaderCompiled.SetUniform("vdirW", vDir); Shader.wireframeShaderCompiled.SetUniform("vdirW", vDir); Shader.collisionShaderCompiled.SetUniform("vdirW", vDir); Shader.diffuseShaderCompiled.SetUniform("cpos", Camera.Instance.position); Shader.unlitShaderCompiled.SetUniform("cpos", Camera.Instance.position); Shader.wireframeShaderCompiled.SetUniform("cpos", Camera.Instance.position); Shader.collisionShaderCompiled.SetUniform("cpos", Camera.Instance.position); Matrix4 cRot = Matrix4.CreateFromQuaternion(Camera.Instance.derivedOrientation); Shader.diffuseShaderCompiled.SetUniform("crot", cRot); Shader.unlitShaderCompiled.SetUniform("crot", cRot); Shader.wireframeShaderCompiled.SetUniform("crot", cRot); Shader.collisionShaderCompiled.SetUniform("crot", cRot); #endregion #region 3D #region First FBO pass UpdateViewport(); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); // Enable rendering to FBO GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, depthRenderbuffer); GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fboHandle); GL.DrawBuffer((DrawBufferMode)FramebufferAttachment.ColorAttachment0Ext); GL.PushAttrib(AttribMask.ViewportBit); GL.Viewport(0, 0, Width, Height); // Clear previous frame GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // Geometry render passes for(int i = 0; i < amountOfRenderPasses; i++) { RootNode.Instance.StartRender(i); } for(int i = 0; i < amountOfRenderPasses; i++) { if(Camera.Instance.parent == null) { Camera.Instance.StartRender(i); } } // Focal depth float[] pixelData = new float[1]; GL.ReadPixels(Width / 2, Height / 2, 1, 1, PixelFormat.DepthComponent, PixelType.Float, pixelData); focalDistance = pixelData[0]; // Restore render settings GL.PopAttrib(); GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // return to visible framebuffer GL.DrawBuffer(DrawBufferMode.Back); GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, 0); GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); #endregion #region FBO render to back buffer & HUD GL.Color4(Color4.White); // 2D rendering settings GL.DepthMask(false); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.CullFace); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(0, ClientRectangle.Width, ClientRectangle.Height, 0, -1, 10); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); // GFX sader selection if(InputManager.IsKeyToggled(Key.Number3)) { if(InputManager.IsKeyToggled(Key.BackSpace)) { Shader.ssaoShaderCompiled.Enable(); Shader.ssaoShaderCompiled.SetUniform("tex", 0); Shader.ssaoShaderCompiled.SetUniform("depthTex", 1); Shader.ssaoShaderCompiled.SetUniform("focalDist", focalDistance); } else { Shader.blurShaderCompiled.Enable(); Shader.blurShaderCompiled.SetUniform("tex", 0); Shader.blurShaderCompiled.SetUniform("depthTex", 1); Shader.blurShaderCompiled.SetUniform("focalDist", focalDistance); } GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, depthTexture); } else { if(InputManager.IsKeyToggled(Key.Number4)) { GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, ditherTexture); Shader.ditherShaderCompiled.Enable(); Shader.ditherShaderCompiled.SetUniform("tex", 0); Shader.ditherShaderCompiled.SetUniform("ditherTex", 1); } else { GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, depthTexture); Shader.fboShaderCompiled.Enable(); Shader.fboShaderCompiled.SetUniform("tex", 0); Shader.fboShaderCompiled.SetUniform("depthTex", 1); } } // Render FBO quad GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, colorTexture); GL.Begin(PrimitiveType.Quads); GL.Color4(Color4.White); GL.TexCoord2(0, 1); GL.Vertex2(0, 0); GL.TexCoord2(0, 0); GL.Vertex2(0, Height); GL.TexCoord2(1, 0); GL.Vertex2(Width, Height); GL.TexCoord2(1, 1); GL.Vertex2(Width, 0); GL.End(); Shader.hudShaderCompiled.Enable(); Shader.hudShaderCompiled.SetUniform("tex", 0); // HUD render pass HudBase.Instance.StartRender(); // Return to 3D rendering settings GL.Color3(Color.White); GL.DepthMask(true); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Lighting); GL.Enable(EnableCap.CullFace); #endregion #endregion // Display the back buffer SwapBuffers(); }
public static Vector3 smoothNormal(Vector3 vector1, Vector3 vector2, Vector3 vector3, Vector3 vector4) { return(vector1.Normalized() + vector2.Normalized() + vector3.Normalized() + vector4.Normalized()); }
public ParticlesRingGenerator(ParticlesPlaneGenerator planeGenerator, Vector3 ringCenter, Vector3 up, float ringRadius, float sectionStart = 0.0f, float sectionEnd = (float)(2.0*Math.PI)) { m_ringCenter = ringCenter; m_ringZAxis = up.Normalized(); m_ringRadius = ringRadius; m_sectionStart = sectionStart; m_sectionEnd = sectionEnd; m_planeGenerator = planeGenerator; if (Math.Abs(m_ringZAxis.X) < c_eps && Math.Abs(m_ringZAxis.Y) < c_eps) { m_ringXAxis = new Vector3(1.0f, 0.0f, 0.0f); } else { m_ringXAxis = new Vector3(m_ringZAxis.Y, -m_ringZAxis.X, 0.0f); m_ringXAxis.Normalize(); } m_ringYAxis = Vector3.Cross(m_ringXAxis, m_ringZAxis); }
//Processes movement public void ProcessMovement(float delta) { //Sets the normal in a variable to calculate the dot product later if (GetFloorNormal() != Vector3.Zero) { Normal_vect = GetFloorNormal(); } else if (Floor_cast.GetCollisionNormal() != Vector3.Zero) { Normal_vect = Floor_cast.GetCollisionNormal(); } //Sets a redundant check to secure that the character isn't on the ground (and sets a fake normal that is perpendicular to the up vector) if (!Floor_cast.IsColliding()) { Normal_vect = Vector3.Forward; Floor_dect = false; } //Reset the redundant check to true if it detects it touched the floor (and sets a -10 gravity value) if (IsOnFloor()) { Floor_dect = true; Grav.y = -10; } //Sets the velocity of gravity if the check is negative if (!Floor_dect) { Grav.y -= 30.0f * delta; } //Sets the velocity vector (acceleration coming in the future) Velocity_vect = Direction_vect * 20; //If the dot product of the normalized normal and the Vector 3 that points downwards is -0.5 < or 0.5 > and the player presed jump (aka space) set a variable to jump and change the gravity if ((new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5 || new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5) && Input.IsActionPressed("Player_jump")) { Jumping = true; Grav.y = 10; } //If you were not jumping and you fell from a platform it resets the gravity to 0 for 1 frame if (Floor_dect_PFPS && !Floor_dect && !Jumping) { Grav.y = 0; } //If you were jumping and you touched the floor it reset jumping to false if (!Floor_dect_PFPS && Floor_dect && Jumping) { Jumping = false; } //If the dot product of the normalized normal and the Vector 3 that points downwards is not -0.5 < and not 0.5 > or the Vector_velocity isn't 0 or is jumping, it aplies the movement WITH gravity if (((!(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5) && !(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5)) || Velocity_vect != Vector3.Zero) || Jumping) { MoveAndSlide((Velocity_vect) + Grav, Vector3.Up, true); } Floor_dect_PFPS = Floor_dect; //If you touch the ceiling with a positive y value on gravity and you keep pressing jump you get ""grabed"" on the ceiling, else you bonk if (IsOnCeiling() && Grav.y > 0) { if (Input.IsActionPressed("Player_jump")) { Grav.y = 2; } else { Grav.y = 0; } } }
public Ray(Vector3 start, Vector3 direction, float distance) { this.Origin = start; this.Direction = direction.Normalized(); this.Distance = distance; }
// Super basic test public void ProcessMovement(FPSInput input, float delta) { _debugSb.Clear(); ApplyRotations(); //Console.WriteLine($"Buttons {input.buttons} delta {delta}"); Vector3 inputDir = new Vector3(); if (input.isBitOn(FPSInput.BitMoveForward)) { inputDir.z -= 1; } if (input.isBitOn(FPSInput.BitMoveBackward)) { inputDir.z += 1; } if (input.isBitOn(FPSInput.BitMoveLeft)) { inputDir.x -= 1; } if (input.isBitOn(FPSInput.BitMoveRight)) { inputDir.x += 1; } float mouseMoveX = 0; // horizontal turn float mouseMoveY = 0; // verticla turn if (input.isBitOn(FPSInput.BitLookLeft)) { mouseMoveX += KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookRight)) { mouseMoveX -= KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookUp)) { mouseMoveY += KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookDown)) { mouseMoveY -= KEYBOARD_TURN_DEGREES_PER_SECOND; } _yaw += mouseMoveX * delta; _pitch += mouseMoveY * delta; // convert desired move to world axes Transform t = _body.GlobalTransform; Vector3 forward = t.basis.z; Vector3 left = t.basis.x; Vector3 runPush = Vector3.Zero; runPush.x += forward.x * inputDir.z; runPush.z += forward.z * inputDir.z; runPush.x += left.x * inputDir.x; runPush.z += left.z * inputDir.x; runPush = runPush.Normalized(); // calculate horizontal move independently. Vector3 lastVel = CalcLastFlatVelocity(_lastMove, _lastDelta); Vector3 horizontal = CalcVelocityQuakeStyle( lastVel, runPush, MOVE_SPEED, delta, true); _velocity.x = horizontal.x; _velocity.z = horizontal.z; // Apply external push Vector3 prevPosition = t.origin; // Move! _body.MoveAndSlide(_velocity); // record move info for next frame _lastMove = _body.GlobalTransform.origin - prevPosition; _lastDelta = delta; _debugSb.Append($"FPS: {Engine.GetFramesPerSecond()}"); _debugSb.Append($"Pitch {_pitch}\nyaw {_yaw}\n"); _debugSb.Append($"Prev delta {_lastDelta}\n"); _debugSb.Append($"Prev move {_lastMove}\n"); _debugSb.Append($"Velocity {_velocity}\n"); _debugSb.Append($"Run push {runPush}\n"); _debugSb.Append($"Move spd {MOVE_SPEED} accel {MOVE_ACCELERATION}\n"); }
public void update(float timeElapsed) { _position += _velocity * timeElapsed; _timeElapsedTotal += timeElapsed; for (int i = 0; i < _delaysRemaining.Length; ++i) { if (_explosionsRemaining > 0 && _delaysRemaining [i] <= 0f) { float intensity = _chainParams.minIntensity + (float)rand.NextDouble() * (_chainParams.maxIntensity - _chainParams.minIntensity); double r = _chainParams.radiusMin + rand.NextDouble() * (_chainParams.radiusMax - _chainParams.radiusMin); double theta = 2.0 * Math.PI * rand.NextDouble(); double phi = Math.PI * (rand.NextDouble() - 0.5); double xy = r * Math.Cos(theta); Vector3 radialOffset = new Vector3 ( (float)(xy * Math.Cos(theta)), (float)(xy * Math.Sin(theta)), (float)(r * Math.Sin(phi))); Vector3 pos = _position + radialOffset; double spreadVelScale = _chainParams.spreadVelocityMin + rand.NextDouble() * (_chainParams.spreadVelocityMax - _chainParams.spreadVelocityMin); Vector3 vel = _velocity; if (radialOffset.LengthFast > 0f) { var radialDir = radialOffset.Normalized(); var radialVelOffset = (float)spreadVelScale * radialDir; pos += radialVelOffset * _timeElapsedTotal; vel += radialVelOffset ; } _em.showExplosion(_chainParams, intensity, pos, vel); _delaysRemaining [i] = _chainParams.minDelay + (float)rand.NextDouble() * (_chainParams.maxDelay - _chainParams.minDelay); --_explosionsRemaining; } _delaysRemaining [i] -= timeElapsed; } }
private int AddVertex(Vector3 p) { _points.Add(p.Normalized()); return(_index++); }
public Ray(Vector3 origin, Vector3 direction) { Origin = origin; Direction = direction.Normalized(); }
/// <summary> /// Returns the distance between the closest points on the segment and the sphere /// </summary> public static float SegmentSphere(Vector3 segmentA, Vector3 segmentB, Vector3 sphereCenter, float sphereRadius) { Vector3 segmentAToCenter = sphereCenter - segmentA; Vector3 fromAtoB = segmentB - segmentA; float segmentLength = fromAtoB.Length(); if (segmentLength < Geometry.Epsilon) { return(segmentAToCenter.Length() - sphereRadius); } Vector3 segmentDirection = fromAtoB.Normalized(); float centerProjection = segmentDirection.Dot(segmentAToCenter); if (centerProjection + sphereRadius < -Geometry.Epsilon || centerProjection - sphereRadius > segmentLength + Geometry.Epsilon) { // No intersection if (centerProjection < 0) { return(segmentAToCenter.Length() - sphereRadius); } return((sphereCenter - segmentB).Length() - sphereRadius); } float sqrDistanceToA = segmentAToCenter.LengthSquared(); float sqrDistanceToLine = sqrDistanceToA - centerProjection * centerProjection; float sqrDistanceToIntersection = sphereRadius * sphereRadius - sqrDistanceToLine; if (sqrDistanceToIntersection < -Geometry.Epsilon) { // No intersection if (centerProjection < -Geometry.Epsilon) { return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius); } if (centerProjection > segmentLength + Geometry.Epsilon) { return((sphereCenter - segmentB).Length() - sphereRadius); } return(Mathf.Sqrt(sqrDistanceToLine) - sphereRadius); } if (sqrDistanceToIntersection < Geometry.Epsilon) { if (centerProjection < -Geometry.Epsilon) { // No intersection return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius); } if (centerProjection > segmentLength + Geometry.Epsilon) { // No intersection return((sphereCenter - segmentB).Length() - sphereRadius); } // Point intersection return(0); } // Line intersection float distanceToIntersection = Mathf.Sqrt(sqrDistanceToIntersection); float distanceA = centerProjection - distanceToIntersection; float distanceB = centerProjection + distanceToIntersection; bool pointAIsAfterSegmentA = distanceA > -Geometry.Epsilon; bool pointBIsBeforeSegmentB = distanceB < segmentLength + Geometry.Epsilon; if (pointAIsAfterSegmentA && pointBIsBeforeSegmentB) { // Two points intersection return(0); } if (!pointAIsAfterSegmentA && !pointBIsBeforeSegmentB) { // The segment is inside, but no intersection distanceB = -(distanceB - segmentLength); return(distanceA > distanceB ? distanceA : distanceB); } bool pointAIsBeforeSegmentB = distanceA < segmentLength + Geometry.Epsilon; if (pointAIsAfterSegmentA && pointAIsBeforeSegmentB) { // Point A intersection return(0); } bool pointBIsAfterSegmentA = distanceB > -Geometry.Epsilon; if (pointBIsAfterSegmentA && pointBIsBeforeSegmentB) { // Point B intersection return(0); } // No intersection if (centerProjection < 0) { return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius); } return((sphereCenter - segmentB).Length() - sphereRadius); }
/// <summary> /// https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h#cl-651 /// </summary> public static Quaternion getRotationTo(Vector3 src, Vector3 dst, Vector3 fallbackAxis) { // Based on Stan Melax's article in Game Programming Gems Quaternion q = new Quaternion(); // Copy, since cannot modify local Vector3 v0 = src.Normalized(); Vector3 v1 = dst.Normalized(); float d = Vector3.Dot (v0, v1); // If dot == 1, vectors are the same if (d >= 1.0f) { return Quaternion.Identity; } if (d < (1e-6f - 1.0f)) { if (fallbackAxis != Vector3.Zero) { // rotate 180 degrees about the fallback axis q = Quaternion.FromAxisAngle (fallbackAxis, (float)Math.PI); } else { // Generate an axis Vector3 axis = Vector3.Cross(Vector3.UnitX, v0); if (axis.Length <= 0.001f) // pick another if colinear axis = Vector3.Cross(Vector3.UnitY, v0); axis.Normalize(); q = Quaternion.FromAxisAngle (axis, (float)Math.PI); } } else { float s = (float)Math.Sqrt( (1f+d)*2f ); float invs = 1f / s; Vector3 c = Vector3.Cross (v0, v1); q.X = c.X * invs; q.Y = c.Y * invs; q.Z = c.Z * invs; q.W = s * 0.5f; q.Normalize(); } return q; }
/// <summary> /// Is vector parallel to other vector? /// </summary> public static bool IsParallelTo(this Vector3 vector, Vector3 other, float tolerance = 1E-6f) { return(System.Math.Abs(1.0 - System.Math.Abs(vector.Normalized().Dot(other.Normalized()))) <= tolerance); }
//start at the highest, rightmost point. work anticlockwise. highest has priority public void CalcNormals(Vector3 a, Vector3 b, Vector3 c) { normals[0] = a.Normalized(); normals[1] = b.Normalized(); normals[2] = c.Normalized(); }
public static Quaternion ConstraintLookAt(StaticModel actor, Vector3 targetAbsRef, Vector3 upRelRef, Vector3 constraintAxisSelect) { Vector3 targetRelRef; //Transforming target into relative coordinates if child if (actor.IsChild) targetRelRef = Geometric.Quaternion_Rotate(actor.ParentModel.Orientation.Inverted(), targetAbsRef); else targetRelRef = new Vector3(targetAbsRef.X, targetAbsRef.Y, targetAbsRef.Z); // HACK INVERSION //targetRelRef = -targetRelRef; // //Make a non projected safe copy of relative target Vector3 targetRelRef_notConstraint = new Vector3(targetRelRef.X, targetRelRef.Y, targetRelRef.Z); /* //Project relative target to plane defined by constraint if (constraintAxisSelect.X != 0) targetRelRef.X = 0; else if (constraintAxisSelect.Y != 0) targetRelRef.Y = 0; else if (constraintAxisSelect.Z != 0) targetRelRef.Z = 0; */ //Normalizing constrainted relative target Vector3 eye = actor.PositionRelative; Vector3 up; Vector3 forward; if (actor.IsChild) { //Normalizing target and transforming it to local system forward = targetRelRef - actor.ParentModel.Position; up = Quaternion_Rotate(actor.OrientationRelative, upRelRef); } else { //Normalizing target.. local system is the same as world system forward = targetRelRef; up = upRelRef; } //Normalizing upVector (we are assuming it is expressed in local system) //Insert manual imprecision tilt to avoid singularity (if any!) float ciao = Vector3.Dot(targetRelRef_notConstraint.Normalized(), up); if (Vector3.Dot(targetRelRef_notConstraint.Normalized(), up) == 1) { forward.X = 0.001f; forward.Y = 0.001f; forward.Z = 0.001f; } //Project relative target to plane defined by constraint if (constraintAxisSelect.X != 0) forward.X = 0; else if (constraintAxisSelect.Y != 0) forward.Y = 0; else if (constraintAxisSelect.Z != 0) forward.Z = 0; //forward = forward.Normalized(); // Vector3 v1 = new Vector3(forward.X,forward.Y,forward.Z) // float ciao = Vector3.Dot(forward, up); //float angle = (float)Math.Acos( Vector3.Dot(current,targetAbsRef) ); //Vector3 rotAxis = Vector3.CrossProduct(current, forward).Normalized(); //Vector3 right = Vector3.CrossProduct(forward, up); Matrix4 lookAt_result = Matrix4.LookAt(forward.X, forward.Y, forward.Z, eye.X, eye.Y, eye.Z, up.X, up.Y, up.Z); Matrix3 targetRelOrientation_matrix = new Matrix3(lookAt_result); Quaternion targetRelOrientation_quaternion = Quaternion.FromMatrix(targetRelOrientation_matrix); /* Quaternion targetRelOrientation_quaternion = new Quaternion(); targetRelOrientation_quaternion.W = (float)Math.Sqrt((double)(1.0f + right.X + up.Y + forward.Z)) * 0.5f; float w4_recip = 1.0f / (4.0f * targetRelOrientation_quaternion.W); targetRelOrientation_quaternion.X = (forward.Y - up.Z) * w4_recip; targetRelOrientation_quaternion.Y = (right.Z - forward.X) * w4_recip; targetRelOrientation_quaternion.Z = (up.X - right.Y) * w4_recip; */ return targetRelOrientation_quaternion; }
public virtual void updateExecution(float timeElapsed) { if (timeElapsed <= 0f) { return; } // basic proportional navigation. see wikipedia var mParams = missile.parameters; var target = missile.target; Vector3 Vr = target.velocity - missile.velocity; Vector3 R = target.position - missile.position; Vector3 omega = Vector3.Cross(R, Vr) / R.LengthSquared; Vector3 cross = Vector3.Cross(Vr, omega); Vector3 latax; if (cross.LengthSquared == 0) { latax = R.Normalized() * mParams.pursuitMaxAcc; } else { latax = mParams.pursuitNavigationGain * cross; } if (mParams.pursuitAugmentedPN == true) { // this code is not tested as there are currently no targets with well defined accelerations Vector3 losDir = R.Normalized(); float targetAccLos = Vector3.Dot(target.acceleration, losDir); Vector3 targetLatAx = target.acceleration - targetAccLos * losDir; latax += mParams.pursuitNavigationGain * targetLatAx / 2f; } missile._lataxDebug = latax; // apply latax var oldVelMag = missile.velocity.LengthFast; missile.velocity += latax * timeElapsed; float tempVelMag = missile.velocity.LengthFast; if (oldVelMag != 0f) { float r = tempVelMag / oldVelMag; if (r > 1f) { missile.velocity /= r; } } if (mParams.pursuitHitTimeCorrection && !float.IsNaN(missile.timeToHit)) { // apply pursuit hit time correction float dist = R.LengthFast; if (dist != 0f) { Vector3 targetDir = R / dist; float v0 = -Vector3.Dot(Vr, targetDir); float t = missile.timeToHit; float correctionAccMag = 2f * (dist - v0 * t) / t / t; Vector3 corrAcc = correctionAccMag * targetDir; missile.velocity += corrAcc * timeElapsed; missile._hitTimeCorrAccDebug = corrAcc; } } else { // hit time correction inactive. allow accelerating to achieve optimal velocity or forever oldVelMag = missile.velocity.LengthFast; float velDelta = mParams.pursuitMaxAcc * timeElapsed; float newVelMag = Math.Min(oldVelMag + velDelta, mParams.pursuitMaxVelocity); if (oldVelMag != 0f) { missile.velocity *= (newVelMag / oldVelMag); } } }
public static void Run() { GraphicsContext context = new GraphicsContext() { Camera = new FirstPersonCamera(new Vector3(4, 3, 3), Vector3.UnitY) }; Matrix4 World = Matrix4.Identity; VoxelTypeMap v = new VoxelTypeMap(); v[0] = new VoxelTypeMap.VoxelTypeData() { Color = Vector4.One, Visible = false }; v[1] = new VoxelTypeMap.VoxelTypeData() { Color = Vector4.UnitY * 0.7f + Vector4.UnitW, Visible = true }; v[2] = new VoxelTypeMap.VoxelTypeData() { Color = Vector4.UnitX + Vector4.UnitW, Visible = true }; BlockManager man = new BlockManager(); man.Side = 32; man.VoxelTypes = v; //Rendering stuff ShaderProgram prog = null; GraphicsDevice.Load += () => { //GraphicsDevice.Winding = FaceWinding.Clockwise; GraphicsDevice.CullMode = OpenTK.Graphics.OpenGL4.CullFaceMode.Back; GraphicsDevice.DepthTestEnabled = true; GraphicsDevice.Window.KeyUp += (k, e) => { if (e.Key == OpenTK.Input.Key.Z) GraphicsDevice.Wireframe = !GraphicsDevice.Wireframe; else if (e.Key == OpenTK.Input.Key.C) GraphicsDevice.CullEnabled = !GraphicsDevice.CullEnabled; }; Random rng = new Random(0); double n = 64; v.UpdateBuffers(); GraphicsDevice.SetBufferTexture(0, v.ColorData); ShaderSource vShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.VertexShader, "Testing/VoxTest/vertex.glsl"); ShaderSource fShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.FragmentShader, "Testing/VoxTest/fragment.glsl"); prog = new ShaderProgram(vShader, fShader); prog.Set("materialColors", 0); }; GraphicsDevice.Update += (e) => { context.Update(e); //World *= Matrix4.CreateRotationY(0.01f); prog.Set("World", Matrix4.Identity); prog.Set("View", context.View); prog.Set("Proj", context.Projection); prog.Set("Fcoef", (float)(2.0f / Math.Log(1000001) / Math.Log(2))); prog.Set("lightDir", new Vector3(5, 10, 5).Normalized()); }; GraphicsDevice.Render += (e) => { GraphicsDevice.Clear(); for (int k = -2; k < 0; k++) { Vector3 a = new Vector3(); a.Y = k * man.Side; for (int i = -5; i <= 5; i++) { a.Z = i * man.Side; for (int j = -5; j <= 5; j++) { a.X = j * man.Side; Vector3 dir = (context.Camera as FirstPersonCamera).Direction; if (Vector3.Dot(dir.Normalized(), a.Normalized()) >= -0.3) { //Chunk c = man.Draw(-Vector3.UnitY * 123, out World); Chunk c = man.Draw(context.Camera.Position + a, out World); if (c.ChunkReady) { c.Bind(); prog.Set("World", World); prog.Set("range1", c.NormalOffsets[1]); prog.Set("range2", c.NormalOffsets[2]); prog.Set("range3", c.NormalOffsets[3]); prog.Set("range4", c.NormalOffsets[4]); prog.Set("range5", c.NormalOffsets[5]); GraphicsDevice.SetShaderProgram(prog); GraphicsDevice.Draw(OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, 0, c.NormalGroupSizes[6]); } } } } } GraphicsDevice.SwapBuffers(); }; GraphicsDevice.Name = "Voxel Test"; GraphicsDevice.Run(60, 0); if (GraphicsDevice.Cleanup != null) GraphicsDevice.Cleanup(); }