forked from Mirrors/openclonk
142 lines
5.2 KiB
C++
142 lines
5.2 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2014-2015, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
|
|
#ifndef C4FOWLIGHTSECTION_H
|
|
#define C4FOWLIGHTSECTION_H
|
|
|
|
#ifndef USE_CONSOLE
|
|
|
|
#include "C4Rect.h"
|
|
#include <list>
|
|
|
|
class C4FoWLight;
|
|
class C4FoWRegion;
|
|
class C4FoWBeam;
|
|
class C4FoWBeamTriangle;
|
|
|
|
/** The light section manages the beams for one light for one direction of 90°.
|
|
|
|
For understanding the internal calculations made in this class, note that this class assumes all of its beams to
|
|
go into a positive y-direction (="down" in display coordinates). Only after the calculation, it transforms its
|
|
result into the global coordinate system again by applying a transformation matrix.
|
|
*/
|
|
class C4FoWLightSection
|
|
{
|
|
public:
|
|
C4FoWLightSection(C4FoWLight *pLight, int r);
|
|
~C4FoWLightSection();
|
|
|
|
private:
|
|
|
|
/* Center light */
|
|
C4FoWLight *pLight;
|
|
|
|
/* Transformation matrix */
|
|
int iRot;
|
|
int a, b, c, d;
|
|
int ra, rb, rc, rd;
|
|
|
|
/* This section's beams */
|
|
C4FoWBeam *pBeams;
|
|
|
|
public:
|
|
|
|
/** Recalculate of all light beams within the given rectangle because the landscape changed. */
|
|
void Invalidate(C4Rect r);
|
|
/** Update all light beams within the given rectangle */
|
|
void Update(C4Rect r);
|
|
|
|
|
|
std::list<C4FoWBeamTriangle> CalculateTriangles(C4FoWRegion *region) const;
|
|
|
|
/** Shorten all light beams to the given reach.
|
|
Called when the size of the light has decreased to the given value */
|
|
void Prune(int32_t reach);
|
|
/** Extend all light beams to the given reach.
|
|
Called when the size of the light has increased to the given value */
|
|
void Dirty(int32_t reach);
|
|
|
|
private:
|
|
|
|
/** Remove all beams. pBeams is NULL after that. */
|
|
void ClearBeams();
|
|
|
|
// Beam coordinate to landscape coordinate. Beam coordinates are relative to the light source.
|
|
template <class T> T transDX(T dx, T dy) const;
|
|
template <class T> T transDY(T dx, T dy) const;
|
|
template <class T> T transX(T x, T y) const;
|
|
template <class T> T transY(T x, T y) const;
|
|
|
|
// Landscape coordinate to beam coordinate. Beam coordinates are relative to the light source.
|
|
template <class T> T rtransDX(T dx, T dy) const;
|
|
template <class T> T rtransDY(T dx, T dy) const;
|
|
template <class T> T rtransX(T x, T y) const;
|
|
template <class T> T rtransY(T x, T y) const;
|
|
|
|
/** Convert triangles to landscape coordinates */
|
|
void transTriangles(std::list<C4FoWBeamTriangle> &triangles) const;
|
|
|
|
/** Returns a rectangle in beam coordinates */
|
|
C4Rect rtransRect(C4Rect r) const {
|
|
C4Rect Rect(rtransX(r.x, r.y), rtransY(r.x, r.y),
|
|
rtransDX(r.Wdt, r.Hgt), rtransDY(r.Wdt, r.Hgt));
|
|
Rect.Normalize();
|
|
return Rect;
|
|
}
|
|
|
|
bool isConsistent() const;
|
|
|
|
/** These methods return the position of the left delimiter point of a beam from the origin that would enclose the
|
|
given rectangle. Note that we assume the rect to have a positive Y-position.
|
|
In other words, the given rectangle's right most point when looked at from the origin.
|
|
*/
|
|
inline int32_t RectLeftMostX(const C4Rect &r) const { return r.x; }
|
|
inline int32_t RectLeftMostY(const C4Rect &r) const { return Max(0, r.x >= 0 ? r.y + r.Hgt : r.y); }
|
|
/** These methods return the position of the left delimiter point of a beam from the origin that would enclose the
|
|
given rectangle. Note that we assume the rect to have a positive Y-position.
|
|
In other words, the given rectangle's right most point when looked at from the origin.
|
|
*/
|
|
inline int32_t RectRightMostX(const C4Rect &r) const { return r.x + r.Wdt; }
|
|
inline int32_t RectRightMostY(const C4Rect &r) const { return Max(0, r.x + r.Wdt <= 0 ? r.y + r.Hgt : r.y); }
|
|
|
|
inline void LightBallExtremePoint(float x, float y, float dir, float &lightX, float &lightY) const;
|
|
|
|
/** Outputs the rightmost position of the light ball, as seen from the given point. Shrinks the light if it is too close
|
|
to work against excessive fades. The light ball is the imaginery size of the light to enable soft shadows. */
|
|
inline void LightBallRightMostPoint(float x, float y, float &lightX, float &lightY) const;
|
|
|
|
/** Outputs the leftmost position of the light ball, as seen from the given point. Shrinks the light if it is too close
|
|
to work against excessive fades. The light ball is the imaginery size of the light to enable soft shadows. */
|
|
inline void LightBallLeftMostPoint(float x, float y, float &lightX, float &lightY) const;
|
|
|
|
|
|
/** Find right-most beam left of point */
|
|
C4FoWBeam *FindBeamLeftOf(int32_t x, int32_t y) const;
|
|
|
|
/** Find beams that go through the given rectangle. Returns the number of beams that are in the rectangle and makes
|
|
firstBeam point to the first and endBeam point to the beam after the last of these. Thus, endBeam is NULL if
|
|
no beams were clipped at the end. */
|
|
int32_t FindBeamsClipped(const C4Rect &rect, C4FoWBeam *&firstBeam, C4FoWBeam *&endBeam) const;
|
|
|
|
public:
|
|
// Serialization for debugging purposes
|
|
void CompileFunc(StdCompiler *pComp);
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|