123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using fun.Basics.Shapes;
- using fun.Core;
- using OpenTK;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Environment = fun.Core.Environment;
- namespace fun.Basics
- {
- public sealed class CollidingElement : Element
- {
- private static float GAP = 0.1f;
- private Vector3 lastPos;
- private Vector3 currPos;
- private TransformElement transform;
- private List<ICollider> colliders;
- public CollidingElement(Environment environment, Entity entity)
- : base(environment, entity)
- {
- transform = entity.GetElement<TransformElement>() as TransformElement;
- currPos = transform.Position;
- lastPos = transform.Position;
- }
- public override void Initialize()
- {
- colliders = new List<ICollider>(environment.Entities
- .Where(e => e.ContainsElement<ICollider>())
- .Select(e => e.GetElement<ICollider>() as ICollider));
- }
- public override void Update(double time)
- {
- ICollider colliding = null;
- do
- {
- lastPos = currPos;
- currPos = transform.Position;
- var move = currPos - lastPos;
- var ray = new Ray(lastPos, Vector3.Normalize(move));
- colliding = colliders.FirstOrDefault(c =>
- {
- var distance = c.Intersects(ray);
- return distance.HasValue && move.LengthSquared > (distance.Value * distance.Value);
- });
- if (colliding != null)
- {
-
- var xyz = new
- {
- XP = new Ray(lastPos, Vector3.UnitX),
- YP = new Ray(lastPos, Vector3.UnitY),
- ZP = new Ray(lastPos, Vector3.UnitZ),
- XM = new Ray(lastPos, -Vector3.UnitX),
- YM = new Ray(lastPos, -Vector3.UnitY),
- ZM = new Ray(lastPos, -Vector3.UnitZ)
- };
-
- var distance = new
- {
- X = colliding.Intersects(move.X > 0 ? xyz.XP : xyz.XM),
- Y = colliding.Intersects(move.Y > 0 ? xyz.YP : xyz.YM),
- Z = colliding.Intersects(move.Z > 0 ? xyz.ZP : xyz.ZM)
- };
-
- var isColliding = new
- {
- X = distance.X.HasValue && Math.Abs(move.X) > distance.X.Value,
- Y = distance.Y.HasValue && Math.Abs(move.Y) > distance.Y.Value,
- Z = distance.Z.HasValue && Math.Abs(move.Z) > distance.Z.Value
- };
- float reduction;
-
- if (isColliding.X)
- {
- reduction = distance.X.Value / Math.Abs(move.X);
- move.X *= reduction - GAP;
- }
- else if (isColliding.Y)
- {
- reduction = distance.Y.Value / Math.Abs(move.Y);
- move.Y *= reduction - GAP;
- }
- else if (isColliding.Z)
- {
- reduction = distance.Z.Value / Math.Abs(move.Z);
- move.Z *= reduction - GAP;
- }
- transform.Position = currPos = lastPos + move;
- }
- } while (colliding != null);
- }
- #region old code
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #endregion
- }
- }
|