public void SetValues(global::Element elem, PhysicsData pd, List <global::Element> elements) { elementIdx = (byte)elements.IndexOf(elem); temperature = pd.temperature; mass = pd.mass; insulation = byte.MaxValue; }
bool CircleVsCircle(Manifold m, Circle ca, Circle cb) { PhysicsData a = m.a; PhysicsData b = m.b; // vector from a to b Vector2 atob = b.position - a.position; float r = ca.radius + cb.radius; r *= r; if (atob.sqrMagnitude > r) { return(false); } float dist = atob.magnitude; if (dist != 0) { m.penetration = r - dist; m.normal = atob.normalized; } else { // circles are in the same position! m.penetration = ca.radius; m.normal = new Vector2(1, 0); } return(true); }
public static bool DetectCircleOverlap(PhysicsData a, PhysicsData b, Circle ca, Circle cb) { float distSqrd = (a.position + b.position).sqrMagnitude; float threshold = ca.radius + cb.radius; threshold *= threshold; return(distSqrd < threshold); }
public SharedData(PhysicsObjectsFactory objectsFactory, GameplayData gameplayData, PhysicsData physicsData, RenderData renderData, KeyState keys) { ObjectsFactory = objectsFactory; GameplayData = gameplayData; PhysicsData = physicsData; RenderData = renderData; Keys = keys; }
public void CopyData(PhysicsData other) { position = other.position; velocity = other.velocity; mass = other.mass; circ = new Circle(); circ.radius = other.circ.radius; restitution = other.restitution; }
public void LoadPhysicsDataFromJSON() { string filePath = Application.dataPath + physDataPath; if (File.Exists(filePath)) { string jsonData = File.ReadAllText(filePath); physData = JsonUtility.FromJson <PhysicsData>(jsonData); Debug.Log("Data Loaded"); } }
protected void Awake() { // Cache the Character instance controlling this component. Avoids excessive runtime lookups. character = GetComponent <Character>(); // Adds a new component to the character which allows him to move to target posiitons moveToTargetScript = gameObject.AddComponent <MoveToTarget>(); // Set the character's physics data to default physicsData = new PhysicsData(defaultPhysicsData); // Caches the entity's components to efficiently modify their behaviours rigidbody = GetComponent <Rigidbody2D>(); }
private void OnGUI() { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Character 1", GUILayout.Width(126)); character1 = EditorGUILayout.ObjectField(character1, typeof(GameObject), true, GUILayout.Width(126)) as GameObject; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Character 2", GUILayout.Width(126)); character2 = EditorGUILayout.ObjectField(character2, typeof(GameObject), true, GUILayout.Width(126)) as GameObject; GUILayout.EndHorizontal(); if (character1 != null && character2 != null) { distance = character2.transform.position.x - character1.transform.position.x; GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Distance", GUILayout.Width(126)); EditorGUILayout.FloatField(distance, GUILayout.Width(126)); GUILayout.EndHorizontal(); EditorGUILayout.LabelField("Throw Angle", GUILayout.Width(126)); angle = EditorGUILayout.Slider(angle, 0, 90, GUILayout.Width(126)); rad = angle * Mathf.Deg2Rad; float v = Mathf.Sqrt(distance * GameManager.gravity / Mathf.Sin(2 * rad)); float vX = (v * Mathf.Cos(rad)); float vY = (v * Mathf.Sin(rad) - GameManager.gravity * 0.02f); Vector2 throwVelocity = new Vector2(vX, vY); if (data == null) { data = new PhysicsData(); } data.throwVelocity = throwVelocity; EditorGUILayout.Space(); EditorGUILayout.Vector2Field("Throw Velocity", throwVelocity, GUILayout.Width(126)); if (GUILayout.Button("Save Data")) { SaveToJSON(data, GameManager.physDataPath); } } }
public Vector2[] gravityPreview(PhysicsData[] others, PhysicsData moon, int points) { Vector2[] arr = new Vector2[points]; PhysicsData[] ents = new PhysicsData[others.Length + 1]; for (int i = 1; i < ents.Length; i++) { if (others[i - 1] == null) { continue; } ents[i] = new PhysicsData(); ents[i].CopyData(others[i - 1]); } ents[0] = new PhysicsData(); ents[0].CopyData(moon); for (int i = 0; i < points; i++) { for (int j = 0; j < ents.Length; j++) { if (ents[j] == null) { continue; } PhysicsData a = ents[j]; for (int k = j + 1; k < ents.Length; k++) { if (ents[k] == null) { continue; } PhysicsData b = ents[k]; Vector2 forceA = Calc.GravityForce(a, b); a.velocity += forceA / a.mass * (1f / 60f); Vector2 forceB = Calc.GravityForce(b, a); b.velocity += forceB / b.mass * (1f / 60f); } ents[j].position += (Vector3)ents[j].velocity * (1f / 60f); } arr[i] = ents[0].position; } return(arr); }
public Element(global::Element e, List <global::Element> elements) { id = e.id; state = (byte)e.state; if (e.HasTag(GameTags.Unstable)) { state |= 8; } int num = elements.FindIndex((global::Element ele) => ele.id == e.lowTempTransitionTarget); int num2 = elements.FindIndex((global::Element ele) => ele.id == e.highTempTransitionTarget); lowTempTransitionIdx = (byte)((num < 0) ? 255 : num); highTempTransitionIdx = (byte)((num2 < 0) ? 255 : num2); elementsTableIdx = (byte)elements.IndexOf(e); specificHeatCapacity = e.specificHeatCapacity; thermalConductivity = e.thermalConductivity; solidSurfaceAreaMultiplier = e.solidSurfaceAreaMultiplier; liquidSurfaceAreaMultiplier = e.liquidSurfaceAreaMultiplier; gasSurfaceAreaMultiplier = e.gasSurfaceAreaMultiplier; molarMass = e.molarMass; strength = e.strength; flow = e.flow; viscosity = e.viscosity; minHorizontalFlow = e.minHorizontalFlow; minVerticalFlow = e.minVerticalFlow; maxMass = e.maxMass; lowTemp = e.lowTemp; highTemp = e.highTemp; highTempTransitionOreID = e.highTempTransitionOreID; highTempTransitionOreMassConversion = e.highTempTransitionOreMassConversion; lowTempTransitionOreID = e.lowTempTransitionOreID; lowTempTransitionOreMassConversion = e.lowTempTransitionOreMassConversion; sublimateIndex = (sbyte)elements.FindIndex((global::Element ele) => ele.id == e.sublimateId); convertIndex = (sbyte)elements.FindIndex((global::Element ele) => ele.id == e.convertId); pack0 = 0; pack1 = 0; if (e.substance == null) { colour = 0u; } else { Color32 color = e.substance.colour; colour = (uint)((color.a << 24) | (color.b << 16) | (color.g << 8) | color.r); } sublimateFX = e.sublimateFX; lightAbsorptionFactor = e.lightAbsorptionFactor; defaultValues = e.defaultValues; }
public int AddNewObj(PhysicsData obj) { for (int i = 0; i < physEnts.Length; i++) { if (physEnts[i] == null) { physEnts[i] = obj; return(i); } } int oldSize = physEnts.Length; Array.Resize(ref physEnts, physEnts.Length * 2); physEnts[oldSize] = obj; return(oldSize); }
private void Initialize() { if (!character) { character = Find("Character"); } if (!settings) { settings = CreateInstance <PhysicsSettings>(); } if (!Data) { Data = CreateInstance <PhysicsData>(); } Data.OnInitialize(settings, ref character); }
public static void ResolveCollision(PhysicsData a, PhysicsData b, Vector2 normal, float penetration) { // calculate relative velocity Vector2 rv = b.velocity - a.velocity; // calculate relative velocity in terms of normal direcion float velAlongNormal = Vector2.Dot(rv, normal); // do not resolve if velocities are separating if (velAlongNormal > 0) { return; } // calculate restitution float e = Mathf.Min(a.restitution, b.restitution); float invMassA = (a.mass == 0) ? 0 : 1 / a.mass; float invMassB = (b.mass == 0) ? 0 : 1 / b.mass; // calculate impulse scalar float j = -(1 + e) * velAlongNormal; if (invMassA != 0 || invMassB != 0) { j /= invMassA + invMassB; } else { j = 0; } // apply impulse Vector2 impulse = j * normal; a.velocity -= invMassA * impulse; b.velocity += invMassB * impulse; // positional correction, needed due to floating point error //if (invMassA != 0 || invMassB != 0) { // const float correctPercent = 0.2f; // const float slop = 0.01f; // Vector2 correction = Mathf.Max(penetration - slop,0.0f) / (invMassA + invMassB) * correctPercent * normal; // a.transform.position -= (Vector3)(invMassA * correction); // b.transform.position += (Vector3)(invMassB * correction); //} }
public override void OnInspectorGUI() { // Caches the scripts this inspector modifies CharacterMovement characterMovement = (CharacterMovement)target; PhysicsData defaultPhysicsData = characterMovement.DefaultPhysicsData; /******************* * PHYSICS FOLDOUT * *******************/ EditorGUI.indentLevel = 0; // "Physics" foldout showPhysicsFoldout = EditorGUILayout.Foldout(showPhysicsFoldout, "Physics"); if (showPhysicsFoldout) { EditorGUI.indentLevel = 1; // "Default Walk Speed" foldout showWalkSpeedFoldout = EditorGUILayout.Foldout(showWalkSpeedFoldout, "Default Walk Speed"); if (showWalkSpeedFoldout) { // Physics foldout EditorGUILayout.BeginVertical(); { // Floating-point fields for the character's walking speed defaultPhysicsData.MinWalkSpeed = EditorGUILayout.FloatField("Min:", defaultPhysicsData.MinWalkSpeed); defaultPhysicsData.MaxWalkSpeed = EditorGUILayout.FloatField("Max:", defaultPhysicsData.MaxWalkSpeed); } EditorGUILayout.EndVertical(); } // End "Default Walk Speed" foldout } Undo.RecordObject(characterMovement, "Character Movement Undo"); }
private void Dependencies() { layerMaskData = layerMaskController.Data; physicsData = physicsController.Data; platformerData = platformerController.Data; }
private async UniTask TranslateMovingPlatformSpeedToTransform() { PhysicsData.OnTranslateMovingPlatformSpeedToTransform(ref character, MovingPlatformCurrentSpeed); await Yield(); }
public void PhysicsUpdate() { for (int i = 0; i < physEnts.Length; i++) { if (physEnts[i] == null) { continue; } for (int j = i + 1; j < physEnts.Length; j++) { if (physEnts[j] == null) { continue; } PhysicsData a = physEnts[i]; PhysicsData b = physEnts[j]; Manifold m = new Manifold { a = a, b = b }; if (CircleVsCircle(m, a.circ, b.circ)) { Calc.ResolveCollision(a, b, m.normal, m.penetration); } // do collision stuff for a and b? } } // gravity for (int i = 0; i < physEnts.Length; i++) { if (physEnts[i] == null) { continue; } for (int j = i + 1; j < physEnts.Length; j++) { if (physEnts[j] == null) { continue; } Vector2 forceA = Calc.GravityForce(physEnts[i], physEnts[j]); physEnts[i].velocity += forceA / physEnts[i].mass * (1f / 60f); Vector2 forceB = Calc.GravityForce(physEnts[j], physEnts[i]); physEnts[j].velocity += forceB / physEnts[j].mass * (1f / 60f); } } for (int i = 0; i < physEnts.Length; i++) { if (physEnts[i] == null || physEnts[i].mass == 0) { continue; } physEnts[i].position += (Vector3)(physEnts[i].velocity) * (1.0f / 60.0f); physEnts[i].owner.transform.position = physEnts[i].position; } }
public PhysicsData(PhysicsData other) { Set(other); }
public static Vector2 GravityForce(PhysicsData a, PhysicsData b) { const float gravConst = 0.00000000006675f; return((Vector2)(b.position - a.position) * gravConst * (a.mass * b.mass / Vector3.Distance(a.position, b.position))); }
/// <summary> /// Copies the values from the given PhysicsData instance. /// </summary> public void Set(PhysicsData other) { minWalkSpeed = other.minWalkSpeed; maxWalkSpeed = other.maxWalkSpeed; }
// this function copies a vehicle's data ; from the name only we can load all pieces, physics and input data public void Copy(Player player) { saveName = player.saveName; physics = player.physics; }
// Update is called once per frame void Update() { Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); if (Input.GetMouseButtonDown(0)) { //Vector2 clickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); if (currMode == inputMode.NONE) { currMode = inputMode.SCALE; position = mousePos; } else if (currMode == inputMode.SCALE) { radius = Vector2.Distance(position, mousePos) / 2f; currMode = inputMode.VELOCITY; } else if (currMode == inputMode.VELOCITY) { velocity = (mousePos - position); MakeNewPhysObject(); currMode = inputMode.NONE; } } if (Input.GetMouseButtonDown(1)) { if (currMode == inputMode.VELOCITY) { velocity = Vector2.zero; MakeNewPhysObject(); currMode = inputMode.NONE; } } if (currMode == inputMode.SCALE) { Utils.DrawDebugCircle(position, 32, Vector2.Distance(position, mousePos) / 2f, Color.white); } else if (currMode == inputMode.VELOCITY) { Debug.DrawLine(position, mousePos); Utils.DrawDebugCircle(position, 32, radius, Color.white); if (gravity) { PhysicsData dat = new PhysicsData(); dat.velocity = (mousePos - position); dat.position = (position); dat.circ = new Circle { radius = radius }; float m = Mathf.PI * radius * radius; dat.mass = m * m * m; PhysicsData[] bigEnts = new PhysicsData[3]; float[] highMass = new float[3]; for (int i = 0; i < physicsEngine.physEnts.Length; i++) { PhysicsData other = physicsEngine.physEnts[i]; if (other == null) { continue; } Vector2 gForce = Calc.GravityForce(other, dat); float f = gForce.magnitude; float low = Mathf.Min(highMass); if (f > low) { for (int j = 0; j < highMass.Length; j++) { if (highMass[j] == low) { highMass[j] = f; bigEnts[j] = physicsEngine.physEnts[i]; break; } } } } if (highMass[0] != 0f) { Vector2[] preview = physicsEngine.gravityPreview(bigEnts, dat, 400); for (int i = 0; i < preview.Length - 1; i++) { Debug.DrawLine(preview[i], preview[i + 1], Color.magenta); } } } } for (int i = 0; i < 10; i++) { if (Input.GetKeyDown(i.ToString())) { steps = speeds[i]; } } float scroll = Input.mouseScrollDelta.y; if (Mathf.Abs(scroll) > 0.01f) { //Debug.Log(Camera.main.orthographicSize * f); Camera.main.orthographicSize += (Camera.main.orthographicSize * scroll * 0.04f); } if (Input.GetKeyDown(KeyCode.Space)) { runPhysics = !runPhysics; } if (Input.GetKey(KeyCode.W)) { Camera.main.transform.position += Vector3.up * Camera.main.orthographicSize * Time.deltaTime; } if (Input.GetKey(KeyCode.A)) { Camera.main.transform.position += Vector3.left * Camera.main.orthographicSize * Time.deltaTime; } if (Input.GetKey(KeyCode.S)) { Camera.main.transform.position += Vector3.down * Camera.main.orthographicSize * Time.deltaTime; } if (Input.GetKey(KeyCode.D)) { Camera.main.transform.position += Vector3.right * Camera.main.orthographicSize * Time.deltaTime; } if (Input.GetKey(KeyCode.Backspace)) { physicsEngine.Purge(1); } if (Input.GetKey(KeyCode.Delete)) { physicsEngine.Purge(0); } }
/// <summary> /// Add the collision data for an object. This involves looking /// for a physics file that matches the mesh file's name, and /// loading the information from that file to build collision /// volumes. /// </summary> /// <param name="objNode">the object for which we are adding the collision data</param> public void AddCollisionObject(ObjectNode objNode) { if (worldManager.CollisionHelper == null) { return; } if (!objNode.UseCollisionObject) { return; } // Create a set of collision shapes for the object List <CollisionShape> shapes = new List <CollisionShape>(); string meshName = objNode.Entity.Mesh.Name; PhysicsData pd = new PhysicsData(); PhysicsSerializer ps = new PhysicsSerializer(); bool static_object = true; if ((objNode.ObjectType == ObjectNodeType.Npc) || (objNode.ObjectType == ObjectNodeType.User)) { static_object = false; } if (meshName.EndsWith(".mesh")) { string physicsName = meshName.Substring(0, meshName.Length - 5) + ".physics"; try { Stream stream = ResourceManager.FindCommonResourceData(physicsName); ps.ImportPhysics(pd, stream); foreach (SubEntity subEntity in objNode.Entity.SubEntities) { if (subEntity.IsVisible) { string submeshName = subEntity.SubMesh.Name; List <CollisionShape> subEntityShapes = pd.GetCollisionShapes(submeshName); foreach (CollisionShape subShape in subEntityShapes) { // static objects will be transformed here, but movable objects // are transformed on the fly if (static_object) { subShape.Transform(objNode.SceneNode.DerivedScale, objNode.SceneNode.DerivedOrientation, objNode.SceneNode.DerivedPosition); } shapes.Add(subShape); log.DebugFormat("Added collision shape for oid {0}, subShape {1}, subMesh {2}", objNode.Oid, subShape, submeshName); } } } // Now populate the region volumes foreach (KeyValuePair <string, List <CollisionShape> > entry in pd.CollisionShapes) { string regionName = RegionVolumes.ExtractRegionName(entry.Key); if (regionName != "") { // We must record this region - - must be // a static object Debug.Assert(static_object); List <CollisionShape> subShapes = new List <CollisionShape>(); foreach (CollisionShape subShape in entry.Value) { subShape.Transform(objNode.SceneNode.DerivedScale, objNode.SceneNode.DerivedOrientation, objNode.SceneNode.DerivedPosition); subShapes.Add(subShape); } RegionVolumes.Instance.AddRegionShapes(objNode.Oid, regionName, subShapes); } } } catch (Exception) { // Unable to load physics data -- use a sphere or no collision data? log.InfoFormat("Unable to load physics data: {0}", physicsName); //// For now, I'm going to put in spheres. Later I should do something real. //CollisionShape shape = new CollisionSphere(Vector3.Zero, Client.OneMeter); //if (static_object) // // static objects will be transformed here, but movable objects // // are transformed on the fly // shape.Transform(objNode.SceneNode.DerivedScale, // objNode.SceneNode.DerivedOrientation, // objNode.SceneNode.DerivedPosition); //shapes.Add(shape); } } if (static_object) { foreach (CollisionShape shape in shapes) { worldManager.CollisionHelper.AddCollisionShape(shape, objNode.Oid); } objNode.CollisionShapes = shapes; } else { MovingObject mo = new MovingObject(worldManager.CollisionHelper); foreach (CollisionShape shape in shapes) { worldManager.CollisionHelper.AddPartToMovingObject(mo, shape); } objNode.Collider = mo; objNode.Collider.Transform(objNode.SceneNode.DerivedScale, objNode.SceneNode.DerivedOrientation, objNode.SceneNode.DerivedPosition); } }
private void SetDependencies() { raycastData = raycastController.Data; physicsData = physicsController.Data; layerMaskData = layerMaskController.Data; }
public static void ExtractCollisionShapes(Mesh mesh, string path) { PhysicsData physicsData = null; List <string> deleteEm = new List <string>(); int count = mesh.SubMeshCount; for (int i = 0; i < count; i++) { SubMesh subMesh = mesh.GetSubMesh(i); CollisionShape shape = null; string targetName = null; bool cv = String.Compare(subMesh.Name.Substring(0, 5), "mvcv_", false) == 0; bool rg = String.Compare(subMesh.Name.Substring(0, 5), "mvrg_", false) == 0; int firstIndex = 0; if (cv) { firstIndex = 5; } else if (rg) { string rest = subMesh.Name.Substring(5); firstIndex = rest.IndexOf("_") + 1 + 5; } if (cv || rg) { // It's probably a collision volume - - check the // shape type to make sure if (String.Compare(subMesh.Name.Substring(firstIndex, 4), "obb_", false) == 0) { shape = ExtractBox(subMesh); } else if (String.Compare(subMesh.Name.Substring(firstIndex, 5), "aabb_", false) == 0) { shape = ExtractBox(subMesh); } else if (String.Compare(subMesh.Name.Substring(firstIndex, 7), "sphere_", false) == 0) { shape = ExtractSphere(subMesh); } else if (String.Compare(subMesh.Name.Substring(firstIndex, 8), "capsule_", false) == 0) { shape = ExtractCapsule(subMesh); } if (shape != null) { targetName = GetTargetSubmesh(mesh, subMesh.Name); } } if (shape != null) { deleteEm.Add(subMesh.Name); if (physicsData == null) { physicsData = new PhysicsData(); } physicsData.AddCollisionShape(targetName, shape); } } for (int i = 0; i < deleteEm.Count; i++) { mesh.RemoveSubMesh(deleteEm[i]); } if (physicsData != null) { PhysicsSerializer serializer = new PhysicsSerializer(); serializer.ExportPhysics(physicsData, path + ".physics"); } if (DoLog) { CloseLog(); } }
public GameStartup() { const float dt = 1 / 60f; ClientSize = new Size(900, 720); DoubleBuffered = true; keys = new KeyState(); world = new EcsWorld(); worldEvents = new EcsWorld(); worldConstraints = new EcsWorld(); gameplayData = new GameplayData(new Vector2(0, -9.80665f)); physicsData = new PhysicsData(dt, 10, 4, 2); renderData = new RenderData(ClientSize.Width, ClientSize.Height, 60f); var sharedData = new SharedData(new PhysicsObjectsFactory(world, worldConstraints), gameplayData, physicsData, renderData, keys); gameplaySystems = new EcsSystems(world, sharedData); gameplaySystems .AddWorld(worldEvents, PhysicsWorldNames.Events) .AddWorld(worldConstraints, PhysicsWorldNames.Constraints) .Add(new InitEnvironment()) // .Add(new CreateSegments()) .Add(new Grabber()) .Inject() .Init(); physicsSystems = new EcsSystems(world, physicsData); physicsSystems .AddWorld(worldEvents, PhysicsWorldNames.Events) .AddWorld(worldConstraints, PhysicsWorldNames.Constraints) // force generators .Add(new ApplyStaticGravity()) // custom one .Add(new UpdateSprings()) // apply forces .Add(new IntegratePoses()) // update bounding volumes .Add(new UpdateCirclesBV()) .Add(new UpdateMeshesBV()) // broad phase .Add(new BroadPhase()) // narrow phase .Add(new ContactTesterCircleCircle()) .Add(new ContactTesterCircleMesh()) .Add(new ContactTesterCircleSegment()) .Add(new ContactTesterMeshSegment()) .Add(new ContactTesterCircleAABox()) // solver phase .Add(new DynamicDefaultContactSolver <Dynamic, Dynamic>()) .Add(new StaticDefaultContactSolver <Dynamic, Static>()) // physics systems internally use PhysicsData, // but you can inject your own data for custom force generators .Inject(gameplayData) .Init(); renderSystems = new EcsSystems(world, sharedData); renderSystems .AddWorld(worldEvents, PhysicsWorldNames.Events) .AddWorld(worldConstraints, PhysicsWorldNames.Constraints) .Add(new DrawVelocities()) .Add(new DrawSegments()) .Add(new DrawMeshes()) .Add(new DrawAABoxes()) .Add(new DrawSprings()) // .Add(new DrawBoundingBoxes()) .Add(new RenderMeshesMassCenter()) .Inject(renderData) .Init(); var timer = new Timer(); timer.Interval = 16; timer.Tick += GameLoop; timer.Start(); }