Skip to content

Commit b50c55a

Browse files
committed
Merge branch 'release/v3.8.0' into autobuild/alpha_v380
2 parents 14aee3b + 12fbab3 commit b50c55a

File tree

13 files changed

+256
-93
lines changed

13 files changed

+256
-93
lines changed

changes.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ Changed Behaviour
5050
- Any new behaviour formerly activated by `#version 3.71` now requires
5151
`#version 3.8` (or higher); specifying `#version 3.71` will trigger a
5252
corresponding warning.
53+
- Some defaults have been changed (requires `#version 3.8` as the _very first_
54+
statement of the scene, or a corresponding command line / INI setting):
55+
- `ambient` now defaults to 0.0 instead of 0.1.
56+
- Camera `right` vector length now defaults to the output image aspect
57+
ratio (presuming square pixels) instead of 1.33.
5358

5459
Other Noteworthy
5560
----------------

source/backend/control/scene.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ void Scene::StartParser(POVMS_Object& parseOptions)
9999
sceneData->inputFile = parseOptions.TryGetUCS2String(kPOVAttrib_InputFile, "object.pov");
100100
sceneData->headerFile = parseOptions.TryGetUCS2String(kPOVAttrib_IncludeHeader, "");
101101

102+
DBL outputWidth = parseOptions.TryGetFloat(kPOVAttrib_Width, 160);
103+
DBL outputHeight = parseOptions.TryGetFloat(kPOVAttrib_Height, 120);
104+
sceneData->aspectRatio = outputWidth / outputHeight;
105+
102106
sceneData->defaultFileType = parseOptions.TryGetInt(kPOVAttrib_OutputFileType, DEFAULT_OUTPUT_FORMAT); // TODO - should get DEFAULT_OUTPUT_FORMAT from the front-end
103107
sceneData->clocklessAnimation = parseOptions.TryGetBool(kPOVAttrib_ClocklessAnimation, false); // TODO - experimental code
104108

source/core/material/texture.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ void Transform_Textures(TEXTURE *Textures, const TRANSFORM *Trans)
212212
* 6/27/98 MBP Added initializers for reflection blur
213213
* 8/27/98 MBP Added initializers for angle-based reflectivity
214214
*
215+
* NOTES
216+
* since v3.8, the default ambient will be be overriden to 0.0 when the first statement
217+
* is a #version with value 3.8 or greater or when such version is set explicitly in command line or ini file
218+
*
215219
******************************************************************************/
216220

217221
FINISH *Create_Finish()

source/core/scene/scenedata.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct Skysphere_Struct;
7070
/// This class just provides access to scene specific data
7171
/// needed in many parts of the code. Be aware that while most
7272
/// data is members are public, they shall **not** be modified
73-
/// carelessly. Code from POV-Ray 3.6 and earlier does depend
73+
/// carelessly. Code from POV-Ray v3.6 and earlier does depend
7474
/// on simple access of this data all over the old code, so
7575
/// this provides an efficient way to reuse all the old code.
7676
/// By no means shall this way of data access be used for any
@@ -166,7 +166,7 @@ class SceneData
166166
bool realTimeRaytracing;
167167

168168
// ********************************************************************************
169-
// Old globals from 3.6 and earlier are temporarily kept below. Please carefully
169+
// Old globals from v3.6 and earlier are temporarily kept below. Please carefully
170170
// consider what is added and mark it accordingly if it needs to go away again
171171
// prior to final release! [trf]
172172
// ********************************************************************************
@@ -196,6 +196,9 @@ class SceneData
196196
UCS2String inputFile; // TODO - handle differently
197197
UCS2String headerFile;
198198

199+
/// Aspect ratio of the output image.
200+
DBL aspectRatio;
201+
199202
int defaultFileType;
200203

201204
FrameSettings frameSettings; // TODO - move ???
@@ -227,13 +230,13 @@ class SceneData
227230

228231
/// Convenience function to determine the effective SDL version.
229232
///
230-
/// Given that version 3.7 and later require the first statement in the file to be
233+
/// Given that version v3.7 and later require the first statement in the file to be
231234
/// a `#version` statement, the absence of such a statement can be presumed to
232-
/// indicate a pre-3.7 scene; this function assumes version 3.62 in that case
233-
/// (which was the latest 3.6 version when 3.7.0 was released).
235+
/// indicate a pre-v3.7 scene; this function assumes v3.6.2 in that case
236+
/// (which was the latest version before v3.7.0).
234237
/// @note It is recommended to use this function only where behaviour differs
235-
/// significantly from pre-3.7 versions.
236-
/// @return The current language version in integer format (e.g. 370 for 3.70)
238+
/// significantly from pre-v3.7 versions.
239+
/// @return The current language version in integer format (e.g. 370 for v3.7.0)
237240
/// if explicitly specified, or 362 otherwise.
238241
///
239242
inline unsigned int EffectiveLanguageVersion() const

source/core/shape/ovus.cpp

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,18 @@
4545
*
4646
* ovus
4747
* {
48-
* bottom_radius,top_radius
48+
* bottom_radius,top_radius [distance d] [radius r] [precision p] [sturm]
4949
* }
5050
*
5151
* The so long awaited 'Egg' forms.
5252
*
5353
* Normally, the bottom_radius is bigger than the top_radius
54-
* the center of the top sphere is at the zenith of the bottom sphere
54+
* the center of the top sphere is at the zenith of the bottom sphere, unless
55+
* a greater distance d is specified with "distance"
5556
* and the bottom sphere is centered at 0.0
5657
* The radius of the connecting surface is the double of the biggest radius
5758
* (yes, the biggest diameter is used as the curvature of the connection)
59+
* unless overriden with "radius"
5860
*
5961
* The hard part was just to find where the connection starts and ends.
6062
*
@@ -82,13 +84,6 @@ namespace pov
8284
* Local preprocessor defines
8385
******************************************************************************/
8486

85-
// Minimal depth for a valid intersection.
86-
// TODO FIXME - can we use EPSILON or a similar more generic constant instead?
87-
const DBL DEPTH_TOLERANCE = 1.0e-4;
88-
89-
// Tolerance used for order reduction during root finding.
90-
// TODO FIXME - can we use EPSILON or a similar more generic constant instead?
91-
const DBL ROOT_TOLERANCE = 1.0e-4;
9287

9388

9489

@@ -110,6 +105,7 @@ void Ovus::Intersect_Ovus_Spheres(const Vector3d& P, const Vector3d& D,
110105
*Depth1 = *Depth2 = *Depth3 = *Depth4 = *Depth5 = *Depth6 = -100; // TODO FIXME - magic value
111106
// no hit unless...
112107

108+
// compute intersection with bottom sphere
113109
Padj = -P;
114110
Rad1 = Sqr(BottomRadius);
115111
Rad2 = Sqr(TopRadius);
@@ -140,8 +136,10 @@ void Ovus::Intersect_Ovus_Spheres(const Vector3d& P, const Vector3d& D,
140136
}
141137
}
142138
}
139+
// shape can only have a maximum of 2 intersections, if we have them already, return
143140
if (lcount > 1) return;
144-
Second_Center = Vector3d(0, BottomRadius, 0);
141+
// compute intersection with top sphere
142+
Second_Center = Vector3d(0, VerticalSpherePosition, 0);
145143
Padj = Second_Center - P;
146144

147145
OCSquared = Padj.lengthSqr();
@@ -172,7 +170,9 @@ void Ovus::Intersect_Ovus_Spheres(const Vector3d& P, const Vector3d& D,
172170

173171
}
174172
}
173+
// shape can only have a maximum of 2 intersections, if we have them already, return
175174
if (lcount > 1) return;
175+
// need to evaluate the spindle of the torus, because intersions are not yet all found
176176
Second_Center = Vector3d(0, VerticalPosition, 0);
177177
Padj = P - Second_Center;
178178
R2 = Sqr(HorizontalPosition);
@@ -196,7 +196,7 @@ void Ovus::Intersect_Ovus_Spheres(const Vector3d& P, const Vector3d& D,
196196

197197
c[4] = k1 * k1 + 4.0 * R2 * (Py2 - r2);
198198

199-
n = Solve_Polynomial(4, c, r, Test_Flag(this, STURM_FLAG), ROOT_TOLERANCE, Thread->Stats());
199+
n = Solve_Polynomial(4, c, r, Test_Flag(this, STURM_FLAG), RootTolerance, Thread->Stats());
200200
while (n--)
201201
{
202202
// here we only keep the 'lemon' inside the torus
@@ -213,7 +213,7 @@ void Ovus::Intersect_Ovus_Spheres(const Vector3d& P, const Vector3d& D,
213213
{
214214
horizontal = sqrt(Sqr(IPoint[X]) + Sqr(IPoint[Z]));
215215
OCSquared = Sqr((horizontal + HorizontalPosition)) + Sqr((vertical - VerticalPosition));
216-
if (fabs(OCSquared - Sqr(ConnectingRadius)) < ROOT_TOLERANCE)
216+
if (fabs(OCSquared - Sqr(ConnectingRadius)) < RootTolerance)
217217
{
218218
if (*Depth5 < 0)
219219
{
@@ -322,7 +322,7 @@ bool Ovus::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadDat
322322
if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
323323
{
324324
INormal = IPoint;
325-
INormal[Y] -= BottomRadius;
325+
INormal[Y] -= VerticalSpherePosition;
326326
INormal /= TopRadius;
327327
MTransNormal(Real_Normal, INormal, Trans);
328328
Real_Normal.normalize();
@@ -341,7 +341,7 @@ bool Ovus::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadDat
341341
if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
342342
{
343343
INormal = IPoint;
344-
INormal[Y] -= BottomRadius;
344+
INormal[Y] -= VerticalSpherePosition;
345345
INormal /= TopRadius;
346346
MTransNormal(Real_Normal, INormal, Trans);
347347
Real_Normal.normalize();
@@ -435,7 +435,7 @@ bool Ovus::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const
435435
DBL horizontal, vertical;
436436
bool INSide = false;
437437
Vector3d Origin, New_Point, Other;
438-
Origin = Vector3d(0, BottomRadius, 0);
438+
Origin = Vector3d(0, VerticalSpherePosition, 0);
439439
MInvTransPoint(New_Point, IPoint, Trans);
440440
OCSquared = New_Point.lengthSqr();
441441
if (OCSquared < Sqr(BottomRadius))
@@ -698,6 +698,8 @@ Ovus::Ovus() : ObjectBase(OVUS_OBJECT)
698698
BottomVertical = 0.0;
699699
TopVertical = 0.0;
700700
ConnectingRadius = 0.0;
701+
VerticalSpherePosition = 0.0;
702+
RootTolerance = 1.0e-4;
701703
}
702704

703705

@@ -774,7 +776,8 @@ ObjectPtr Ovus::Copy()
774776
******************************************************************************/
775777

776778
Ovus::~Ovus()
777-
{}
779+
{
780+
}
778781

779782

780783

@@ -811,7 +814,11 @@ void Ovus::Compute_BBox()
811814
{
812815
// Compute the biggest vertical cylinder radius
813816
DBL biggest;
817+
DBL bottom;
818+
DBL length;
814819
biggest = ConnectingRadius - HorizontalPosition;
820+
bottom = -BottomRadius;
821+
length = BottomRadius + VerticalSpherePosition + TopRadius;
815822
if (biggest < BottomRadius)
816823
{
817824
biggest = BottomRadius;
@@ -820,9 +827,17 @@ void Ovus::Compute_BBox()
820827
{
821828
biggest = TopRadius;
822829
}
830+
// handle degenerated ovus in sphere
831+
// negative value have been intercepted by Parser::Parse_Ovus
832+
// and the 0.0 is only possible for detected degenerated ovus in that function
833+
if (BottomRadius == 0.0)
834+
{
835+
bottom = VerticalSpherePosition-TopRadius;
836+
length = 2*TopRadius;
837+
}
823838

824-
Make_BBox(BBox, -biggest, -BottomRadius, -biggest,
825-
2.0 * biggest, 2.0 * BottomRadius + TopRadius, 2.0 * biggest);
839+
Make_BBox(BBox, -biggest, bottom, -biggest,
840+
2.0 * biggest, length, 2.0 * biggest);
826841

827842
Recompute_BBox(&BBox, Trans);
828843
}
@@ -883,46 +898,64 @@ void Ovus::UVCoord(Vector2d& Result, const Intersection *Inter, TraceThreadData
883898
*
884899
* CHANGES
885900
*
901+
* due to the addition of distance, the mapping is changed to something similar
902+
* to lemon, cone & cylinder
903+
*
886904
******************************************************************************/
887905

888906
void Ovus::CalcUV(const Vector3d& IPoint, Vector2d& Result) const
889907
{
890-
DBL len, x, y, z;
908+
DBL len, x, z, t;
891909
DBL phi, theta;
892910
Vector3d P;
893911

894-
// Transform the ray into the ovus space.
912+
// Transform the point back into the ovus space.
895913
MInvTransPoint(P, IPoint, Trans);
896914

897-
// the center of UV coordinate is the bottom center when top radius ->0
898-
// and it is the top center when top radius -> 2.0* bottom radius
899-
// when top radius == bottom radius, it is half-way between both center
900-
//
901-
// bottom center is <0,0,0>
902-
// top center is <0,BottomRadius,0>
903-
// TODO FIXME - comment doesn't seem to match the following code
915+
// the center of UV coordinate is the <0,0> point
904916
x = P[X];
905-
// y = P[Y] - BottomRadius*(TopRadius/(2.0*BottomRadius));
906-
y = P[Y] - (TopRadius/2.0);
907917
z = P[Z];
908918

909-
// now assume it's just a sphere, for UV mapping/projection
910-
len = sqrt(x * x + y * y + z * z);
919+
// Determine its angle from the point (0, 0, 0) in the x-z plane.
920+
len = x * x + z * z;
911921

912-
if (len == 0.0)
913-
return;
922+
if ( (P[Y] > EPSILON) && (P[Y] < (VerticalSpherePosition - EPSILON) ) )
923+
{
924+
// when on the spindle, the range 0.25 to 0.75 is used
925+
// Verbatim from C-Lipka:
926+
// Dividing at 1/4 and 3/4 has the advantage of the division being exactly at a pixel boundary
927+
// if the texture is an image 2^N by 2^M pixels in size, which is common for image textures
928+
// originally designed for mesh-based renderers. It also happens to work for 20N by 20M pixels,
929+
// which is common for image textures with "arbitrary" sizes.
930+
phi = 0.75-0.5*(P[Y])/(VerticalSpherePosition);
931+
}
932+
else if (P[Y]>EPSILON)
933+
{
934+
// aka P[Y] is above VerticalSpherePositon, use TopRadius, from 0% to 25%
935+
phi = 0.0;
936+
if (TopRadius != 0.0)
937+
{
938+
t = ((P[Y]-VerticalSpherePosition)/(TopRadius));
939+
phi = (sin(sqrt(1-t)*M_PI_2)/(4.0));
940+
}
941+
}
914942
else
915943
{
916-
x /= len;
917-
y /= len;
918-
z /= len;
944+
// aka P[Y] is below origin (<0), use BottomRadius, from 75% to 100%
945+
phi = 1.0;
946+
if (BottomRadius != 0.0)
947+
{
948+
t = ((BottomRadius+P[Y])/(BottomRadius));
949+
phi = 1.0-sin(sqrt(t)*M_PI_2)/(4.0);
950+
}
951+
else if (TopRadius != 0.0) // per Parser::Parse_Ovus, TopRadius & BottomRadius cannot be both 0.0 at the same time, but keep the test due to division
952+
{
953+
// degenerate ovus in sphere
954+
t = ((TopRadius-VerticalSpherePosition+P[Y])/(TopRadius));
955+
phi = 1.0-sin(sqrt(t)*M_PI_2)/(4.0);
956+
}
919957
}
920958

921-
// Determine its angle from the x-z plane.
922-
phi = 0.5 + asin(y) / M_PI; // This will be from 0 to 1
923-
924-
// Determine its angle from the point (1, 0, 0) in the x-z plane.
925-
len = x * x + z * z;
926959

927960
if (len > EPSILON)
928961
{

source/core/shape/ovus.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,12 @@ class Ovus : public ObjectBase
9696
DBL BottomVertical;
9797
/// highest vertical for the connecting surface (computed)
9898
DBL TopVertical;
99-
/// Radius of the connecting surface (computed)
99+
/// Radius of the connecting surface (computed, or provided in SDL)
100100
DBL ConnectingRadius;
101+
/// vertical position of center of top sphere (computed or provided in SDL)
102+
DBL VerticalSpherePosition;
103+
/// precision for root solver
104+
DBL RootTolerance;
101105

102106
private:
103107
void CalcUV(const Vector3d& IPoint, Vector2d& Result) const;

0 commit comments

Comments
 (0)