protected internal void DrawLight() { if (!IsActive) { return; } eLightFlags lightFlags = eLightFlags.CanRenderUnderground; if (Data.Volume) { lightFlags |= eLightFlags.EnableVolume; } if (!Data.Specular) { lightFlags |= eLightFlags.DisableSpecular; } if (Data.CastShadows) { // shadows aren't casted in underground areas, such as tunnels, // not sure how to fix this as the game's CSearchLight has the same issue lightFlags |= eLightFlags.EnableShadows; } CLightDrawData *drawData = CLightDrawData.New(eLightType.SPOT_LIGHT, lightFlags, Position, Data.Color, Data.Intensity); NativeVector3 dir = Direction; NativeVector3 perp = Utility.GetPerpendicular(dir).ToNormalized(); drawData->Range = Data.Range; drawData->VolumeIntensity = Data.VolumeIntensity; drawData->VolumeExponent = 70.0f; // doesn't seem to have any effect drawData->VolumeSize = Data.VolumeSize; drawData->FalloffExponent = Data.Falloff; GameFunctions.SetLightDrawDataDirection(drawData, &dir, &perp); GameFunctions.SetLightDrawDataAngles(drawData, Data.InnerAngle, Data.OuterAngle); if (Data.CastShadows) { drawData->ShadowRenderId = shadowId; drawData->ShadowUnkValue = GameFunctions.GetValueForLightDrawDataShadowUnkValue(drawData); } if (Data.Corona) { GameMemory.Coronas->Draw(Position, Data.CoronaSize, Data.Color.Raw, Data.CoronaIntensity, 100.0f, Direction, Data.InnerAngle, Data.OuterAngle, 3); } }
protected internal void DrawLight() { if (!IsActive) { return; } CLightDrawData *drawData = CLightDrawData.New(eLightType.SPOT_LIGHT, Data.Volume ? eLightFlags.VolumeEnabled : eLightFlags.None, Position, Data.Color, Data.Intensity); NativeVector3 dir = Direction; drawData->Range = Data.Range; drawData->VolumeIntensity = Data.VolumeIntensity; drawData->VolumeExponent = 70.0f; // doesn't seem to have any effect drawData->VolumeSize = Data.VolumeSize; drawData->FalloffExponent = Data.Falloff; // this doesn't create a vector exactly like the one created in the original game code, but it looks like the game just wants a vector perpendicular // to the direction vector and while testing this seemed to work fine // if any issue arises, revert to the old code NativeVector3 dirPerpendicular = new Vector3(dir.Y - dir.Z, dir.Z - dir.X, -dir.X - dir.Y).ToNormalized(); GameFunctions.SetLightDrawDataDirection(drawData, &dir, &dirPerpendicular); GameFunctions.SetLightDrawDataAngles(drawData, Data.InnerAngle, Data.OuterAngle); if (Data.CastShadows) { drawData->Flags |= eLightFlags.ShadowsEnabled; drawData->ShadowRenderId = shadowId; drawData->ShadowUnkValue = GameFunctions.GetValueForLightDrawDataShadowUnkValue(drawData); } if (!Data.Specular) { drawData->Flags |= eLightFlags.DisableSpecular; } if (Data.Corona) { // if using pointers referencing a variable inside the method // NativeVector3 p = Position; // DrawCorona(..., &p, ...); // sometimes it crashes, // so we are using these unmanaged pointers *CoronaPositionPtr = Position; *CoronaDirectionPtr = Direction; GameFunctions.DrawCorona(GameMemory.CoronaDrawQueue, CoronaPositionPtr, Data.CoronaSize, Data.Color.Raw, Data.CoronaIntensity, 100.0f, CoronaDirectionPtr, 1.0f, Data.InnerAngle, Data.OuterAngle, 3); } }
public static void RangeLight(Vector3 position, eLightFlags flags, float intensity, float range, float volumeIntensity, float volumeSize, float falloff, Color color, ulong shadowId = 0) { CLightDrawData *drawData = CLightDrawData.New(eLightType.RANGE_2, flags, position, color, intensity); if (volumeIntensity > 0) { drawData->VolumeIntensity = volumeIntensity; drawData->VolumeExponent = 70.0f; drawData->VolumeSize = volumeSize; } drawData->FalloffExponent = falloff; if (shadowId != 0) { drawData->ShadowRenderId = shadowId; drawData->ShadowUnkValue = GameFunctions.GetValueForLightDrawDataShadowUnkValue(drawData); } }
public static void SpotLight(Vector3 position, Vector3 direction, eLightFlags flags, float intensity, float range, float volumeIntensity, float volumeSize, float falloff, float innerAngle, float outerAngle, Color color, ulong shadowId = 0) { CLightDrawData *drawData = CLightDrawData.New(eLightType.SPOT_LIGHT, flags, position, color, intensity); NativeVector3 dir = direction; NativeVector3 perp = Utility.GetPerpendicular(dir).ToNormalized(); drawData->Range = range; if (volumeIntensity > 0) { drawData->VolumeIntensity = volumeIntensity; drawData->VolumeExponent = 70.0f; drawData->VolumeSize = volumeSize; } drawData->FalloffExponent = falloff; GameFunctions.SetLightDrawDataDirection(drawData, &dir, &perp); GameFunctions.SetLightDrawDataAngles(drawData, innerAngle, outerAngle); if (shadowId != 0) { drawData->ShadowRenderId = shadowId; drawData->ShadowUnkValue = GameFunctions.GetValueForLightDrawDataShadowUnkValue(drawData); } }
protected internal void DrawLight() { if (!IsActive) { return; } eLightFlags lightFlags = eLightFlags.CanRenderUnderground; if (Data.Volume) { lightFlags |= eLightFlags.EnableVolume; } if (!Data.Specular) { lightFlags |= eLightFlags.DisableSpecular; } if (Data.CastShadows) { // shadows aren't casted in underground areas, such as tunnels, // not sure how to fix this as the game's CSearchLight has the same issue lightFlags |= eLightFlags.EnableShadows; } CLightDrawData *drawData = CLightDrawData.New(eLightType.SPOT_LIGHT, lightFlags, Position, Data.Color, Data.Intensity); NativeVector3 dir = Direction; drawData->Range = Data.Range; drawData->VolumeIntensity = Data.VolumeIntensity; drawData->VolumeExponent = 70.0f; // doesn't seem to have any effect drawData->VolumeSize = Data.VolumeSize; drawData->FalloffExponent = Data.Falloff; // TODO: figure out how SSE instrinsics work, and what this does NativeVector3 v16 = _mm_andnot_ps(new Vector3(-0.0f, -0.0f, -0.0f), dir); NativeVector3 v17 = _mm_and_ps(_mm_cmple_ps(v16, _mm_shuffle_epi32(v16, -46)), _mm_cmplt_ps(v16, _mm_shuffle_epi32(v16, -55))); NativeVector3 v18 = _mm_and_ps( _mm_or_ps( _mm_andnot_ps( _mm_or_ps( _mm_or_ps(_mm_shuffle_epi32(v17, 85), _mm_shuffle_epi32(v17, 0)), _mm_shuffle_epi32(v17, -86)), new Vector3(Single.NaN, Single.NaN, Single.NaN)), v17), new Vector3(1.0f, 1.0f, 1.0f)); v17 = _mm_shuffle_ps(v18, v18, 85); NativeVector3 v19 = _mm_shuffle_ps(v18, v18, -86); Vector3 v = new Vector3(x: (v19.X * dir.Y) - (v17.X * dir.Z), y: (v18.X * dir.Z) - (v19.X * dir.X), z: (v17.X * dir.X) - (v18.X * dir.Y)); NativeVector3 u = v.ToNormalized(); GameFunctions.SetLightDrawDataDirection(drawData, &dir, &u); GameFunctions.SetLightDrawDataAngles(drawData, Data.InnerAngle, Data.OuterAngle); if (Data.CastShadows) { drawData->ShadowRenderId = shadowId; drawData->ShadowUnkValue = GameFunctions.GetValueForLightDrawDataShadowUnkValue(drawData); } if (Data.Corona) { GameMemory.Coronas->Draw(Position, Data.CoronaSize, Data.Color.Raw, Data.CoronaIntensity, 100.0f, Direction, Data.InnerAngle, Data.OuterAngle, 3); } }