private List <RayCastResult> DoRayCast(TESObjectCELL cell, float[] source, float[] target) { return(cell.RayCast(new RayCastParameters() { Begin = source, End = target })); }
internal bool CanPlaceGrass(TESObjectCELL cell, TESObjectLAND land, float x, float y, float z) { if (cell == null) { return(true); } // Currently not dealing with this. if (cell.IsInterior || !cell.IsAttached) { return(true); } var rp = new RayCastParameters(); rp.Begin = new float[] { x, y, z + this.RayHeight }; rp.End = new float[] { x, y, z - this.RayDepth }; rp.Cell = cell; var rs = TESObjectCELL.RayCast(rp); foreach (var r in rs) { if (r.Fraction >= 1.0f || r.HavokObject == IntPtr.Zero) { continue; } uint flags = Memory.ReadUInt32(r.HavokObject + 0x2C) & 0x7F; ulong mask = (ulong)1 << (int)flags; if ((this.RaycastMask & mask) == 0) { continue; } if (this.Ignore != null && this.IsIgnoredObject(r)) { continue; } return(false); } return(true); }
internal static bool Apply(CameraUpdate update, NiTransform transform, NiPoint3 result) { init(); if (update == null || transform == null || result == null) { return(false); } if (update.Values.CollisionEnabled.CurrentValue < 0.5) { return(false); } var actor = update.Target.Actor; if (actor == null) { return(false); } var cell = actor.ParentCell; if (cell == null) { return(false); } float safety = (float)(update.Values.NearClip.CurrentValue + 1.0); if (safety < 1.0f) { safety = 1.0f; } float safety2 = Math.Max(0.0f, Settings.Instance.CameraCollisionSafety); var tpos = transform.Position; TempPoint1.CopyFrom(actor.Position); TempPoint1.Z = tpos.Z; if (safety2 > 0.0f) { TempSafety.Y = -safety2 * 0.5f; TempTransform.CopyFrom(transform); TempTransform.Position.CopyFrom(TempPoint1); TempTransform.Translate(TempSafety, TempPoint1); } TempNormal.X = tpos.X - TempPoint1.X; TempNormal.Y = tpos.Y - TempPoint1.Y; TempNormal.Z = tpos.Z - TempPoint1.Z; float len = TempNormal.Length; if (len <= 0.0f) { return(false); } TempNormal.Normalize(TempNormal); TempNormal.Multiply(len + safety + safety2, TempNormal); TempPoint2.X = TempPoint1.X + TempNormal.X; TempPoint2.Y = TempPoint1.Y + TempNormal.Y; TempPoint2.Z = TempPoint1.Z + TempNormal.Z; var ls = TESObjectCELL.RayCast(new RayCastParameters() { Cell = cell, Begin = new float[] { TempPoint1.X, TempPoint1.Y, TempPoint1.Z }, End = new float[] { TempPoint2.X, TempPoint2.Y, TempPoint2.Z } }); if (ls == null || ls.Count == 0) { return(false); } RayCastResult best = null; float bestDist = 0.0f; List <NiAVObject> ignore = new List <NiAVObject>(3); { var sk = actor.GetSkeletonNode(true); if (sk != null) { ignore.Add(sk); } } { var sk = actor.GetSkeletonNode(false); if (sk != null) { ignore.Add(sk); } } if (update.CachedMounted) { var mount = actor.GetMount(); if (mount != null) { var sk = mount.GetSkeletonNode(false); if (sk != null) { ignore.Add(sk); } } } foreach (var r in ls) { if (!IsValid(r, ignore)) { continue; } float dist = r.Fraction; if (best == null) { best = r; bestDist = dist; } else if (dist < bestDist) { best = r; bestDist = dist; } } if (best == null) { return(false); } bestDist *= len + safety + safety2; bestDist -= safety + safety2; bestDist /= len + safety + safety2; // Negative is ok! result.X = (TempPoint2.X - TempPoint1.X) * bestDist + TempPoint1.X; result.Y = (TempPoint2.Y - TempPoint1.Y) * bestDist + TempPoint1.Y; result.Z = (TempPoint2.Z - TempPoint1.Z) * bestDist + TempPoint1.Z; return(true); }