173 lines
5.5 KiB
PHP

// SPDX-License-Identifier: LGPL-3.0-linking-exception
type
{ Directional light for 3D scene }
TBGRADirectionalLight3D = class(TBGRALight3D,IBGRADirectionalLight3D)
protected
FDirection, FBetweenDirectionAndObserver: TPoint3D_128;
public
constructor Create(ADirection: TPoint3D);
function GetDirection: TPoint3D; override;
procedure SetDirection(const AValue: TPoint3D);
procedure ComputeDiffuseAndSpecularColor(Context: PSceneLightingContext); override;
procedure ComputeDiffuseColor(Context: PSceneLightingContext); override;
procedure ComputeDiffuseLightness(Context: PSceneLightingContext); override;
function IsDirectional: boolean; override;
end;
{ Point light for 3D scene }
TBGRAPointLight3D = class(TBGRALight3D,IBGRAPointLight3D)
protected
FVertex: IBGRAVertex3D;
FIntensity: single;
public
constructor Create(AVertex: IBGRAVertex3D; AIntensity: single);
function GetIntensity: single; override;
procedure SetIntensity(const AValue: single);
function GetVertex: IBGRAVertex3D;
procedure SetVertex(const AValue: IBGRAVertex3D);
function GetPosition: TPoint3D; override;
procedure ComputeDiffuseAndSpecularColor(Context: PSceneLightingContext); override;
procedure ComputeDiffuseLightness(Context: PSceneLightingContext); override;
procedure ComputeDiffuseColor(Context: PSceneLightingContext); override;
function IsDirectional: boolean; override;
end;
{ TBGRAPointLight3D }
constructor TBGRAPointLight3D.Create(AVertex: IBGRAVertex3D; AIntensity: single);
begin
inherited Create;
FVertex:= AVertex;
FIntensity := AIntensity;
end;
function TBGRAPointLight3D.GetIntensity: single;
begin
result := FIntensity;
end;
procedure TBGRAPointLight3D.SetIntensity(const AValue: single);
begin
FIntensity:= AValue;
end;
function TBGRAPointLight3D.GetVertex: IBGRAVertex3D;
begin
result := FVertex;
end;
procedure TBGRAPointLight3D.SetVertex(const AValue: IBGRAVertex3D);
begin
FVertex := AValue;
end;
function TBGRAPointLight3D.GetPosition: TPoint3D;
begin
Result:= FVertex.GetViewCoord;
end;
procedure TBGRAPointLight3D.ComputeDiffuseAndSpecularColor(Context: PSceneLightingContext);
{$DEFINE PARAM_POINTLIGHT}
{$i phonglight.inc}
procedure TBGRAPointLight3D.ComputeDiffuseLightness(Context: PSceneLightingContext);
const maxValue = 100*32768;
var
vect: TPoint3D_128;
dist2,intensity: single;
begin
vect := FVertex.ViewCoord_128 - Context^.basic.Position;
dist2 := DotProduct3D_128(vect,vect);
if dist2 = 0 then
TBGRAMaterial3D(Context^.material).ComputeDiffuseLightness(Context,maxValue,FLightness)
else
begin
intensity := DotProduct3D_128(vect, Context^.basic.Normal)/(dist2*sqrt(dist2))*FIntensity;
if Context^.LightThrough and (intensity < 0) then intensity := -intensity*Context^.LightThroughFactor;
if intensity > 100 then intensity := 100;
if intensity < FMinIntensity then intensity := FMinIntensity;
TBGRAMaterial3D(Context^.material).ComputeDiffuseLightness(Context,round(intensity*32768),FLightness);
end;
end;
procedure TBGRAPointLight3D.ComputeDiffuseColor(Context: PSceneLightingContext);
var
vect: TPoint3D_128;
intensity,dist2: single;
begin
vect := FVertex.ViewCoord_128 - Context^.basic.Position;
dist2 := DotProduct3D_128(vect,vect);
if dist2 = 0 then
intensity := 100
else
begin
intensity := DotProduct3D_128(vect, Context^.basic.Normal)/(dist2*sqrt(dist2))*FIntensity;
if Context^.LightThrough and (intensity < 0) then intensity := -intensity*Context^.LightThroughFactor;
if intensity > 100 then intensity := 100;
if intensity < FMinIntensity then intensity := FMinIntensity;
end;
TBGRAMaterial3D(Context^.material).ComputeDiffuseColor(Context,intensity, FColorInt);
end;
function TBGRAPointLight3D.IsDirectional: boolean;
begin
result := false;
end;
{ TBGRADirectionalLight3D }
constructor TBGRADirectionalLight3D.Create(ADirection: TPoint3D);
begin
inherited Create;
SetDirection(ADirection);
end;
function TBGRADirectionalLight3D.GetDirection: TPoint3D;
begin
result := Point3D(-FDirection.x,-FDirection.y,-FDirection.z);
end;
procedure TBGRADirectionalLight3D.SetDirection(const AValue: TPoint3D);
begin
FDirection := -Point3D_128(AValue.x,AValue.y,AValue.z);
Normalize3D_128(FDirection);
FBetweenDirectionAndObserver := FDirection + FViewVector;
Normalize3D_128(FBetweenDirectionAndObserver);
end;
procedure TBGRADirectionalLight3D.ComputeDiffuseAndSpecularColor(Context: PSceneLightingContext);
{$i phonglight.inc}
procedure TBGRADirectionalLight3D.ComputeDiffuseColor(Context: PSceneLightingContext);
var
intensity: single;
begin
intensity:= DotProduct3D_128(Context^.basic.Normal, FDirection);
if Context^.LightThrough and (intensity < 0) then intensity := -intensity*Context^.LightThroughFactor;
if intensity < FMinIntensity then intensity := FMinIntensity;
TBGRAMaterial3D(Context^.material).ComputeDiffuseColor(Context,intensity,FColorInt);
end;
procedure TBGRADirectionalLight3D.ComputeDiffuseLightness(
Context: PSceneLightingContext);
var
intensity: single;
begin
intensity:= DotProduct3D_128(Context^.basic.Normal, FDirection);
if Context^.LightThrough and (intensity < 0) then intensity := -intensity*Context^.LightThroughFactor;
if intensity < FMinIntensity then intensity := FMinIntensity;
TBGRAMaterial3D(Context^.material).ComputeDiffuseLightness(Context,round(intensity*32768),FLightness);
end;
function TBGRADirectionalLight3D.IsDirectional: boolean;
begin
result := true;
end;