public virtual void Fire(Actor ss, Slot s) { CurrentReloadTime = 0; Projectile p = (Projectile)Root.Instance.Factory.CreateInstance(ProjectileType); if (p.NoReplication || Root.Instance.IsAuthoritive) { p.Target = ss.Computer.Target; Matrix4 ship = ss.Matrix; Matrix4 slot = s.Matrix; Matrix4 combined = slot * ship; Vector3 x, y, z; Matrix4Extensions.ExtractBasis(combined, out x, out y, out z); p.Position = Matrix4Extensions.ExtractTranslation(combined); p.Orientation = Matrix4Extensions.ExtractRotation(combined); //p.localspeed=new Vector3(0,0,ExitingSpeed); p.Speed = z * ExitingSpeed; p.Source = ss; Root.Instance.Scene.Spawn(p); if (FireSound != null) { p.PlaySound(FireSound, false); } } //else p.Kill=true; }
/// <summary> /// Helper to calculate the combined mass, centre of mass, and /// inertia tensor about the origin and the CoM (for the local /// primitives) primitiveProperties is an array of properties - /// must be the same number as there are primitives /// </summary> /// <param name="primitiveProperties"></param> /// <param name="mass"></param> /// <param name="centerOfMass"></param> /// <param name="inertiaTensor"></param> /// <param name="inertiaTensorCoM"></param> public void GetMassProperties(PrimitiveProperties[] primitiveProperties, out float mass, out Vector3 centerOfMass, out Matrix4 inertiaTensor, out Matrix4 inertiaTensorCoM) { mass = 0.0f; centerOfMass = Vector3.Zero; inertiaTensor = Matrix4.Identity; inertiaTensorCoM = Matrix4.Identity; for (int prim = primitivesLocal.Count; prim-- != 0;) { float m; Vector3 com; Matrix4 it; primitivesLocal[prim].GetMassProperties(primitiveProperties[prim], out m, out com, out it); mass += m; centerOfMass += m * com; inertiaTensor = Matrix4Extensions.Add(inertiaTensor, it); } if (mass > 0.0f) { centerOfMass /= mass; // Transfer of axe theorem inertiaTensorCoM.M11 = inertiaTensor.M11 - mass * (centerOfMass.Y * centerOfMass.Y + centerOfMass.Z * centerOfMass.Z); inertiaTensorCoM.M22 = inertiaTensor.M22 - mass * (centerOfMass.Z * centerOfMass.Z + centerOfMass.X * centerOfMass.X); inertiaTensorCoM.M33 = inertiaTensor.M33 - mass * (centerOfMass.X * centerOfMass.X + centerOfMass.Y * centerOfMass.Y); // CHECK THIS. seems strange for me inertiaTensorCoM.M12 = inertiaTensorCoM.M21 = inertiaTensor.M12 + mass * centerOfMass.X * centerOfMass.Y; inertiaTensorCoM.M23 = inertiaTensorCoM.M32 = inertiaTensor.M23 + mass * centerOfMass.Y * centerOfMass.Z; inertiaTensorCoM.M31 = inertiaTensorCoM.M13 = inertiaTensor.M31 + mass * centerOfMass.Z * centerOfMass.X; } }
public BeamRenderer(int count, IDrawable part, Vector3 dist) { Count = count; Part = part; Distance = dist; Offset = Matrix4Extensions.FromTranslation(Distance); }
public void Draw(IRenderer r, Node n) { CreateBuffers(); Material mq = Material.CreateSimpleMaterial(Root.Instance.ResourceManager.LoadTexture("revenant.tga")); mq.twosided = true; mq.wire = true; r.SetMode(RenderMode.Draw3D); r.SetMaterial(mq); IEffect e = (IEffect)Root.Instance.ResourceManager.Load("shaders/simple.cgfx", typeof(IEffect)); float[] modelview = new float[16]; float[] projection = new float[16]; r.GetMatrix(modelview, projection); Matrix4 m1 = Matrix4Extensions.FromFloats(modelview); Matrix4 m2 = Matrix4Extensions.FromFloats(projection); Matrix4 m3 = m2 * m1; e.SetParameter(e.GetParameter("mvp"), Matrix4Extensions.ToFloats(m3)); e.SetParameter(e.GetParameter("mv"), modelview); e.SetParameter(e.GetParameter("Color"), new float[] { 1, 0, 0, 1 }); e.BeginPass(0); foreach (Md5Mesh m in Meshes) { m.Draw(r, n); } e.EndPass(0); }
/// <summary> /// Multiply /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="result"></param> public static void Multiply(ref Transform lhs, ref Transform rhs, out Transform result) { result = new Transform(); Matrix4Extensions.Multiply(ref rhs.Orientation, ref lhs.Orientation, out result.Orientation); //result.Orientation = rhs.Orientation * lhs.Orientation; Vector3Extensions.TransformNormal(ref rhs.Position, ref lhs.Orientation, out result.Position); Vector3.Add(ref lhs.Position, ref result.Position, out result.Position); //result.Position = lhs.Position + Vector3.Transform(rhs.Position, lhs.Orientation); }
/// <summary> /// Pushes intersection points onto the back of pts. Returns the /// number of points found. /// Points that are close together (compared to /// combinationDistance) get combined /// dirToBody0 is the collision normal towards box0 /// </summary> /// <param name="pts"></param> /// <param name="box0"></param> /// <param name="box1"></param> /// <param name="combinationDistance"></param> /// <param name="collTolerance"></param> /// <returns>int</returns> private static int GetBoxBoxIntersectionPoints(List <ContactPoint> pts, Box box0, Box box1, float combinationDistance, float collTolerance) { // first transform box1 into box0 space - there box0 has a corner // at the origin and faces parallel to the world planes. Then intersect // each of box1's edges with box0 faces, transforming each point back into // world space. Finally combine points float tolVal = 0.5f * collTolerance; Vector3 tol = new Vector3(tolVal, tolVal, tolVal); combinationDistance += collTolerance * 2.0f * (float)System.Math.Sqrt(3.0d); for (int ibox = 0; ibox < 2; ++ibox) { Box boxA = (ibox != 0) ? box1 : box0; Box boxB = (ibox != 0) ? box0 : box1; #region REFERENCE: Matrix4 boxAInvOrient = Matrix4.Transpose(boxA.Orientation); Matrix4 boxAInvOrient; Matrix4.Transpose(ref boxA.transform.Orientation, out boxAInvOrient); #endregion #region REFERENCE: Vector3 pos = Vector3.Transform(boxB.Position - boxA.Position,boxAInvOrient) Vector3 pos; Vector3.Subtract(ref boxB.transform.Position, ref boxA.transform.Position, out pos); Vector3Extensions.TransformNormal(ref pos, ref boxAInvOrient, out pos); #endregion #region REFERENCE: Matrix4 boxOrient = boxB.Orientation * boxAInvOrient; Matrix4 boxOrient; Matrix4Extensions.Multiply(ref boxB.transform.Orientation, ref boxAInvOrient, out boxOrient); #endregion Box box = tempBox; box.Position = pos; box.Orientation = boxOrient; box.SideLengths = boxB.SideLengths; // if we get more than a certain number of points back from this call, // and iBox == 0, could probably skip the other test... Vector3 sL = boxA.SideLengths; GetAABox2BoxEdgesIntersectionPoints(pts, ref sL, box, ref boxA.transform.Orientation, ref boxA.transform.Position, combinationDistance * combinationDistance); } return(pts.Count); }
public Vector3 CalcVertexPosition(Md5Vertex v, Md5Anim a, int frame) { Vector3 pos = Vector3.Zero; for (int i = v.WeightIndex; i < v.WeightIndex + v.WeightCount; ++i) { Md5Weight w = Weights[i]; Md5JointValue j = a.Frames[frame].Values[w.JointIndex]; Matrix4 m = Matrix4Extensions.FromTranslation(j.Position) * Matrix4Extensions.FromQuaternion(j.Orientation); pos += w.Value * Vector3.Transform(w.Position, m); } return(pos); }
public ShockWave(Texture t, float size, float lifetime, bool random) { Size = size; LifeTime = lifetime; f = size / (float)Math.Sqrt(lifetime); Mat = new Material(); Mat.Additive = true; Mat.diffusemap = t; Mat.twosided = true; Mat.NoLighting = true; Mat.DepthWrite = false; Shader = Root.Instance.ResourceManager.LoadShader("shock.shader"); CreateVertexBuffer(); BaseMatrix = random?Matrix4Extensions.FromAngleAxis(VecRandom.Instance.NextUnitVector3(), 30.0f / 180.0f * (float)Math.PI):Matrix4.Identity; }
/// <summary> /// ApplyTranformRate /// </summary> /// <param name="rate"></param> /// <param name="dt"></param> public void ApplyTransformRate(TransformRate rate, float dt) { //Position += dt * rate.Velocity; Vector3 pos; Vector3.Multiply(ref rate.Velocity, dt, out pos); Vector3.Add(ref Position, ref pos, out Position); Vector3 dir = rate.AngularVelocity; float ang = dir.Length; if (ang > 0.0f) { Vector3.Divide(ref dir, ang, out dir); // dir /= ang; ang *= dt; Matrix4 rot = Matrix4.CreateFromAxisAngle(dir, ang); Matrix4Extensions.Multiply(ref Orientation, ref rot, out Orientation); } // JiggleMath.Orthonormalise(ref this.Orientation); }
public void Draw(IRenderer r, Node n) { if (Age > LifeTime) { return; } r.SetMode(RenderMode.Draw3D); r.SetMaterial(Mat); r.BindTexture(Mat.diffusemap.Id); r.UseShader(Shader); r.SetUniform(Shader.GetUniformLocation("Alpha"), new float[] { CurrentAlpha }); float s = CurrentSize / 2; Matrix4 m = BaseMatrix * Matrix4Extensions.FromScale(s, s, s); r.PushMatrix(); r.MultMatrix(m); r.Draw(Vertices, PrimitiveType.QUADS, 0, 4, null); r.PopMatrix(); }
/// <summary> /// Helper to calculate the combined mass, centre of mass, and /// inertia tensor about the origin and the CoM (for the local /// primitives) primitiveProperties indicates the properties used /// for all primitives - so the mass is the total mass /// </summary> /// <param name="primitiveProperties"></param> /// <param name="mass"></param> /// <param name="centerOfMass"></param> /// <param name="inertiaTensor"></param> /// <param name="inertiaTensorCoM"></param> public void GetMassProperties(PrimitiveProperties primitiveProperties, out float mass, out Vector3 centerOfMass, out Matrix4 inertiaTensor, out Matrix4 inertiaTensorCoM) { mass = 0.0f; centerOfMass = Vector3.Zero; inertiaTensor = new Matrix4(); float totalWeighting = 0.0f; if (primitiveProperties.MassType == PrimitiveProperties.MassTypeEnum.Mass) { for (int prim = primitivesLocal.Count; prim-- != 0;) { if (primitiveProperties.MassDistribution == PrimitiveProperties.MassDistributionEnum.Solid) { totalWeighting += primitivesLocal[prim].GetVolume(); } else { totalWeighting += primitivesLocal[prim].GetSurfaceArea(); } } } for (int prim = primitivesLocal.Count; prim-- != 0;) { float m; Vector3 com; Matrix4 it; PrimitiveProperties primProperties = primitiveProperties; if (primitiveProperties.MassType == PrimitiveProperties.MassTypeEnum.Mass) { float weighting = 0.0f; if (primitiveProperties.MassDistribution == PrimitiveProperties.MassDistributionEnum.Solid) { weighting = primitivesLocal[prim].GetVolume(); } else { weighting = primitivesLocal[prim].GetSurfaceArea(); } primProperties.MassOrDensity *= weighting / totalWeighting; } primitivesLocal[prim].GetMassProperties(primProperties, out m, out com, out it); mass += m; centerOfMass += m * com; inertiaTensor = Matrix4Extensions.Add(inertiaTensor, it); } inertiaTensorCoM = Matrix4.Identity; if (mass > 0.0f) { centerOfMass /= mass; // Transfer of axe theorem inertiaTensorCoM.M11 = inertiaTensor.M11 - mass * (centerOfMass.Y * centerOfMass.Y + centerOfMass.Z * centerOfMass.Z); inertiaTensorCoM.M22 = inertiaTensor.M22 - mass * (centerOfMass.Z * centerOfMass.Z + centerOfMass.X * centerOfMass.X); inertiaTensorCoM.M33 = inertiaTensor.M33 - mass * (centerOfMass.X * centerOfMass.X + centerOfMass.Y * centerOfMass.Y); // CHECK THIS. seems strange for me inertiaTensorCoM.M12 = inertiaTensorCoM.M21 = inertiaTensor.M12 + mass * centerOfMass.X * centerOfMass.Y; inertiaTensorCoM.M23 = inertiaTensorCoM.M32 = inertiaTensor.M23 + mass * centerOfMass.Y * centerOfMass.Z; inertiaTensorCoM.M31 = inertiaTensorCoM.M13 = inertiaTensor.M31 + mass * centerOfMass.Z * centerOfMass.X; } if (primitiveProperties.MassType == PrimitiveProperties.MassTypeEnum.Mass) { mass = primitiveProperties.MassOrDensity; } }
/// <summary> /// CollDetectSweep /// </summary> /// <param name="info"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> private void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { // todo - proper swept test // note - mesh is static and its triangles are in world space TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh; Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box; Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box; Vector3 oldCentre; oldBox.GetCentre(out oldCentre); Vector3 newCentre; newBox.GetCentre(out newCentre); Vector3 delta; Vector3.Subtract(ref newCentre, ref oldCentre, out delta); float boxMinLen = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z)); int nPositions = 1 + (int)(delta.Length / boxMinLen); // limit the max positions... if (nPositions > 50) { System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test"); nPositions = 50; } if (nPositions == 1) { CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor); } else { BoundingBox bb = BoundingBoxHelper.InitialBox; BoundingBoxHelper.AddBox(oldBox, ref bb); BoundingBoxHelper.AddBox(newBox, ref bb); unsafe { #if USE_STACKALLOC int *potentialTriangles = stackalloc int[MaxLocalStackTris]; { #else int[] potTriArray = IntStackAlloc(); fixed(int *potentialTriangles = potTriArray) { #endif int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb); if (numTriangles > 0) { for (int i = 0; i <= nPositions; ++i) { float frac = ((float)i) / nPositions; Vector3 centre; Vector3.Multiply(ref delta, frac, out centre); Vector3.Add(ref centre, ref oldCentre, out centre); Matrix4 orient = Matrix4Extensions.Add(Matrix4Extensions.Multiply(oldBox.Orientation, 1.0f - frac), Matrix4Extensions.Multiply(newBox.Orientation, frac)); Box box = new Box(centre - 0.5f * Vector3Extensions.TransformNormal(newBox.SideLengths, orient), orient, newBox.SideLengths); // ideally we'd break if we get one collision... but that stops us getting multiple collisions // when we enter a corner (two walls meeting) - can let us pass through CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor); } } #if USE_STACKALLOC } #else } FreeStackAlloc(potTriArray); #endif } } }
protected Matrix4 GetJointMatrix(Md5Joint j) { return(Matrix4Extensions.FromTranslation(j.Position) * Matrix4Extensions.FromQuaternion(j.Orientation)); }