Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }