public virtual void InitializeGame() { // Setup world global object // Initialize GTraphics Manager _gm = new GraphicsManager(this); _sm = SceneManager.Instance; Scene top = new Scene(); _sm.Add(top); // Start the game loop thread _gameLoop = ThreadManager.CreateThread(GameLoop); _gameLoop.Start(); AssetsPath = Application.ExecutablePath + "\\Content"; if (!Directory.Exists(AssetsPath)) { // Break directory into it parts List <String> path = new List <String>(Application.ExecutablePath.Split('\\')); path.Remove(path.Last()); // Go back a directory until we find content do { path.Remove(path.Last()); AssetsPath = String.Format("{0}\\Content", String.Join("\\", path)); } while (!Directory.Exists(AssetsPath) && path.Count > 0); } _physicsWorld = new PhysicsWorld(World.WorldSize); _physicsFactory = new PhysicsFactory(_physicsWorld); if (!SingleThread) { // Start the Physics loop now that the world is created _physicsLoop = ThreadManager.CreateThread(PhysicsLoop); _physicsLoop.Start(); } }
public static unsafe PhysicsWorld GenerateRandomWorld(ref Random rnd, int numBodies, float size, int numThreadsHint, bool direct) { // Create the world PhysicsWorld world = new PhysicsWorld(numBodies, 0, 0); // Create bodies NativeSlice <RigidBody> bodies = world.StaticBodies; for (int i = 0; i < numBodies; i++) { bodies[i] = new RigidBody { WorldFromBody = new RigidTransform { pos = rnd.NextFloat3(-size, size), rot = (rnd.NextInt(10) > 0) ? rnd.NextQuaternionRotation() : quaternion.identity }, Collider = GenerateRandomCollider(ref rnd), // Not safe, could be garbage collected Entity = Entity.Null, CustomTags = 0 }; } // Build the broadphase if (direct) { world.CollisionWorld.Broadphase.Build(world.StaticBodies, world.DynamicBodies, world.MotionDatas, world.MotionVelocities, world.CollisionWorld.CollisionTolerance, 1.0f, -9.81f * math.up()); } else { var buildStaticTree = new NativeArray <int>(1, Allocator.TempJob); buildStaticTree[0] = 1; world.CollisionWorld.Broadphase.ScheduleBuildJobs(ref world, timeStep: 1.0f, gravity: -9.81f * math.up(), buildStaticTree, inputDeps: new JobHandle(), numThreadsHint).Complete(); buildStaticTree.Dispose(); } return(world); }
public void Draw(WriteableBitmap bitmap) { if (_type == PhysicsType.Water) { bitmap.FillRectangle(0, WorldHeight * 2 / 3, WorldWidth, WorldHeight, Colors.SkyBlue); } else if (_type == PhysicsType.Wind) { bitmap.FillRectangle(0, WorldHeight * 1 / 3, WorldWidth, WorldHeight * 2 / 3, Colors.LightGray); } bitmap.DrawLineAa( _edge.PointA.X.ToDisplayUnits(), _edge.PointA.Y.ToDisplayUnits(), _edge.PointB.X.ToDisplayUnits(), _edge.PointB.Y.ToDisplayUnits(), Colors.Black); for (int i = _objList.Count - 1; i >= 0; i--) { int x = _objList[i].Position.X.ToDisplayUnits(); int y = _objList[i].Position.Y.ToDisplayUnits(); if (y > WorldHeight || x > WorldWidth || x < 0 || y < 0) { PhysicsWorld.RemoveObject(_objList[i]); _objList.Remove(_objList[i]); } else { if (_type == PhysicsType.Water) { bitmap.FillEllipseCentered(x, y, BallSize, BallSize, y > WorldHeight * 2 / 3 ? Colors.DarkBlue : Colors.Black); } else { bitmap.FillEllipseCentered(x, y, BallSize, BallSize, Colors.Black); } } } }
/// <summary> /// Makes a clone of the body. Fixtures and therefore shapes are not included. /// Use DeepClone() to clone the body, as well as fixtures and shapes. /// </summary> /// <param name="world"></param> /// <returns></returns> public Body Clone(PhysicsWorld world = null) { Body body = new Body(world ?? _world, Position, Rotation, UserData); body._bodyType = _bodyType; body._linearVelocity = _linearVelocity; body._angularVelocity = _angularVelocity; body.GravityScale = GravityScale; body.UserData = UserData; body._enabled = _enabled; body._fixedRotation = _fixedRotation; body._sleepingAllowed = _sleepingAllowed; body._linearDamping = _linearDamping; body._angularDamping = _angularDamping; body._awake = _awake; body.IsBullet = IsBullet; body.IgnoreCCD = IgnoreCCD; body.IgnoreGravity = IgnoreGravity; body._torque = _torque; return(body); }
private Entity Raycast(float3 fromPosition, float3 toPosition) { PhysicsWorld physicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld; RaycastInput raycastInput = new RaycastInput() { Start = fromPosition, End = toPosition, Filter = CollisionFilter.Default }; Unity.Physics.RaycastHit raycastHit; if (physicsWorld.CastRay(raycastInput, out raycastHit)) { Entity hitEntity = raycastHit.Entity; return(hitEntity); } else { return(Entity.Null); } }
//------------------------------------------------------ // Load Scene //------------------------------------------------------ public void load(PhysicsWorld physics_world, float near_plane) { _material_manager = new MaterialManager(); _light_manager = new LightManager(); _world_loader = new WorldLoader(_path_scene, "light_objects", physics_world, _material_manager); // Load Scenes _world_loader.addWorldToScene(new string[] { "sponza", //"test_scene", //"test_scene_2", }, _meshes, _light_manager); load_Flashlight(); load_SunLight(near_plane); _animation_timer.start(); _circadian_timer.start(); }
private void OnRenderInternal(object sender, FrameEventArgs e) { long newTime = time.ElapsedMilliseconds; long delta = (newTime - lastTime); if (delta > 0) { Fps = Fps * 0.95f + (1000f / delta) * 0.05f; } lastTime = newTime; var window = (GameWindow)sender; GL.Viewport(0, 0, window.Width, window.Height); GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); OnDraw(Time); window.SwapBuffers(); if (PhysicsWorld != null) { PhysicsWorld.StepSimulation(DT); } }
public bool GetInputPos(out float3 resultPos) { resultPos = new float3(0, 0, 0); Ray ray = Camera.ScreenPointToRay(Input.mousePosition); var world = World.DefaultGameObjectInjectionWorld; PhysicsWorld physicsWorld = world.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld; var raycastInput = new RaycastInput { Start = ray.origin, End = ray.origin + ray.direction * int.MaxValue, Filter = CollisionFilter.Default }; if (!physicsWorld.CastRay(raycastInput, out var result)) { return(false); } resultPos = result.Position; return(true); }
private static void CreateConstraint(PhysicsWorld world, float3 up, int hitRigidBodyIndex, ColliderKey hitColliderKey, float3 hitPosition, float3 hitSurfaceNormal, float hitDistance, float skinWidth, float maxSlopeCos, ref NativeArray <SurfaceConstraintInfo> constraints, ref int numConstraints) { CreateConstraintFromHit(world, hitRigidBodyIndex, hitColliderKey, hitPosition, hitSurfaceNormal, hitDistance, skinWidth, out SurfaceConstraintInfo constraint); // Check if max slope plane is required float verticalComponent = math.dot(constraint.Plane.Normal, up); bool shouldAddPlane = verticalComponent > k_SimplexSolverEpsilon && verticalComponent < maxSlopeCos; if (shouldAddPlane) { AddMaxSlopeConstraint(up, ref constraint, ref constraints, ref numConstraints); } // Prepare velocity to resolve penetration ResolveConstraintPenetration(ref constraint); // Add original constraint to the list constraints[numConstraints++] = constraint; }
void createTrails(PhysicsWorld localWorld, Color color) { //UnityEngine.Material material = new UnityEngine.Material(Shader.Find("Lightweight-Default")); //material.color = color; foreach (var body in localWorld.DynamicBodies) { GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere); go.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); //go.GetComponent<Renderer>().material = material; go.transform.position = new Vector3( body.WorldFromBody.pos.x, body.WorldFromBody.pos.y, body.WorldFromBody.pos.z); go.transform.rotation = new Quaternion( body.WorldFromBody.rot.value.x, body.WorldFromBody.rot.value.y, body.WorldFromBody.rot.value.z, body.WorldFromBody.rot.value.w); go.transform.SetParent(transform, true); } }
public static void CreateConstraintFromHit(PhysicsWorld world, ColliderKey key, int rigidbodyIndex, float3 position, float3 velocity, float3 normal, float distance, float deltaTime, out SurfaceConstraintInfo constraint) { bool dynamicBody = 0 <= rigidbodyIndex && rigidbodyIndex < world.NumDynamicBodies; constraint = new SurfaceConstraintInfo { Plane = new Plane { Normal = normal, Distance = distance }, RigidBodyIndex = rigidbodyIndex, ColliderKey = key, HitPosition = position, Velocity = dynamicBody ? world.MotionVelocities[rigidbodyIndex].LinearVelocity : velocity }; if (distance < 0.0f) { constraint.Velocity = constraint.Velocity - constraint.Plane.Normal * distance; } }
/// <summary> /// Attaches the bodies with revolute joints. /// </summary> /// <param name="world">The world.</param> /// <param name="bodies">The bodies.</param> /// <param name="localAnchorA">The local anchor A.</param> /// <param name="localAnchorB">The local anchor B.</param> /// <param name="connectFirstAndLast">if set to <c>true</c> [connect first and last].</param> /// <param name="collideConnected">if set to <c>true</c> [collide connected].</param> public static List <RevoluteJoint> AttachBodiesWithRevoluteJoint(PhysicsWorld world, List <Body> bodies, Vector2 localAnchorA, Vector2 localAnchorB, bool connectFirstAndLast, bool collideConnected) { List <RevoluteJoint> joints = new List <RevoluteJoint>(bodies.Count + 1); for (int i = 1; i < bodies.Count; i++) { RevoluteJoint joint = new RevoluteJoint(bodies[i], bodies[i - 1], localAnchorA, localAnchorB); joint.CollideConnected = collideConnected; world.AddJoint(joint); joints.Add(joint); } if (connectFirstAndLast) { RevoluteJoint lastjoint = new RevoluteJoint(bodies[0], bodies[bodies.Count - 1], localAnchorA, localAnchorB); lastjoint.CollideConnected = collideConnected; world.AddJoint(lastjoint); joints.Add(lastjoint); } return(joints); }
public static Vector3 ObstacleAvoidance(Vector3 currentVelocity, Vector3 position, float steeringForce, float distance, PhysicsWorld pWorld) { var rot = Quaternion.LookRotation(currentVelocity.normalized, Vector3.up); var ahead = position + (currentVelocity.normalized * distance); var start = position + (currentVelocity.normalized * -.5f); var startLeft = start + (rot * new Vector3(-.55f, 0, 0)); var aheadLeft = ahead + (rot * new Vector3(-.55f, 0, 0)); var startRight = start + (rot * new Vector3(.55f, 0, 0)); var aheadRight = ahead + (rot * new Vector3(.55f, 0, 0)); var(leftHit, _, _, leftObjectPos) = Raycast(startLeft, aheadLeft, 2, pWorld); var(rightHit, _, _, rightObjectPos) = Raycast(startRight, aheadRight, 2, pWorld); var(topHit, _, _, topObjectPos) = Raycast(aheadLeft, aheadRight, 2, pWorld); if (!leftHit && !rightHit && !topHit) { return(new Vector3()); } var avoidance = ahead; if (leftHit) { avoidance -= leftObjectPos; } else if (rightHit) { avoidance -= rightObjectPos; } else { avoidance -= topObjectPos; } avoidance.y = 0; return(avoidance * steeringForce); }
/// <summary>Extension method for PhysicsWorld, checking for a valid /// position by raycasting onto the surface layer from the passed /// position. Returns true if the raycast is successful and a position /// via out.</summary> public static bool GetPointOnSurfaceLayer(this PhysicsWorld physicsWorld, LocalToWorld localToWorld, float3 position, out float3 pointOnSurface, float obstacleRaycastDistanceMax, int colliderLayer, int surfaceLayer) { var rayInput = new RaycastInput() { Start = position + localToWorld.Up * obstacleRaycastDistanceMax, End = position - localToWorld.Up * obstacleRaycastDistanceMax, Filter = new CollisionFilter() { BelongsTo = ToBitMask(colliderLayer), CollidesWith = ToBitMask(surfaceLayer) } }; pointOnSurface = float3.zero; if (physicsWorld.CastRay(rayInput, out var hit)) { pointOnSurface = hit.Position; return(true); } return(false); }
public static Body CreateRectangle(PhysicsWorld world, float width, float height, float density, Vector2 position, object userData = null) { if (width <= 0) { throw new ArgumentOutOfRangeException("width", "Width must be more than 0 meters"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height", "Height must be more than 0 meters"); } Body newBody = CreateBody(world, position); newBody.UserData = userData; Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2); PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density); newBody.CreateFixture(rectangleShape); return(newBody); }
public RobDemo(Image image) : base(image) { Settings.ContactIteration = 20; _combinedParticle = new CombinedParticle(_vertexs, 3, 1, true); PhysicsWorld.AddObject(_combinedParticle); // 为顶点绑定形状 foreach (var vertex in _combinedParticle.Vertexs) { vertex.BindShape(new Circle(4.ToSimUnits())); } // 增加边缘 PhysicsWorld.CreatePolygonEdge(_edgePoints.ToArray()); // 增加重力 PhysicsWorld.CreateGravity(9.8); DrawQueue.Add(this); Start = true; }
internal void UpdatePhysics(float dt) { _physicsAccumulator += dt; while (_physicsAccumulator >= _physicsTimeStep) { for (int i = _objects.Count - 1; i >= 0; i--) { if (_objects[i].Destroying) { _objects[i].OnDestroyInternal(); _objects[i] = null; _objects.RemoveAt(i); } else { _objects[i].FixedUpdateInternal(); } } PhysicsWorld.Step(_physicsTimeStep); _contactListener.NotifyObjects(); _physicsAccumulator -= _physicsTimeStep; } }
/// <summary> /// Destroys a joint, removing it from the region. /// </summary> /// <param name="joint">The join to remove.</param> public void DestroyJoint(InternalBaseJoint joint) { Joints.Remove(joint); joint.One.Joints.Remove(joint); joint.Two.Joints.Remove(joint); joint.Disable(); if (joint is BaseJoint pjoint) { if (pjoint.CurrentJoint != null) { try { PhysicsWorld.Remove(pjoint.CurrentJoint); } catch (Exception ex) { // We don't really care... Utilities.CheckException(ex); } } } SendToAll(new DestroyJointPacketOut(joint)); }
public void WorldTest() { { var world = new PhysicsWorld(staticBodyCount: 4, dynamicBodyCount: 10, jointCount: 23); Assert.AreEqual(4, world.StaticBodyCount); Assert.AreEqual(10, world.DynamicBodyCount); Assert.AreEqual(14, world.BodyCount); Assert.AreEqual(23, world.JointCount); world.Reset(0, 0, 0); Assert.AreEqual(0, world.StaticBodyCount); Assert.AreEqual(0, world.DynamicBodyCount); Assert.AreEqual(0, world.BodyCount); Assert.AreEqual(0, world.JointCount); world.Dispose(); } { // World clone. var world = new PhysicsWorld(staticBodyCount: 40, dynamicBodyCount: 100, jointCount: 200); Assert.AreEqual(40, world.StaticBodyCount); Assert.AreEqual(100, world.DynamicBodyCount); Assert.AreEqual(140, world.BodyCount); Assert.AreEqual(200, world.JointCount); var worldClone = world.Clone(); Assert.AreEqual(40, worldClone.StaticBodyCount); Assert.AreEqual(100, worldClone.DynamicBodyCount); Assert.AreEqual(140, worldClone.BodyCount); Assert.AreEqual(200, worldClone.JointCount); worldClone.Dispose(); world.Dispose(); } }
public void RotatedColliderCast_Against_RotatedBox_Test( [Values(0f, 10f, -20f, 30f, 40f)] float startX) { // Simulate the physics. SimulatePhysics(); var aabb = RotatedBox.Aabb; Assert.IsTrue(startX < aabb.Min.x); var start = new float2(startX, 0f); var expectedPosition = new float2(aabb.Min.x + ColliderEpsilon, 0f); // Set-up the query. var geometry = new BoxGeometry { Size = new float2(BoxSize) }; using (var colliderBlob = PhysicsBoxCollider.Create(geometry, CollisionFilter.Default, PhysicsMaterial.Default)) { var input = new ColliderCastInput { Start = start, End = expectedPosition, Rotation = float2x2.Rotate(math.radians(BoxRotation)), Collider = colliderBlob }; // Perform the query. var results = PhysicsWorld.CastCollider(input, out ColliderCastHit hit); Assert.IsTrue(results); Assert.IsTrue(hit.PhysicsBodyIndex != PhysicsBody.Constants.InvalidBodyIndex, "PhysicsBody Index is Invalid."); Assert.AreEqual(hit.Entity, RotatedBox.Entity, "Entity is invalid."); PhysicsAssert.AreEqual(expectedPosition, hit.Position, QueryEpsilon, "Hit position is incorrect."); } }
public SimplexTerrainComponent(PhysicsWorld physicsWorld) : base(physicsWorld) { rHeights = new float[4]; int numberOfOctaves = 8; octaves = new OpenSimplexNoise[numberOfOctaves]; frequencys = new double[numberOfOctaves]; amplitudes = new double[numberOfOctaves]; for (int i = 0; i < 8; i++) { tmpVec[i] = new Vector2f(); } for (int i = 0; i < numberOfOctaves; i++) { octaves[i] = new OpenSimplexNoise(666); frequencys[i] = (float)System.Math.Pow(2, i); amplitudes[i] = (float)System.Math.Pow(0.5f, octaves.Length - i); } //Texture splat = AssetManager.LoadTexture("C:\\Users\\User\\Desktop\\test_0_1.png"); ///terrainMaterial.SetValue(TerrainMaterial.TEXTURE_SPLAT, splat); //terrainMaterial.SetValue(Material.COLOR_DIFFUSE, new Vector4f(0.2f, 0.7f, 0.2f, 1.0f)); Texture grass = AssetManager.LoadTexture(Assets.AssetManager.GetAppPath() + "\\textures\\grass4.jpg"); Texture grass_nrm = AssetManager.LoadTexture(Assets.AssetManager.GetAppPath() + "\\textures\\grass_NRM.jpg"); Texture dirt = AssetManager.LoadTexture(Assets.AssetManager.GetAppPath() + "\\textures\\dirt.jpg"); Texture dirt_nrm = AssetManager.LoadTexture(Assets.AssetManager.GetAppPath() + "\\textures\\dirt_NRM.jpg"); terrainMaterial.SetValue(TerrainMaterial.TEXTURE_DIFFUSE0, grass); terrainMaterial.SetValue(TerrainMaterial.TEXTURE_NORMAL0, grass_nrm); terrainMaterial.SetValue(TerrainMaterial.TEXTURE_DIFFUSE_SLOPE, dirt); terrainMaterial.SetValue(TerrainMaterial.TEXTURE_NORMAL_SLOPE, dirt_nrm); terrainMaterial.SetValue(Material.MATERIAL_CASTSHADOWS, false); terrainMaterial.SetValue(Material.SHININESS, 0.1f); terrainMaterial.SetValue(Material.ROUGHNESS, 0.08f); }
protected override void OnUpdate() { RaycastHit rayCastInfos; PhysicsWorld pw = physicSystem.PhysicsWorld; //Get Player InputsComponents InputComponent input = entityManager.GetComponentData <InputComponent>(GameVariables.Player.Entity); //Create ray cast UnityEngine.Ray camRay = GameVariables.MainCamera.ScreenPointToRay(input.Mouse); RaycastInput rayInfo = new RaycastInput { Start = camRay.origin, End = camRay.GetPoint(2000), Filter = new CollisionFilter { BelongsTo = 1u << 31, CollidesWith = 1u << 30, GroupIndex = 0 } }; //Create TargetData TargetData target = new TargetData(); //Do ray cast if (pw.CastRay(rayInfo, out rayCastInfos)) { var newPos = rayCastInfos.Position; newPos.x += 0.5f; newPos.y = 0f; target.Value = newPos; } //Set Player new TargetData entityManager.SetComponentData(GameVariables.Player.Entity, target); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { ComponentManager = new ComponentManager(); ComponentManager.DelayedAdd(new Logger()); PhysicsWorld = new PhysicsWorld(); ComponentManager.DelayedAdd(PhysicsWorld); GameObjectManager = new ComponentManager <GameObject>(); ComponentManager.DelayedAdd(GameObjectManager); PrefabFactory = new PrefabFactory(GameObjectManager); ComponentManager.DelayedAdd(PrefabFactory); ComponentManager.Start(); Input = new InputManager(this); Components.Add(Input); Input.AddButton("shoot", new InputButton(Keys.Space)); IsMouseVisible = true; base.Initialize(); }
/// <summary> /// Use this as constructor. /// </summary> protected override void Initialize() { #if WINDOWS // Set console title. Console.Title = "Client"; IsMouseVisible = true; #else #endif // Initialize Members // ClientNetworkManager = new ClientNetworkManager(this); ClientNetworkManager.Connect("Vita", "10.17.23.15"); //TODO: find connections SpriteBatch = new SpriteBatch(GraphicsDevice); TileMap = new TileMap(this); Camera = new Camera(ScreenSize); #if PSM Camera.ConstrainToMap(TileMap, PSMScreenSize); #else Camera.ConstrainToMap(TileMap); #endif PhysicsWorld = new PhysicsWorld(this); ControllablePlayer = new ControllablePlayer(this, PhysicsWorld, ClientNetworkManager); Camera.Focus = ControllablePlayer; // Subscribe to network events // ClientNetworkManager.onPlayerConnected += ClientNetworkManager_OnPlayerConnected; ClientNetworkManager.onPlayerDisconnected += ClientNetworkManager_OnPlayerDisconnected; ClientNetworkManager.onPlayerMove += ClientNetworkManager_OnPlayerMove; ClientNetworkManager.onLocalPlayerConnected += ClientNetworkManager_OnLocalPlayerConnected; ClientNetworkManager.onPlayerAttack += ClientNetworkManager_OnPlayerAttack; // Initialize XNA base engine. base.Initialize(); }
public override void Init() { ShadowMappingComponent smc; RenderManager.AddComponent(smc = new ShadowMappingComponent(cam, Environment, new int[] { 2048, 1024 })); smc.RenderMode = ShadowMappingComponent.ShadowRenderMode.Forward; // Node floor = (Node)AssetManager.LoadModel(AssetManager.GetAppPath() + "\\models\\scene.apx"); // rootNode.AddChild(floor); // PhysicsWorld.AddObject(floor, 0); Geometry cube = new Geometry(MeshFactory.CreateCube(new Vector3f(-15, -0.5f, -15f), new Vector3f(15f, 0.5f, 15f))); rootNode.AddChild(cube); PhysicsWorld.AddObject(cube, 0); Node n = (Node)AssetManager.LoadModel(AssetManager.GetAppPath() + "\\models\\monkeyhq.obj"); n.SetLocalTranslation(new Vector3f(0, 50, 0)); rootNode.AddChild(n); //PhysicsWorld.AddObject(n, 5, Scene.Physics.PhysicsWorld.PhysicsShape.Box); PhysicsWorld.AddCharacter((DefaultCamera)cam, InputManager, n, 1); }
// collects data related to player collisions private JobHandle InitCollectBulletDataJob(ref ISimulation sim, ref PhysicsWorld world, JobHandle deps, ObjectType target, ObjectType bullet) { // first arg is max capacity, setting as max possible collision pairs collisions.Add(target, new NativeMultiHashMap <Entity, CollisionInfo>( groups[(int)bullet].CalculateEntityCount() * groups[(int)target].CalculateEntityCount(), Allocator.TempJob)); damageMaps.Add(bullet, new NativeHashMap <Entity, BulletDamage>( groups[(int)bullet].CalculateEntityCount(), Allocator.TempJob)); JobHandle copyDamageJob = new CopyBulletDamageJob { damageMap = damageMaps[bullet].AsParallelWriter() }.Schedule(groups[(int)bullet], deps); JobHandle collectJob = new CollectHitsJob { world = buildPhysWorld.PhysicsWorld.CollisionWorld, collisions = collisions[target].AsParallelWriter(), targetMask = masks[(int)target], bulletMask = masks[(int)bullet] }.Schedule(sim, ref world, deps); return(JobHandle.CombineDependencies(copyDamageJob, collectJob)); }
public Body(PhysicsWorld world, Vector2?position = null, float rotation = 0, object userdata = null) { FixtureList = new List <Fixture>(); BodyId = _bodyIdCounter++; _world = world; UserData = userdata; GravityScale = 1.0f; BodyType = BodyType.Static; Enabled = true; //FPE note: Also creates proxies in the broadphase _xf.q.Set(rotation); if (position.HasValue) { _xf.p = position.Value; _sweep.C0 = _xf.p; _sweep.C = _xf.p; _sweep.A0 = rotation; _sweep.A = rotation; } world.AddBody(this); //FPE note: bodies can't live without a World }
public static unsafe PhysicsWorld GenerateRandomWorld(ref Random rnd, int numBodies, float size) { // Create the world PhysicsWorld world = new PhysicsWorld(numBodies, 0, 0); // Create bodies NativeSlice <RigidBody> bodies = world.StaticBodies; for (int i = 0; i < numBodies; i++) { bodies[i] = new RigidBody { WorldFromBody = new RigidTransform { pos = rnd.NextFloat3(-size, size), rot = (rnd.NextInt(10) > 0) ? rnd.NextQuaternionRotation() : quaternion.identity }, Collider = (Collider *)GenerateRandomCollider(ref rnd).GetUnsafePtr(), // Not safe, could be garbage collected Entity = Entity.Null, CustomTags = 0 }; } StaticLayerChangeInfo staticLayerChangeInfo = new StaticLayerChangeInfo(); staticLayerChangeInfo.Init(Allocator.TempJob); staticLayerChangeInfo.NumStaticBodies = numBodies; staticLayerChangeInfo.HaveStaticBodiesChanged = 1; // Build the broadphase world.CollisionWorld.Broadphase.ScheduleBuildJobs(ref world, timeStep: 1.0f, gravity: -9.81f * math.up(), numThreadsHint: 1, ref staticLayerChangeInfo, inputDeps: new JobHandle()).Complete(); staticLayerChangeInfo.Deallocate(); return(world); }
unsafe IntPtr CreateConvexMesh( PhysicsWorld.ConvexHullDecompositionDataItem item ) { IntPtr vertices; int vertexCount; //set vertices { vertexCount = item.Vertices.Length; Vec3* vertices2 = (Vec3*)PhysXNativeWorld.Alloc( item.Vertices.Length * sizeof( Vec3 ) ); for( int n = 0; n < item.Vertices.Length; n++ ) vertices2[ n ] = item.Vertices[ n ]; vertices = (IntPtr)vertices2; } //set indices IntPtr indices; int indexCount; bool indices16Bits = item.Indices.Length < 65535; { indexCount = item.Indices.Length; if( indices16Bits ) { ushort* indices2 = (ushort*)PhysXNativeWorld.Alloc( item.Indices.Length * sizeof( ushort ) ); for( int n = 0; n < item.Indices.Length; n++ ) indices2[ n ] = (ushort)item.Indices[ n ]; indices = (IntPtr)indices2; } else { uint* indices2 = (uint*)PhysXNativeWorld.Alloc( item.Indices.Length * sizeof( uint ) ); for( int n = 0; n < item.Indices.Length; n++ ) indices2[ n ] = (uint)item.Indices[ n ]; indices = (IntPtr)indices2; } } IntPtr pxConvexMesh = PhysXNativeWorld.CreateConvexMesh( vertices, vertexCount, indices, indexCount, indices16Bits ); PhysXNativeWorld.Free( vertices ); PhysXNativeWorld.Free( indices ); return pxConvexMesh; }
public virtual void Unregister(PhysicsWorld physics) { }
void CreateScene() { var cache = ResourceCache; scene = new Scene(); // Create scene subsystem components scene.CreateComponent<Octree>(); physicsWorld = scene.CreateComponent<PhysicsWorld>(); // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene, // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load CameraNode = new Node(); Camera camera = CameraNode.CreateComponent<Camera>(); camera.FarClip = 300.0f; Renderer.SetViewport(0, new Viewport(Context, scene, camera, null)); // Create static scene content. First create a zone for ambient lighting and fog control Node zoneNode = scene.CreateChild("Zone"); Zone zone = zoneNode.CreateComponent<Zone>(); zone.AmbientColor = new Color(0.15f, 0.15f, 0.15f); zone.FogColor = new Color(0.5f, 0.5f, 0.7f); zone.FogStart = 100.0f; zone.FogEnd = 300.0f; zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.0f)); // Create a directional light with cascaded shadow mapping Node lightNode = scene.CreateChild("DirectionalLight"); lightNode.SetDirection(new Vector3(0.3f, -0.5f, 0.425f)); Light light = lightNode.CreateComponent<Light>(); light.LightType = LightType.Directional; light.CastShadows = true; light.ShadowBias = new BiasParameters(0.00025f, 0.5f); light.ShadowCascade = new CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f); light.SpecularIntensity = 0.5f; // Create the floor object Node floorNode = scene.CreateChild("Floor"); floorNode.Position = new Vector3(0.0f, -0.5f, 0.0f); floorNode.Scale = new Vector3(200.0f, 1.0f, 200.0f); StaticModel sm = floorNode.CreateComponent<StaticModel>(); sm.Model = cache.GetModel("Models/Box.mdl"); sm.SetMaterial(cache.GetMaterial("Materials/Stone.xml")); RigidBody body = floorNode.CreateComponent<RigidBody>(); // Use collision layer bit 2 to mark world scenery. This is what we will raycast against to prevent camera from going // inside geometry body.CollisionLayer = 2; CollisionShape shape = floorNode.CreateComponent<CollisionShape>(); shape.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity); // Create mushrooms of varying sizes const uint numMushrooms = 60; for (uint i = 0; i < numMushrooms; ++i) { Node objectNode = scene.CreateChild("Mushroom"); objectNode.Position = new Vector3(NextRandom(180.0f) - 90.0f, 0.0f, NextRandom(180.0f) - 90.0f); objectNode.Rotation = new Quaternion(0.0f, NextRandom(360.0f), 0.0f); objectNode.SetScale(2.0f + NextRandom(5.0f)); StaticModel o = objectNode.CreateComponent<StaticModel>(); o.Model = cache.GetModel("Models/Mushroom.mdl"); o.SetMaterial(cache.GetMaterial("Materials/Mushroom.xml")); o.CastShadows = true; body = objectNode.CreateComponent<RigidBody>(); body.CollisionLayer = 2; shape = objectNode.CreateComponent<CollisionShape>(); shape.SetTriangleMesh(o.Model, 0, Vector3.One, Vector3.Zero, Quaternion.Identity); } // Create movable boxes. Let them fall from the sky at first const uint numBoxes = 100; for (uint i = 0; i < numBoxes; ++i) { float scale = NextRandom(2.0f) + 0.5f; Node objectNode = scene.CreateChild("Box"); objectNode.Position = new Vector3(NextRandom(180.0f) - 90.0f, NextRandom(10.0f) + 10.0f, NextRandom(180.0f) - 90.0f); objectNode.Rotation = new Quaternion(NextRandom(360.0f), NextRandom(360.0f), NextRandom(360.0f)); objectNode.SetScale(scale); StaticModel o = objectNode.CreateComponent<StaticModel>(); o.Model = cache.GetModel("Models/Box.mdl"); o.SetMaterial(cache.GetMaterial("Materials/Stone.xml")); o.CastShadows = true; body = objectNode.CreateComponent<RigidBody>(); body.CollisionLayer = 2; // Bigger boxes will be heavier and harder to move body.Mass = scale * 2.0f; shape = objectNode.CreateComponent<CollisionShape>(); shape.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity); } }
protected override void OnUpdate(float timeStep) { Input input = Input; if (character != null) { // Clear previous controls character.Controls.Set(CtrlForward | CtrlBack | CtrlLeft | CtrlRight | CtrlJump, false); // Update controls using touch utility class touch?.UpdateTouches(character.Controls); // Update controls using keys if (UI.FocusElement == null) { if (touch == null || !touch.UseGyroscope) { character.Controls.Set(CtrlForward, input.GetKeyDown(Key.W)); character.Controls.Set(CtrlBack, input.GetKeyDown(Key.S)); character.Controls.Set(CtrlLeft, input.GetKeyDown(Key.A)); character.Controls.Set(CtrlRight, input.GetKeyDown(Key.D)); } character.Controls.Set(CtrlJump, input.GetKeyDown(Key.Space)); // Add character yaw & pitch from the mouse motion or touch input if (TouchEnabled) { for (uint i = 0; i < input.NumTouches; ++i) { TouchState state = input.GetTouch(i); if (state.TouchedElement == null) // Touch on empty space { Camera camera = CameraNode.GetComponent<Camera>(); if (camera == null) return; var graphics = Graphics; character.Controls.Yaw += TouchSensitivity * camera.Fov / graphics.Height * state.Delta.X; character.Controls.Pitch += TouchSensitivity * camera.Fov / graphics.Height * state.Delta.Y; } } } else { character.Controls.Yaw += (float)input.MouseMove.X * YawSensitivity; character.Controls.Pitch += (float)input.MouseMove.Y * YawSensitivity; } // Limit pitch character.Controls.Pitch = MathHelper.Clamp(character.Controls.Pitch, -80.0f, 80.0f); // Switch between 1st and 3rd person if (input.GetKeyPress(Key.F)) firstPerson = !firstPerson; // Turn on/off gyroscope on mobile platform if (touch != null && input.GetKeyPress(Key.G)) touch.UseGyroscope = !touch.UseGyroscope; if (input.GetKeyPress(Key.F5)) { scene.SaveXml(FileSystem.ProgramDir + "Data/Scenes/CharacterDemo.xml", "\t"); } if (input.GetKeyPress(Key.F7)) { scene.LoadXml(FileSystem.ProgramDir + "Data/Scenes/CharacterDemo.xml"); Node characterNode = scene.GetChild("Jack", true); if (characterNode != null) { character = characterNode.GetComponent<Character>(); } physicsWorld = scene.CreateComponent<PhysicsWorld>(); physicsWorld.SubscribeToPhysicsPreStep(HandlePhysicsPreStep); } } // Set rotation already here so that it's updated every rendering frame instead of every physics frame if (character != null) character.Node.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, character.Controls.Yaw); } }
protected virtual JobHandle ScheduleTriggerEventsJob(DisplayTriggerEventsJob job, ISimulation simulation, ref PhysicsWorld world, JobHandle inDeps) { // Explicitly call ScheduleImpl here, to avoid a dependency on Havok.Physics return(job.ScheduleImpl(simulation, ref world, inDeps)); }
unsafe IntPtr CreateTriangleMesh( PhysicsWorld._MeshGeometry geometry ) { byte[] cookedData = null; //try get cooked triangle mesh from cache if( !geometry.CreatedAsCustomMeshGeometry ) cookedData = GetCookedTriangleMeshFromCache( geometry.Vertices, geometry.Indices, geometry.MaterialIndices ); if( cookedData == null ) { //cook triangle mesh //set vertices IntPtr vertices; int vertexCount; { vertexCount = geometry.Vertices.Length; Vec3* vertices2 = (Vec3*)PhysXNativeWorld.Alloc( geometry.Vertices.Length * sizeof( Vec3 ) ); for( int n = 0; n < geometry.Vertices.Length; n++ ) vertices2[ n ] = geometry.Vertices[ n ]; vertices = (IntPtr)vertices2; } //set indices IntPtr indices; int indexCount; bool indices16Bits = geometry.Indices.Length < 65535; { indexCount = geometry.Indices.Length; if( indices16Bits ) { ushort* indices2 = (ushort*)PhysXNativeWorld.Alloc( geometry.Indices.Length * sizeof( ushort ) ); for( int n = 0; n < geometry.Indices.Length; n++ ) indices2[ n ] = (ushort)geometry.Indices[ n ]; indices = (IntPtr)indices2; } else { uint* indices2 = (uint*)PhysXNativeWorld.Alloc( geometry.Indices.Length * sizeof( uint ) ); for( int n = 0; n < geometry.Indices.Length; n++ ) indices2[ n ] = (uint)geometry.Indices[ n ]; indices = (IntPtr)indices2; } } //material indices IntPtr materialIndices = IntPtr.Zero; if( geometry.MaterialIndices != null ) { short* materialIndices2 = (short*)PhysXNativeWorld.Alloc( geometry.MaterialIndices.Length * sizeof( short ) ); for( int n = 0; n < geometry.MaterialIndices.Length; n++ ) materialIndices2[ n ] = geometry.MaterialIndices[ n ]; materialIndices = (IntPtr)materialIndices2; } IntPtr cookedNativeData; int cookedLength; bool cookResult = PhysXNativeWorld.CookTriangleMesh( vertices, vertexCount, indices, indexCount, indices16Bits, materialIndices, out cookedNativeData, out cookedLength ); PhysXNativeWorld.Free( vertices ); PhysXNativeWorld.Free( indices ); if( materialIndices != IntPtr.Zero ) PhysXNativeWorld.Free( materialIndices ); if( !cookResult ) return IntPtr.Zero; cookedData = new byte[ cookedLength ]; Marshal.Copy( cookedNativeData, cookedData, 0, cookedLength ); PhysXNativeWorld.Free( cookedNativeData ); //write to cache if( PhysXPhysicsWorld.Instance.writeCacheForCookedTriangleMeshes && !geometry.CreatedAsCustomMeshGeometry ) WriteCookedTriangleMeshToCache( geometry.Vertices, geometry.Indices, geometry.MaterialIndices, cookedData ); } //create triangle mesh IntPtr triangleMesh; fixed( byte* pCookedData = cookedData ) { triangleMesh = PhysXNativeWorld.CreateTriangleMesh( (IntPtr)pCookedData, cookedData.Length ); } return triangleMesh; }