mirror of
https://github.com/leozide/leocad
synced 2025-01-29 20:34:50 +01:00
New light gizmos.
This commit is contained in:
parent
2f5594b5f6
commit
3942156acf
4 changed files with 526 additions and 351 deletions
119
common/lc_math.h
119
common/lc_math.h
|
@ -1991,6 +1991,125 @@ inline bool lcSphereRayMinIntersectDistance(const lcVector3& Center, float Radiu
|
|||
}
|
||||
}
|
||||
|
||||
inline bool lcConeRayMinIntersectDistance(const lcVector3& Tip, const lcVector3& Direction, float Radius, float Height, const lcVector3& Start, const lcVector3& End, float* Dist)
|
||||
{
|
||||
const lcVector3 v = End - Start;
|
||||
const lcVector3 h = Direction;
|
||||
const lcVector3 w = Start - Tip;
|
||||
const float vh = lcDot(v, h);
|
||||
const float wh = lcDot(w, h);
|
||||
const float m = (Radius * Radius) / (Height * Height);
|
||||
|
||||
const float a = lcDot(v, v) - m * vh * vh - vh * vh;
|
||||
const float b = 2 * (lcDot(v, w) - m * vh * wh - vh * wh);
|
||||
const float c = lcDot(w, w) - m * wh * wh - wh * wh;
|
||||
|
||||
const float delta = b * b - 4 * a * c;
|
||||
|
||||
if (delta < 0.0f)
|
||||
return false;
|
||||
|
||||
float ts[2] = { (-b - sqrtf(delta)) / (2 * a), (-b + sqrtf(delta)) / (2 * a) };
|
||||
|
||||
for (int ti = 0; ti < 2; ti++)
|
||||
{
|
||||
float t = ts[ti];
|
||||
lcVector3 Intersection = Start + v * t;
|
||||
|
||||
float ConeD = lcDot(Intersection - Tip, Direction);
|
||||
|
||||
if (ConeD < 0.0f)
|
||||
continue;
|
||||
|
||||
if (ConeD < Height)
|
||||
{
|
||||
*Dist = lcLength(Intersection - Start);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
lcVector3 Center(Tip + Direction * Height);
|
||||
lcVector4 Plane(Direction, -lcDot(Direction, Center));
|
||||
|
||||
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, Plane))
|
||||
{
|
||||
if (lcLengthSquared(Center - Intersection) < Radius * Radius)
|
||||
{
|
||||
*Dist = lcLength(Intersection - Start);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool lcCylinderRayMinIntersectDistance(float Radius, float Height, const lcVector3& Start, const lcVector3& End, float* Dist)
|
||||
{
|
||||
lcVector4 BottomPlane(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
lcVector3 Intersection;
|
||||
float MinDistance = FLT_MAX;
|
||||
|
||||
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, BottomPlane))
|
||||
{
|
||||
if (Intersection.x * Intersection.x + Intersection.y * Intersection.y < Radius * Radius)
|
||||
{
|
||||
float Distance = lcLength(Intersection - Start);
|
||||
|
||||
if (Distance < MinDistance)
|
||||
MinDistance = Distance;
|
||||
}
|
||||
}
|
||||
|
||||
lcVector4 TopPlane(0.0f, 0.0f, 1.0f, -Height);
|
||||
|
||||
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, TopPlane))
|
||||
{
|
||||
if (Intersection.x * Intersection.x + Intersection.y * Intersection.y < Radius * Radius)
|
||||
{
|
||||
float Distance = lcLength(Intersection - Start);
|
||||
|
||||
if (Distance < MinDistance)
|
||||
MinDistance = Distance;
|
||||
}
|
||||
}
|
||||
|
||||
lcVector3 Direction = End - Start;
|
||||
|
||||
float a = (Direction.x * Direction.x) + (Direction.y * Direction.y);
|
||||
float b = 2 * (Direction.x * Start.x + Direction.y * Start.y);
|
||||
float c = (Start.x * Start.x) + (Start.y * Start.y) - (Radius * Radius);
|
||||
|
||||
float delta = b * b - 4 * (a * c);
|
||||
|
||||
if (delta > 0.0f)
|
||||
{
|
||||
float ts[2] = { (-b - sqrtf(delta)) / (2 * a), (-b + sqrtf(delta)) / (2 * a) };
|
||||
|
||||
for (int ti = 0; ti < 2; ti++)
|
||||
{
|
||||
float t = ts[ti];
|
||||
Intersection = Start + Direction * t;
|
||||
|
||||
if (Intersection.z < 0.0f || Intersection.z > Height)
|
||||
continue;
|
||||
|
||||
float Distance = lcLength(Intersection - Start);
|
||||
|
||||
if (Distance < MinDistance)
|
||||
MinDistance = Distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (MinDistance == FLT_MAX)
|
||||
return false;
|
||||
|
||||
*Dist = MinDistance;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline lcVector3 lcRayPointClosestPoint(const lcVector3& Point, const lcVector3& Start, const lcVector3& End)
|
||||
{
|
||||
const lcVector3 Dir = Point - Start;
|
||||
|
|
732
common/light.cpp
732
common/light.cpp
|
@ -8,11 +8,14 @@
|
|||
#include "lc_application.h"
|
||||
#include "lc_context.h"
|
||||
|
||||
#define LC_LIGHT_POSITION_EDGE 7.5f
|
||||
#define LC_LIGHT_TARGET_EDGE 5.0f
|
||||
#define LC_LIGHT_SPHERE_RADIUS 5.0f
|
||||
#define LC_LIGHT_SUN_RADIUS 8.5f
|
||||
#define LC_LIGHT_SPOT_BASE_EDGE 12.5f
|
||||
#define LC_LIGHT_TARGET_EDGE 5.0f
|
||||
#define LC_LIGHT_SPOT_CONE_HEIGHT 10.0f
|
||||
#define LC_LIGHT_SPOT_CONE_RADIUS 7.5f
|
||||
#define LC_LIGHT_DIRECTIONAL_RADIUS 5.0f
|
||||
#define LC_LIGHT_DIRECTIONAL_HEIGHT 7.5f
|
||||
|
||||
#define LC_LIGHT_POSITION_EDGE 7.5f
|
||||
|
||||
static const std::array<QLatin1String, 4> gLightTypes = { QLatin1String("POINT"), QLatin1String("SPOT"), QLatin1String("DIRECTIONAL"), QLatin1String("AREA") };
|
||||
|
||||
|
@ -597,7 +600,7 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
{
|
||||
float Distance;
|
||||
|
||||
if (lcSphereRayMinIntersectDistance(mPosition, LC_LIGHT_SPHERE_RADIUS, ObjectRayTest.Start, ObjectRayTest.End, &Distance))
|
||||
if (lcSphereRayMinIntersectDistance(mPosition, LC_LIGHT_SPHERE_RADIUS, ObjectRayTest.Start, ObjectRayTest.End, &Distance) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
|
@ -607,8 +610,63 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
return;
|
||||
}
|
||||
|
||||
lcVector3 Min = lcVector3(-LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE);
|
||||
lcVector3 Max = lcVector3(LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE);
|
||||
if (mLightType == lcLightType::Spot)
|
||||
{
|
||||
float Distance;
|
||||
lcVector3 Direction = lcNormalize(mTargetPosition - mPosition);
|
||||
|
||||
if (lcConeRayMinIntersectDistance(mPosition - Direction * LC_LIGHT_SPOT_CONE_HEIGHT, Direction, LC_LIGHT_SPOT_CONE_RADIUS, LC_LIGHT_SPOT_CONE_HEIGHT, ObjectRayTest.Start, ObjectRayTest.End, &Distance) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
ObjectRayTest.Distance = Distance;
|
||||
}
|
||||
}
|
||||
else if (mLightType == lcLightType::Area)
|
||||
{
|
||||
lcVector3 FrontVector = mTargetPosition - mPosition;
|
||||
lcVector4 Plane(FrontVector, -lcDot(FrontVector, mPosition));
|
||||
lcVector3 Intersection;
|
||||
|
||||
if (lcLineSegmentPlaneIntersection(&Intersection, ObjectRayTest.Start, ObjectRayTest.End, Plane))
|
||||
{
|
||||
lcVector3 UpVector(1, 1, 1);
|
||||
|
||||
if (fabs(FrontVector[0]) < fabs(FrontVector[1]))
|
||||
{
|
||||
if (fabs(FrontVector[0]) < fabs(FrontVector[2]))
|
||||
UpVector[0] = -(UpVector[1] * FrontVector[1] + UpVector[2] * FrontVector[2]);
|
||||
else
|
||||
UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fabs(FrontVector[1]) < fabs(FrontVector[2]))
|
||||
UpVector[1] = -(UpVector[0] * FrontVector[0] + UpVector[2] * FrontVector[2]);
|
||||
else
|
||||
UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]);
|
||||
}
|
||||
|
||||
lcVector3 XAxis = lcNormalize(lcCross(FrontVector, UpVector));
|
||||
lcVector3 YAxis = lcNormalize(lcCross(FrontVector, XAxis));
|
||||
lcVector3 IntersectionDirection = Intersection - mPosition;
|
||||
|
||||
float x = lcDot(IntersectionDirection, XAxis);
|
||||
float y = lcDot(IntersectionDirection, YAxis);
|
||||
|
||||
if (fabsf(x) < mAreaSize.x / 2.0f && fabsf(y) < mAreaSize.y / 2.0f)
|
||||
{
|
||||
float Distance = lcLength(Intersection - ObjectRayTest.Start);
|
||||
|
||||
if (Distance < ObjectRayTest.Distance)
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
ObjectRayTest.Distance = Distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lcVector3 Start = lcMul31(ObjectRayTest.Start, mWorldLight);
|
||||
lcVector3 End = lcMul31(ObjectRayTest.End, mWorldLight);
|
||||
|
@ -616,16 +674,19 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
float Distance;
|
||||
lcVector3 Plane;
|
||||
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance))
|
||||
if (mLightType == lcLightType::Directional)
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
ObjectRayTest.Distance = Distance;
|
||||
ObjectRayTest.PieceInfoRayTest.Plane = Plane;
|
||||
if (lcCylinderRayMinIntersectDistance(LC_LIGHT_DIRECTIONAL_RADIUS, LC_LIGHT_DIRECTIONAL_HEIGHT, Start, End, &Distance) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
ObjectRayTest.Distance = Distance;
|
||||
ObjectRayTest.PieceInfoRayTest.Plane = Plane;
|
||||
}
|
||||
}
|
||||
|
||||
Min = lcVector3(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE);
|
||||
Max = lcVector3(LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE);
|
||||
lcVector3 Min = lcVector3(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE);
|
||||
lcVector3 Max = lcVector3( LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE);
|
||||
|
||||
lcMatrix44 WorldTarget = mWorldLight;
|
||||
WorldTarget.SetTranslation(lcMul30(-mTargetPosition, WorldTarget));
|
||||
|
@ -654,7 +715,7 @@ void lcLight::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
|
|||
return;
|
||||
}
|
||||
|
||||
lcVector3 Min(-LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE);
|
||||
lcVector3 Min(-LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE); // todo: fix light box test
|
||||
lcVector3 Max(LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE);
|
||||
|
||||
lcVector4 LocalPlanes[6];
|
||||
|
@ -798,13 +859,175 @@ void lcLight::DrawInterface(lcContext* Context, const lcScene& Scene) const
|
|||
Q_UNUSED(Scene);
|
||||
Context->SetMaterial(lcMaterialType::UnlitColor);
|
||||
|
||||
if (IsPointLight())
|
||||
switch (mLightType)
|
||||
{
|
||||
case lcLightType::Point:
|
||||
DrawPointLight(Context);
|
||||
else
|
||||
break;
|
||||
|
||||
case lcLightType::Spot:
|
||||
DrawSpotLight(Context);
|
||||
break;
|
||||
|
||||
case lcLightType::Directional:
|
||||
DrawDirectionalLight(Context);
|
||||
break;
|
||||
|
||||
case lcLightType::Area:
|
||||
DrawAreaLight(Context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lcLight::DrawPointLight(lcContext* Context) const
|
||||
{
|
||||
Context->SetWorldMatrix(lcMatrix44Translation(mPosition));
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
|
||||
if (IsFocused(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
|
||||
Context->SetColor(FocusedColor);
|
||||
}
|
||||
else if (IsSelected(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
|
||||
Context->SetColor(LightColor);
|
||||
}
|
||||
|
||||
DrawSphere(Context, LC_LIGHT_SPHERE_RADIUS);
|
||||
}
|
||||
|
||||
void lcLight::DrawSpotLight(lcContext* Context) const
|
||||
{
|
||||
constexpr int ConeEdges = 8;
|
||||
float TargetDistance = SetupLightMatrix(Context);
|
||||
|
||||
float Verts[(ConeEdges + 1) * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
for (int EdgeIndex = 0; EdgeIndex < ConeEdges; EdgeIndex++)
|
||||
{
|
||||
float c = cosf((float)EdgeIndex / ConeEdges * LC_2PI) * LC_LIGHT_SPOT_CONE_RADIUS;
|
||||
float s = sinf((float)EdgeIndex / ConeEdges * LC_2PI) * LC_LIGHT_SPOT_CONE_RADIUS;
|
||||
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = 0.0f;
|
||||
}
|
||||
|
||||
*CurVert++ = 0.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
*CurVert++ = LC_LIGHT_SPOT_CONE_HEIGHT;
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
|
||||
const GLushort Indices[(ConeEdges + 4) * 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0,
|
||||
0, 8, 2, 8, 4, 8, 6, 8,
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, (ConeEdges + 4) * 2, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
DrawTarget(Context, TargetDistance);
|
||||
|
||||
if (IsSelected())
|
||||
DrawCone(Context, TargetDistance);
|
||||
}
|
||||
|
||||
void lcLight::DrawDirectionalLight(lcContext* Context) const
|
||||
{
|
||||
float TargetDistance = SetupLightMatrix(Context);
|
||||
|
||||
DrawCylinder(Context, LC_LIGHT_DIRECTIONAL_RADIUS, LC_LIGHT_DIRECTIONAL_HEIGHT);
|
||||
|
||||
DrawTarget(Context, TargetDistance);
|
||||
}
|
||||
|
||||
void lcLight::DrawAreaLight(lcContext* Context) const
|
||||
{
|
||||
float TargetDistance = SetupLightMatrix(Context);
|
||||
|
||||
if (mLightShape == LC_LIGHT_SHAPE_SQUARE || mLightShape == LC_LIGHT_SHAPE_RECTANGLE)
|
||||
{
|
||||
float Verts[4 * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
*CurVert++ = -mAreaSize.x / 2.0f;
|
||||
*CurVert++ = -mAreaSize.y / 2.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
|
||||
*CurVert++ = mAreaSize.x / 2.0f;
|
||||
*CurVert++ = -mAreaSize.y / 2.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
|
||||
*CurVert++ = mAreaSize.x / 2.0f;
|
||||
*CurVert++ = mAreaSize.y / 2.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
|
||||
*CurVert++ = -mAreaSize.x / 2.0f;
|
||||
*CurVert++ = mAreaSize.y / 2.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
|
||||
const GLushort Indices[(4 + 2) * 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
0, 2, 1, 3,
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, (4 + 2) * 2, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr int CircleEdges = 16;
|
||||
|
||||
float Verts[CircleEdges * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
for (int EdgeIndex = 0; EdgeIndex < CircleEdges; EdgeIndex++)
|
||||
{
|
||||
float c = cosf((float)EdgeIndex / CircleEdges * LC_2PI) * mAreaSize.x / 2.0f;
|
||||
float s = sinf((float)EdgeIndex / CircleEdges * LC_2PI) * mAreaSize.y / 2.0f;
|
||||
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = 0.0f;
|
||||
}
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
|
||||
const GLushort Indices[(CircleEdges + 2) * 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0,
|
||||
0, 8, 4, 12
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, (CircleEdges + 2) * 2, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
DrawTarget(Context, TargetDistance);
|
||||
}
|
||||
|
||||
float lcLight::SetupLightMatrix(lcContext* Context) const
|
||||
{
|
||||
lcVector3 FrontVector(mTargetPosition - mPosition);
|
||||
lcVector3 UpVector(1, 1, 1);
|
||||
|
@ -831,324 +1054,37 @@ void lcLight::DrawDirectionalLight(lcContext* Context) const
|
|||
const lcMatrix44 LightViewMatrix = lcMul(LightMatrix, lcMatrix44Translation(mPosition));
|
||||
Context->SetWorldMatrix(LightViewMatrix);
|
||||
|
||||
float Length = FrontVector.Length();
|
||||
|
||||
float Verts[(20 + 8 + 2 + 16) * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
if (mLightType != lcLightType::Directional)
|
||||
{
|
||||
if (mLightType == lcLightType::Spot)
|
||||
{
|
||||
for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++)
|
||||
{
|
||||
float c = cosf((float)EdgeIdx / 4 * LC_PI) * LC_LIGHT_POSITION_EDGE;
|
||||
float s = sinf((float)EdgeIdx / 4 * LC_PI) * LC_LIGHT_POSITION_EDGE;
|
||||
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
}
|
||||
|
||||
*CurVert++ = -LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = LC_LIGHT_SPOT_BASE_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
}
|
||||
else if (mLightType == lcLightType::Area)
|
||||
{
|
||||
const float LC_LIGHT_AREA_EDGE = 5.0f;
|
||||
const float LC_LIGHT_AREA_H_EDGE = 8.5f;
|
||||
const float LC_LIGHT_AREA_W_EDGE = 17.0f;
|
||||
|
||||
*CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_AREA_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
|
||||
*CurVert++ = -LC_LIGHT_AREA_H_EDGE; *CurVert++ = -LC_LIGHT_AREA_W_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_AREA_H_EDGE; *CurVert++ = -LC_LIGHT_AREA_W_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = LC_LIGHT_AREA_H_EDGE; *CurVert++ = LC_LIGHT_AREA_W_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
*CurVert++ = -LC_LIGHT_AREA_H_EDGE; *CurVert++ = LC_LIGHT_AREA_W_EDGE; *CurVert++ = -LC_LIGHT_POSITION_EDGE;
|
||||
}
|
||||
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length;
|
||||
|
||||
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
|
||||
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -Length;
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
}
|
||||
|
||||
int BaseIndices = 0;
|
||||
|
||||
if (mLightType == lcLightType::Spot)
|
||||
{
|
||||
BaseIndices = 56;
|
||||
const GLushort Indices[56 + 24 + 2 + 40] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 0,
|
||||
1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15, 1,
|
||||
16, 17, 17, 18, 18, 19, 19, 16,
|
||||
20, 21, 21, 22, 22, 23, 23, 20,
|
||||
24, 25, 25, 26, 26, 27, 27, 24,
|
||||
20, 24, 21, 25, 22, 26, 23, 27,
|
||||
28, 29,
|
||||
30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38,
|
||||
38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 30,
|
||||
28, 30, 28, 34, 28, 38, 28, 42
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
}
|
||||
else if (mLightType == lcLightType::Area)
|
||||
{
|
||||
BaseIndices = 32;
|
||||
const GLushort Indices[32 + 24 + 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
0, 4, 1, 5, 2, 6, 3, 7,
|
||||
8, 9, 9, 10, 10, 11, 11, 8,
|
||||
12, 13, 13, 14, 14, 15, 15, 12,
|
||||
16, 17, 17, 18, 18, 19, 19, 16,
|
||||
12, 16, 13, 17, 14, 18, 15, 19,
|
||||
20, 21
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
}
|
||||
else if (mLightType == lcLightType::Directional)
|
||||
{
|
||||
constexpr float Radius = LC_LIGHT_SUN_RADIUS;
|
||||
constexpr int Slices = 9; // longitude
|
||||
constexpr int Stacks = 9; // latitude
|
||||
constexpr int NumSphereVertices = 918; // Slices * 2 * 3 * 3 + (Stacks - 2) * Slices * 4 * 3
|
||||
constexpr int NumSphereIndices = 306; // Slices * 2 + (Stacks - 1) * Slices * 2 * 2
|
||||
|
||||
BaseIndices = NumSphereIndices;
|
||||
|
||||
float Vertices[NumSphereVertices + 24 + 6];
|
||||
float *Vert = Vertices;
|
||||
|
||||
quint16 Indices[NumSphereIndices + 24 + 2];
|
||||
quint16 *Indx = Indices;
|
||||
|
||||
auto AddVertex = [&](float x, float y, float z)
|
||||
{
|
||||
*Vert++ = x;
|
||||
*Vert++ = y;
|
||||
*Vert++ = z;
|
||||
};
|
||||
|
||||
auto AddLineIndex = [&](quint16 v1, quint16 v2)
|
||||
{
|
||||
*Indx++ = v1;
|
||||
*Indx++ = v2;
|
||||
};
|
||||
|
||||
std::vector<lcVector3> WrkVertices;
|
||||
|
||||
float Slice = LC_2PI / Slices;
|
||||
float Stack = LC_PI / Stacks;
|
||||
float SliceAngle, StackAngle;
|
||||
|
||||
for(int i = 0; i <= Stacks; ++i)
|
||||
{
|
||||
StackAngle = LC_PI / 2 - i * Stack; // starting from pi/2 to -pi/2
|
||||
float xy = Radius * cosf(StackAngle);
|
||||
float z = Radius * sinf(StackAngle);
|
||||
|
||||
for(int j = 0; j <= Slices; ++j) // add (Slices+1) vertices per stack
|
||||
{
|
||||
SliceAngle = j * Slice;
|
||||
|
||||
lcVector3 Vertex;
|
||||
Vertex.x = xy * cosf(SliceAngle);
|
||||
Vertex.y = xy * sinf(SliceAngle);
|
||||
Vertex.z = z;
|
||||
|
||||
WrkVertices.push_back(Vertex);
|
||||
}
|
||||
}
|
||||
|
||||
int Index = 0;
|
||||
|
||||
lcVector3 v1, v2, v3, v4;
|
||||
|
||||
for(int i = 0; i < Stacks; ++i)
|
||||
{
|
||||
int vi1 = i * (Slices + 1);
|
||||
int vi2 = (i + 1) * (Slices + 1);
|
||||
|
||||
for(int j = 0; j < Slices; ++j, ++vi1, ++vi2)
|
||||
{
|
||||
// 4 vertices per slice
|
||||
// v1--v3
|
||||
// | |
|
||||
// v2--v4
|
||||
v1 = WrkVertices[vi1];
|
||||
v2 = WrkVertices[vi2];
|
||||
v3 = WrkVertices[vi1 + 1];
|
||||
v4 = WrkVertices[vi2 + 1];
|
||||
|
||||
// if first stack or last stack, store 1 triangle per slice else, store 2 triangles (1 quad) per slice
|
||||
if(i == 0)
|
||||
{
|
||||
// first stack triangle v1-v2-v4
|
||||
AddVertex(v1.x, v1.y, v1.z);
|
||||
AddVertex(v2.x, v2.y, v2.z);
|
||||
AddVertex(v4.x, v4.y, v4.z);
|
||||
|
||||
// only vertical lines for first stack)
|
||||
AddLineIndex(Index, Index+1);
|
||||
|
||||
Index += 3;
|
||||
}
|
||||
else if(i == (Stacks-1))
|
||||
{
|
||||
// last stack inverted triangle v1-v2-v3
|
||||
AddVertex(v1.x, v1.y, v1.z);
|
||||
AddVertex(v2.x, v2.y, v2.z);
|
||||
AddVertex(v3.x, v3.y, v3.z);
|
||||
|
||||
// both vertical and horizontal lines for last stack
|
||||
AddLineIndex(Index, Index+1);
|
||||
AddLineIndex(Index, Index+2);
|
||||
|
||||
Index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 triangles (quad vertices v1-v2-v3-v4) for other stacks
|
||||
AddVertex(v1.x, v1.y, v1.z);
|
||||
AddVertex(v2.x, v2.y, v2.z);
|
||||
AddVertex(v3.x, v3.y, v3.z);
|
||||
AddVertex(v4.x, v4.y, v4.z);
|
||||
|
||||
// both vertical and horizontal lines for other stacks
|
||||
AddLineIndex(Index, Index+1);
|
||||
AddLineIndex(Index, Index+2);
|
||||
|
||||
Index += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddVertex( LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex(-LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex( LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex( LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex(-LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex( LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE - Length);
|
||||
AddVertex(0.0f, 0.0f, 0.0f);
|
||||
AddVertex(0.0f, 0.0f, -Length);
|
||||
|
||||
const int Idx[10] = { Index++, Index++, Index++, Index++, Index++, Index++, Index++, Index++, Index++, Index++ };
|
||||
AddLineIndex(Idx[0], Idx[1]); AddLineIndex(Idx[1], Idx[2]); AddLineIndex(Idx[2], Idx[3]); AddLineIndex(Idx[3], Idx[0]);
|
||||
AddLineIndex(Idx[4], Idx[5]); AddLineIndex(Idx[5], Idx[6]); AddLineIndex(Idx[6], Idx[7]); AddLineIndex(Idx[7], Idx[4]);
|
||||
AddLineIndex(Idx[0], Idx[4]); AddLineIndex(Idx[1], Idx[5]); AddLineIndex(Idx[2], Idx[6]); AddLineIndex(Idx[3], Idx[7]);
|
||||
AddLineIndex(Idx[8], Idx[9]);
|
||||
|
||||
Context->SetVertexBufferPointer(Vertices);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
}
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
const float LineWidth = Preferences.mLineWidth;
|
||||
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
|
||||
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
|
||||
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
|
||||
|
||||
if (!IsSelected())
|
||||
if (IsSelected(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
|
||||
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, BaseIndices + 24 + 2, GL_UNSIGNED_SHORT, 0);
|
||||
Context->SetLineWidth(2.0f * LineWidth);
|
||||
|
||||
if (IsFocused(LC_LIGHT_SECTION_POSITION))
|
||||
Context->SetColor(FocusedColor);
|
||||
else
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsSelected(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
Context->SetLineWidth(2.0f * LineWidth);
|
||||
if (IsFocused(LC_LIGHT_SECTION_POSITION))
|
||||
Context->SetColor(FocusedColor);
|
||||
else
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
}
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, BaseIndices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
if (IsSelected(LC_LIGHT_SECTION_TARGET))
|
||||
{
|
||||
Context->SetLineWidth(2.0f * LineWidth);
|
||||
if (IsFocused(LC_LIGHT_SECTION_TARGET))
|
||||
Context->SetColor(FocusedColor);
|
||||
else
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
}
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, BaseIndices * 2);
|
||||
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
|
||||
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
|
||||
int SpotCone = 0;
|
||||
|
||||
if (mLightType == lcLightType::Spot)
|
||||
{
|
||||
SpotCone = 40;
|
||||
|
||||
float Radius = tanf(LC_DTOR * mSpotCutoff) * Length;
|
||||
|
||||
for (int EdgeIdx = 0; EdgeIdx < 16; EdgeIdx++)
|
||||
{
|
||||
*CurVert++ = cosf((float)EdgeIdx / 16 * LC_2PI) * Radius;
|
||||
*CurVert++ = sinf((float)EdgeIdx / 16 * LC_2PI) * Radius;
|
||||
*CurVert++ = -Length;
|
||||
}
|
||||
}
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 2 + SpotCone, GL_UNSIGNED_SHORT, (BaseIndices + 24) * 2);
|
||||
}
|
||||
|
||||
return FrontVector.Length();
|
||||
}
|
||||
|
||||
void lcLight::DrawPointLight(lcContext* Context) const
|
||||
void lcLight::DrawSphere(lcContext* Context, float Radius) const
|
||||
{
|
||||
constexpr int Slices = 6;
|
||||
constexpr int NumIndices = 3 * Slices + 6 * Slices * (Slices - 2) + 3 * Slices;
|
||||
constexpr int NumVertices = (Slices - 1) * Slices + 2;
|
||||
constexpr float Radius = LC_LIGHT_SPHERE_RADIUS;
|
||||
lcVector3 Vertices[NumVertices];
|
||||
quint16 Indices[NumIndices];
|
||||
|
||||
|
@ -1157,7 +1093,7 @@ void lcLight::DrawPointLight(lcContext* Context) const
|
|||
|
||||
*Vertex++ = lcVector3(0, 0, Radius);
|
||||
|
||||
for (int i = 1; i < Slices; i++ )
|
||||
for (int i = 1; i < Slices; i++)
|
||||
{
|
||||
const float r0 = Radius * sinf(i * (LC_PI / Slices));
|
||||
const float z0 = Radius * cosf(i * (LC_PI / Slices));
|
||||
|
@ -1173,7 +1109,7 @@ void lcLight::DrawPointLight(lcContext* Context) const
|
|||
|
||||
*Vertex++ = lcVector3(0, 0, -Radius);
|
||||
|
||||
for (quint16 i = 0; i < Slices - 1; i++ )
|
||||
for (quint16 i = 0; i < Slices - 1; i++)
|
||||
{
|
||||
*Index++ = 0;
|
||||
*Index++ = 1 + i;
|
||||
|
@ -1184,12 +1120,12 @@ void lcLight::DrawPointLight(lcContext* Context) const
|
|||
*Index++ = 1;
|
||||
*Index++ = 1 + Slices - 1;
|
||||
|
||||
for (quint16 i = 0; i < Slices - 2; i++ )
|
||||
for (quint16 i = 0; i < Slices - 2; i++)
|
||||
{
|
||||
quint16 Row1 = 1 + i * Slices;
|
||||
quint16 Row2 = 1 + (i + 1) * Slices;
|
||||
|
||||
for (quint16 j = 0; j < Slices - 1; j++ )
|
||||
for (quint16 j = 0; j < Slices - 1; j++)
|
||||
{
|
||||
*Index++ = Row1 + j;
|
||||
*Index++ = Row2 + j + 1;
|
||||
|
@ -1209,7 +1145,7 @@ void lcLight::DrawPointLight(lcContext* Context) const
|
|||
*Index++ = Row1 + 0;
|
||||
}
|
||||
|
||||
for (quint16 i = 0; i < Slices - 1; i++ )
|
||||
for (quint16 i = 0; i < Slices - 1; i++)
|
||||
{
|
||||
*Index++ = (Slices - 1) * Slices + 1;
|
||||
*Index++ = (Slices - 1) * (Slices - 1) + i;
|
||||
|
@ -1220,32 +1156,144 @@ void lcLight::DrawPointLight(lcContext* Context) const
|
|||
*Index++ = (Slices - 1) * (Slices - 1) + (Slices - 2) + 1;
|
||||
*Index++ = (Slices - 1) * (Slices - 1);
|
||||
|
||||
Context->SetWorldMatrix(lcMatrix44Translation(mPosition));
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
|
||||
if (IsFocused(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
|
||||
Context->SetColor(FocusedColor);
|
||||
}
|
||||
else if (IsSelected(LC_LIGHT_SECTION_POSITION))
|
||||
{
|
||||
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
|
||||
Context->SetColor(LightColor);
|
||||
}
|
||||
|
||||
Context->SetVertexBufferPointer(Vertices);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_TRIANGLES, NumIndices, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
void lcLight::DrawCylinder(lcContext* Context, float Radius, float Height) const
|
||||
{
|
||||
constexpr int Slices = 8;
|
||||
|
||||
float Verts[(Slices * 2) * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
for (int EdgeIndex = 0; EdgeIndex < Slices; EdgeIndex++)
|
||||
{
|
||||
float c = cosf((float)EdgeIndex / Slices * LC_2PI) * Radius;
|
||||
float s = sinf((float)EdgeIndex / Slices * LC_2PI) * Radius;
|
||||
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = Height;
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = 0.0f;
|
||||
}
|
||||
|
||||
const GLushort Indices[48] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 0,
|
||||
1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15, 1,
|
||||
};
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 48, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
void lcLight::DrawTarget(lcContext* Context, float TargetDistance) const
|
||||
{
|
||||
float Verts[10 * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
|
||||
|
||||
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
|
||||
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -TargetDistance;
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
|
||||
const GLushort Indices[(12 + 1) * 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
0, 4, 1, 5, 2, 6, 3, 7,
|
||||
8, 9
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
const float LineWidth = Preferences.mLineWidth;
|
||||
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
|
||||
|
||||
if (IsSelected(LC_LIGHT_SECTION_TARGET))
|
||||
{
|
||||
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
|
||||
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
|
||||
|
||||
Context->SetLineWidth(2.0f * LineWidth);
|
||||
|
||||
if (IsFocused(LC_LIGHT_SECTION_TARGET))
|
||||
Context->SetColor(FocusedColor);
|
||||
else
|
||||
Context->SetColor(SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
}
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 12 * 2, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
Context->SetLineWidth(LineWidth);
|
||||
Context->SetColor(LightColor);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 2, GL_UNSIGNED_SHORT, 12 * 2 * 2);
|
||||
}
|
||||
|
||||
void lcLight::DrawCone(lcContext* Context, float TargetDistance) const
|
||||
{
|
||||
constexpr int ConeEdges = 16;
|
||||
const float Radius = tanf(LC_DTOR * mSpotCutoff) * TargetDistance;
|
||||
|
||||
float Verts[(ConeEdges + 1) * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
for (int EdgeIndex = 0; EdgeIndex < ConeEdges; EdgeIndex++)
|
||||
{
|
||||
float c = cosf((float)EdgeIndex / ConeEdges * LC_2PI) * Radius;
|
||||
float s = sinf((float)EdgeIndex / ConeEdges * LC_2PI) * Radius;
|
||||
|
||||
*CurVert++ = c;
|
||||
*CurVert++ = s;
|
||||
*CurVert++ = -TargetDistance;
|
||||
}
|
||||
|
||||
*CurVert++ = 0.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
*CurVert++ = 0.0f;
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormatPosition(3);
|
||||
|
||||
const GLushort Indices[(ConeEdges + 4) * 2] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0,
|
||||
16, 0, 16, 4, 16, 8, 16, 12
|
||||
};
|
||||
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_LINES, (ConeEdges + 4) * 2, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
void lcLight::RemoveKeyFrames()
|
||||
{
|
||||
mPositionKeys.RemoveAll();
|
||||
|
|
|
@ -331,8 +331,16 @@ protected:
|
|||
lcObjectKeyArray<float> mSpotExponentKeys;
|
||||
lcObjectKeyArray<float> mSpotTightnessKeys;
|
||||
|
||||
void DrawDirectionalLight(lcContext* Context) const;
|
||||
void DrawPointLight(lcContext* Context) const;
|
||||
void DrawSpotLight(lcContext* Context) const;
|
||||
void DrawDirectionalLight(lcContext* Context) const;
|
||||
void DrawAreaLight(lcContext* Context) const;
|
||||
|
||||
float SetupLightMatrix(lcContext* Context) const;
|
||||
void DrawSphere(lcContext* Context, float Radius) const;
|
||||
void DrawCylinder(lcContext* Context, float Radius, float Height) const;
|
||||
void DrawTarget(lcContext* Context, float TargetDistance) const;
|
||||
void DrawCone(lcContext* Context, float TargetDistance) const;
|
||||
|
||||
quint32 mState;
|
||||
lcLightType mLightType;
|
||||
|
|
|
@ -983,7 +983,7 @@ void lcQPropertiesTree::slotReturnPressed()
|
|||
{
|
||||
QString Value = Editor->text();
|
||||
|
||||
Model->SetLightName(Light, Value.toLocal8Bit().data());
|
||||
Model->SetLightName(Light, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1513,14 +1513,14 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
|
|||
{
|
||||
Factor = Light->mAreaSize;
|
||||
FactorALabel = tr("Width");
|
||||
FactorAToolTip = tr("The width (X direction) of the area light in units.");
|
||||
FactorBToolTip = tr("The height (Y direction) of the area light in units.");
|
||||
FactorAToolTip = tr("The width (X direction) of the area light.");
|
||||
FactorBToolTip = tr("The height (Y direction) of the area light.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FactorALabel = tr("Width (m)");
|
||||
FactorAToolTip = tr("The width (X direction) of the area light in metres.");
|
||||
FactorBToolTip = tr("The height (Y direction) of the area light in units.");
|
||||
FactorALabel = tr("Width");
|
||||
FactorAToolTip = tr("The width (X direction) of the area light.");
|
||||
FactorBToolTip = tr("The height (Y direction) of the area light.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1623,7 +1623,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
|
|||
lightSpotTightness = addProperty(lightProperties, tr("Spot Tightness"), PropertyFloat);
|
||||
}
|
||||
}
|
||||
else if (LightType == lcLightType::Area)
|
||||
else if (LightType == lcLightType::Area)
|
||||
{
|
||||
lightShape = addProperty(lightProperties, tr("Shape"), PropertyLightShape);
|
||||
lightFactorA = addProperty(lightProperties, FactorALabel, PropertyFloat);
|
||||
|
@ -1631,7 +1631,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
|
|||
if (ShapeIndex == LC_LIGHT_SHAPE_RECTANGLE || ShapeIndex == LC_LIGHT_SHAPE_ELLIPSE || POVRayLight)
|
||||
lightFactorB = addProperty(lightProperties, tr("Height"), PropertyFloat);
|
||||
else
|
||||
FactorAToolTip = tr("The size of the area light grid in metres.");
|
||||
FactorAToolTip = tr("The size of the area light grid.");
|
||||
|
||||
if (POVRayLight)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue