Пример #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);
            }
        }
Пример #2
0
        [FieldOffset(0x00D4)] public float                ShadowNearClip; // default: 0.1

        public static CLightDrawData *New(eLightType type, eLightFlags flags, Vector3 position, RGB color, float intensity)
        {
            const float ByteToFloatFactor = 1.0f / 255.0f;

            CLightDrawData *d = GameFunctions.GetFreeLightDrawDataSlotFromQueue();

            NativeVector3        pos = position;
            NativeColorRGBAFloat col = new NativeColorRGBAFloat {
                R = color.R * ByteToFloatFactor, G = color.G * ByteToFloatFactor, B = color.B * ByteToFloatFactor
            };

            GameFunctions.InitializeLightDrawData(d, type, (uint)flags, &pos, &col, intensity, 0xFFFFFF);

            return(d);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #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);
            }
        }