124 lines
2.6 KiB
ObjectPascal

unit utore3d;
{$mode objfpc}
interface
uses
Classes, SysUtils, BGRAScene3D;
type
{ TToreScene3D }
TToreScene3D = class(TBGRAScene3D)
private
shape,lightObj: IBGRAObject3D;
procedure CreateLight;
procedure CreateShape;
public
angle: single;
constructor Create;
procedure Render; override;
end;
implementation
uses BGRABitmapTypes, BGRAMatrix3D;
{ TToreScene3D }
constructor TToreScene3D.Create;
begin
inherited Create;
CreateLight;
CreateShape;
end;
procedure TToreScene3D.Render;
begin
with shape.MainPart do
begin
ResetTransform;
Translate(sin(angle*Pi/180+Pi/4)*10,0,0);
Scale(20);
RotateZDeg(angle*0.3);
RotateXDeg(angle*0.1+90);
end;
with lightObj.MainPart do
begin
ResetTransform;
RotateYDeg(angle);
Translate(60,0,0);
end;
inherited Render;
end;
procedure TToreScene3D.CreateShape;
const NbX = 40;
NbY = 20;
var
v: array[0..NbY-1,0..NbX-1] of IBGRAVertex3D;
i,j: integer;
m: TMatrix3D;
p,ofs: TPoint3D;
begin
shape := CreateObject(BGRA(255,0,0));
m := MatrixRotateY(2*Pi/NbY);
p := Point3D(0.3,0,0);
ofs := Point3D(1,0,0);
for i := 0 to NbY-1 do
begin
v[i,0] := shape.MainPart.Add(p+ofs);
p := m*p;
end;
m := MatrixRotateZ(2*Pi/NbX);
for j := 1 to NbX-1 do
for i := 0 to NbY-1 do
v[i,j] := shape.MainPart.Add(m*v[i,j-1].SceneCoord);
for j := 0 to NbX-1 do
for i := 0 to NbY-1 do
shape.AddFace([v[i,j],v[i,(j+1)mod NbX],v[(i+1) mod NbY,(j+1)mod NbX],v[(i+1) mod NbY,j]]);
end;
procedure TToreScene3D.CreateLight;
var v: array of IBGRAVertex3D;
lamp: IBGRAMaterial3D;
begin
lightObj := CreateObject(BGRAWhite);
DefaultLightingNormal := lnVertex;
DefaultMaterial.SpecularIndex := 10;
{ if DefaultLightingNormal = lnFace then
begin
AmbiantLightness := 0.4;
AddPointLight(lightObj.Vertices.Add(0,0,0),40,0.8,-0.3)
end
else
begin }
AmbiantLightColor := BGRA(128,128,128);
AddPointLight(lightObj.MainPart.Add(0,0,0),40,BGRA(128,128,64),-0.3);
//end;
v := lightObj.MainPart.Add([-1,-2,-2, 1,-1,-1, 1,1,-1, -1,2,-2,
-1,-2,+2, 1,-1,+1, 1,1,+1, -1,2,+2]);
lamp := CreateMaterial;
lamp.LightThroughFactor := 0.0001;
lightObj.Material := lamp;
lightObj.AddFace([v[0],v[1],v[2],v[3]],true);
lightObj.AddFace([v[4],v[5],v[1],v[0]],true);
lightObj.AddFace([v[7],v[6],v[5],v[4]],true);
lightObj.AddFace([v[3],v[2],v[6],v[7]],true);
lightObj.AddFace([v[1],v[5],v[6],v[2]],true);
//lightObj.AddFace([v[4],v[0],v[3],v[7]],true);
AddPointLight(lightObj.MainPart.Add(5,0,0),4,1,-0.3);
end;
end.