void OnPostUpdate(PostUpdateEventArgs args) { Graphics graphics = application.Graphics; var now = DateTime.UtcNow; span += now - dateTime; dateTime = now; if (++frameCount >= FrameSampleCount) { float average = (float)(span.TotalMilliseconds / frameCount); float fps = 1000; if (average != 0) { fps /= average; } frameCount = 0; span = TimeSpan.Zero; if (FpsOnly) { text.Value = $"{(int)fps} FPS\n{AdditionalText}"; } else if (!InnerCacheDetails) { text.Value = $"{(int)fps} FPS\n{graphics.NumBatches} batches\n{Runtime.RefCountedCache.Count} MCW\n{AdditionalText}"; } else { text.Value = $"{(int)fps} FPS\n{graphics.NumBatches} batches\n{Runtime.RefCountedCache.GetCacheStatus()}\n{AdditionalText}"; } } }
void HandlePostUpdate(PostUpdateEventArgs args) { if (character == null) { return; } Node characterNode = character.Node; // Get camera lookat dir from character yaw + pitch Quaternion rot = characterNode.Rotation; Quaternion dir = rot * Quaternion.FromAxisAngle(Vector3.UnitX, character.Controls.Pitch); // Turn head to camera pitch, but limit to avoid unnatural animation Node headNode = characterNode.GetChild("Bip01_Head", true); if (headNode != null) { float limitPitch = MathHelper.Clamp(character.Controls.Pitch, -45.0f, 45.0f); Quaternion headDir = rot * Quaternion.FromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), limitPitch); // This could be expanded to look at an arbitrary target, now just look at a point in front Vector3 headWorldTarget = headNode.WorldPosition + headDir * new Vector3(0.0f, 0.0f, 1.0f); headNode.LookAt(headWorldTarget, new Vector3(0.0f, 1.0f, 0.0f), TransformSpace.World); // Correct head orientation because LookAt assumes Z = forward, but the bone has been authored differently (Y = forward) headNode.Rotate(new Quaternion(0.0f, 90.0f, 90.0f), TransformSpace.Local); } if (firstPerson) { if (headNode != null) { CameraNode.Position = headNode.WorldPosition + rot * new Vector3(0.0f, 0.15f, 0.2f); CameraNode.Rotation = dir; } } else { // Third person camera: position behind the character Vector3 aimPoint = characterNode.Position + rot * new Vector3(0.0f, 1.7f, 0.0f); // Collide camera ray with static physics objects (layer bitmask 2) to ensure we see the character properly Vector3 rayDir = dir * new Vector3(0f, 0f, -1f); float rayDistance = touch != null ? touch.CameraDistance : CameraInitialDist; PhysicsRaycastResult result = new PhysicsRaycastResult(); scene.GetComponent <PhysicsWorld>().RaycastSingle(ref result, new Ray(aimPoint, rayDir), rayDistance, 2); if (result.Body != null) { rayDistance = Math.Min(rayDistance, result.Distance); } rayDistance = MathHelper.Clamp(rayDistance, CameraMinDist, CameraMaxDist); CameraNode.Position = aimPoint + rayDir * rayDistance; CameraNode.Rotation = dir; } }
void HandlePostUpdate(PostUpdateEventArgs args) { if (character == null) return; Node characterNode = character.Node; // Get camera lookat dir from character yaw + pitch Quaternion rot = characterNode.Rotation; Quaternion dir = rot * Quaternion.FromAxisAngle(Vector3.UnitX, character.Controls.Pitch); // Turn head to camera pitch, but limit to avoid unnatural animation Node headNode = characterNode.GetChild("Bip01_Head", true); float limitPitch = MathHelper.Clamp(character.Controls.Pitch, -45.0f, 45.0f); Quaternion headDir = rot * Quaternion.FromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), limitPitch); // This could be expanded to look at an arbitrary target, now just look at a point in front Vector3 headWorldTarget = headNode.WorldPosition + headDir * new Vector3(0.0f, 0.0f, 1.0f); headNode.LookAt(headWorldTarget, new Vector3(0.0f, 1.0f, 0.0f), TransformSpace.World); // Correct head orientation because LookAt assumes Z = forward, but the bone has been authored differently (Y = forward) headNode.Rotate(new Quaternion(0.0f, 90.0f, 90.0f), TransformSpace.Local); if (firstPerson) { CameraNode.Position = headNode.WorldPosition + rot * new Vector3(0.0f, 0.15f, 0.2f); CameraNode.Rotation = dir; } else { // Third person camera: position behind the character Vector3 aimPoint = characterNode.Position + rot * new Vector3(0.0f, 1.7f, 0.0f); // Collide camera ray with static physics objects (layer bitmask 2) to ensure we see the character properly Vector3 rayDir = dir * new Vector3(0f, 0f, -1f); float rayDistance = touch != null ? touch.CameraDistance : CameraInitialDist; PhysicsRaycastResult result = new PhysicsRaycastResult(); scene.GetComponent<PhysicsWorld>().RaycastSingle(ref result, new Ray(aimPoint, rayDir), rayDistance, 2); if (result.Body != null) rayDistance = Math.Min(rayDistance, result.Distance); rayDistance = MathHelper.Clamp(rayDistance, CameraMinDist, CameraMaxDist); CameraNode.Position = aimPoint + rayDir * rayDistance; CameraNode.Rotation = dir; } }
void OnPostUpdate(PostUpdateEventArgs args) { Graphics graphics = application.Graphics; var now = DateTime.UtcNow; span += now - dateTime; dateTime = now; if (++frameCount >= FrameSampleCount) { float average = (float)(span.TotalMilliseconds / frameCount); float fps = 1000; if (average != 0) fps /= average; frameCount = 0; span = TimeSpan.Zero; text.Value = $"{(int)fps} FPS\n{graphics.NumBatches} batches\n{Runtime.KnownObjectsCount} MCW\n" + AdditionalText; } }
void OnPostUpdate(PostUpdateEventArgs args) { Graphics graphics = application.Graphics; var now = DateTime.UtcNow; span += now - dateTime; dateTime = now; if (++frameCount >= FrameSampleCount) { float average = (float)(span.TotalMilliseconds / frameCount); float fps = 1000; if (average != 0) { fps /= average; } frameCount = 0; span = TimeSpan.Zero; text.Value = $"{(int)fps} FPS\n{graphics.NumBatches} batches\n{Runtime.KnownObjectsCount} MCW\n" + AdditionalText; } }