POV-Ray : Newsgroups : povray.general : Interlocking Heightfields. Server Time
31 Jul 2024 02:28:41 EDT (-0400)
  Interlocking Heightfields. (Message 11 to 20 of 33)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Thomas de Groot
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 10:31:14
Message: <482854b2$1@news.povray.org>
"Stephen" <mcavoysAT@aolDOTcom> schreef in bericht 
news:vlgg24d2uho0olc8us6unf682kdm9nooh7@4ax.com...
>
> Thanks Thomas, on cleaning up my code (below) I found your problem.
> But I also discovered that I don't understand the "function", function
> :)
>
Well Stephen, I suppose your function code was not too bad.  :-)
The only thing I could maybe say is that you do not really need to rotate 
the pattern -90*x. like with the pigment {image_map ....}.

Nice sky code by the way!

Thomas


Post a reply to this message

From: Stephen
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 10:38:46
Message: <nelg24p0kualu9282f1f3r41g7jvkb352l@4ax.com>
On Mon, 12 May 2008 16:31:13 +0200, "Thomas de Groot"
<t.d### [at] internlDOTnet> wrote:

>
>"Stephen" <mcavoysAT@aolDOTcom> schreef in bericht 
>news:vlgg24d2uho0olc8us6unf682kdm9nooh7@4ax.com...
>>
>> Thanks Thomas, on cleaning up my code (below) I found your problem.
>> But I also discovered that I don't understand the "function", function
>> :)
>>
>Well Stephen, I suppose your function code was not too bad.  :-)
>The only thing I could maybe say is that you do not really need to rotate 
>the pattern -90*x. like with the pigment {image_map ....}.

I wonder why Rune did that? I just copied his code to understand the
macro :)

>Nice sky code by the way!
>
Stolen from PoseRay I think. 
If it is not bolted down it walks and if it is it gets painted :)

Thanks for your time. (Finished your Bridge builders, Hmm!)
-- 

Regards
     Stephen


Post a reply to this message

From: Robert McGregor
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 15:30:01
Message: <web.482899ea8c5c8be8bd1b3ad10@news.povray.org>
"Thomas de Groot" <t.d### [at] internlDOTnet> wrote:

> I just finished my Bridge entry, so I have time to spare :-)
> I shall have a look at this and report back.

And I just viewed your entry, very nice job Thomas! Wonderful use of theme.

Now if I could only think of something... I often seem to have this problem of
my brain not "clicking" on what to render until the last few days (and
sometimes too late, as in The Mother Hive, alas, I missed that one by a day...)

-Rob

"There is no spoon."


Post a reply to this message

From: Kenneth
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 17:10:01
Message: <web.4828b0f28c5c8be878dcad930@news.povray.org>
"Thomas de Groot" <t.d### [at] internlDOTnet> wrote:

>
> What I have done sometimes, and if some repetition is not too obvious in the
> final image, is to mirror a height_field along x or z (or both, according to
> need). The seam is absolutely invisible.
>
> Thomas

That's a wonderful idea--and so obvious that it pains me that I've never thought
of it before. :-(

Ken W.


Post a reply to this message

From: Kenneth
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 17:20:00
Message: <web.4828b3b78c5c8be878dcad930@news.povray.org>
Stephen <mcavoysAT@aolDOTcom> wrote:
>
> My first thought was to use a function
> like:
>    height_field {
>       function 100, 100 {pattern {spotted scale 0.3 rotate -90*x}}
> smooth
>       scale <30,5,30>
>    }
>
> Which should define a height field in 3D space but I cannot find
> enough information in the documentation to enable me to do it
> properly...

That looks right to me--you've already figured it out! Though the rotation may
not be necessary, as the spotted pattern is a 3-D pattern, and will produce
results at *any* angle.

HFs made from functions have some odd built-in problems, though, as I've
discovered to my chagrin.  Take a look at something I posted recently...

http://news.povray.org/povray.advanced-users/thread/%3Cweb.47f304325a8bc21378dcad930%40news.povray.org%3E/

Ken W.


Post a reply to this message

From: John VanSickle
Subject: Re: Interlocking Heightfields.
Date: 12 May 2008 18:48:25
Message: <4828c939@news.povray.org>
Stephen wrote:
> Can anyone advise me on how to create a patchwork of heightfields
> where the edges match up? It is for a landscape and I've spent a
> couple of days trying to no avail.

I have something here that is horribly complex, but it may be helpful.

There are several macros here that do the work.  The upshot to all this 
is that I divide the x-z plane into a set of squares of unit size, and 
create a separate heightfield for each box.  Some of these squares are 
subdivided into smaller squares when they are near the camera.  Squares 
whose height_fields fall outside of the camera view are culled so that 
they don't take up memory space; this will be an issue if you have 
reflective surfaces that clearly show the off-camera portions of your 
scene.  The macro HF_Chunk() creates a height field for one square in 
the x-z plane, starting at a particular x-z location and going the 
specified size in the positive x and z directions.  I use one as the 
square size.  The precision of the height field is calculated based on 
the number of pixels the height field will span in the image.  This 
causes issues if the height field is near the viewpoint, so such height
fields are subdivided until every child is either off-camera (and 
culled) or no longer causing the problems from being too close.

The macro also allows you to pass a transform to it so that the height 
fields can be scaled and moved to where you want them.  It also requires 
a set of four vectors that determine the camera for you scene so that it 
can do the culling and precision calculations.

I have to warn the reader that this code is not particularly idiot-proof.

Hope this helps,
John

---------------------------

// This is used by the following macros.  It simply takes three
// vectors and uses them to create a transform.
#macro Matrix(mv_X,mv_Y,mv_Z,mv_L)
matrix <(mv_X).x,(mv_X).y,(mv_X).z,
         (mv_Y).x,(mv_Y).y,(mv_Y).z,
         (mv_Z).x,(mv_Z).y,(mv_Z).z,
         (mv_L).x,(mv_L).y,(mv_L).z >
#end

// This creates a single piece of pigment-based height field, which will
// tile neatly with other pieces using the same macro.  Imagine an array
// of boxes going forever in the x and z directions.
// * sU and sV give you a box in a particular column and row.
// * sS allows you to pick a larger or smaller chunk of height field. I
// recommend a value of 1.
// * pigUse is the pigment on which the height_fields are based.
// * transPut does a transform to the height fields so that they are
// scaled and placed where you want them.
// * vCamR is the right vector of the camera (not normalized)
// * vCamU is the up vector for the camera (not normalized)
// * vCamD is the direction vector for the camera (not normalized)
// * pCamL is the location of the camera
// * cLevel is the current subdivision level of the heightfield.
// This macro calls itself recursively, and cLevel is used to prevent
// infinite recursion.
// The recursion happens because the macro sets the precision of the
// heightfield to match the screen size of the heightfield (in pixels),
// which causes problems for heightfields that are near the camera.
// Dicing them up solved the problem.

#macro HF_Chunk(sU,sV,sS,pigUse,transPut,vCamR,vCamU,vCamD,pCamL,cLevel)
   #ifndef(Test) #local Test=1; #end
   // get a rough idea of the dimensions of the final block
   #local Block= height_field {
     function 32,32 { pigment { pigUse 
Matrix(x/sS,z,-y/sS,<-sU/sS,sV/sS+1,0>) } }
     scale <sS,1,sS>
     translate <sU,0,sV>
     transform transPut
   }
   #local pS=min_extent(Block);
   #local pE=max_extent(Block);
   #undef Block

   #if(BoxInProjectiveCamera(pCamL,vCamR,vCamU,vCamD,pS,pE))
// check to see if further subdivision is warranted
     #local fBefore=false;
     #local fBehind=false;
     #if( vdot(vnormalize(vCamD),<pS.x,pS.y,pS.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pE.x,pS.y,pS.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pS.x,pE.y,pS.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pE.x,pE.y,pS.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pS.x,pS.y,pE.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pE.x,pS.y,pE.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pS.x,pE.y,pE.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end
     #if( vdot(vnormalize(vCamD),<pE.x,pE.y,pE.z>-pCamL)>.01) #local 
fBefore=true; #else #local fBehind=true; #end

     #if( fBefore=true & fBehind=true & cLevel<8 )
       HF_Chunk(sU,     sV, 
sS/2,pigUse,transPut,vCamR,vCamU,vCamD,pCamL,cLevel+1)
       HF_Chunk(sU+sS/2,sV, 
sS/2,pigUse,transPut,vCamR,vCamU,vCamD,pCamL,cLevel+1)
       HF_Chunk(sU, 
sV+sS/2,sS/2,pigUse,transPut,vCamR,vCamU,vCamD,pCamL,cLevel+1)
 
HF_Chunk(sU+sS/2,sV+sS/2,sS/2,pigUse,transPut,vCamR,vCamU,vCamD,pCamL,cLevel+1)
     #else
       #local Detail=ProjectedBoxSize(pCamL,vCamR,vCamU,vCamD,pS,pE);
       #local Detail=max(2,min(512/(Test*7+1),Detail));
       height_field {
         function Detail,Detail { pigment { pigUse 
Matrix(x/sS,z,-y/sS,<-sU/sS,sV/sS+1,0>) } }
         scale <sS,1,sS>
         translate <sU,0,sV>
         transform transPut
       }
     #end // end of further subdivision check
   #end // end of entire container in projective camera test
#end // end of macro

// a macro to determine if a given box is in the camera view
// pCamL is the camera's location
// pCamD is the direction vector of the camera (*not* normalized)
// pCamR is the right vector of the camera (*not* normalized)
// pCamU is the up vector of the camera (*not* normalized)
// pStart is the box's starting location
// pEnd is the box's ending location
#macro BoxInProjectiveCamera(pCamL,vCamR,vCamU,vCamD,pS,pE)
   #local pQS=pS-pCamL;
   #local pQE=pE-pCamL;
   #local vLL=vCamD-vCamR/2-vCamU/2;
   #local vLR=vCamD+vCamR/2-vCamU/2;
   #local vUR=vCamD+vCamR/2+vCamU/2;
   #local vUL=vCamD-vCamR/2+vCamU/2;
   #local fResult=true;

   // if all points are behind the camera return false
   #if(max(
     vdot(<pQS.x,pQS.y,pQS.z>,vCamD),
     vdot(<pQS.x,pQS.y,pQE.z>,vCamD),
     vdot(<pQS.x,pQE.y,pQS.z>,vCamD),
     vdot(<pQS.x,pQE.y,pQE.z>,vCamD),
     vdot(<pQE.x,pQS.y,pQS.z>,vCamD),
     vdot(<pQE.x,pQS.y,pQE.z>,vCamD),
     vdot(<pQE.x,pQE.y,pQS.z>,vCamD),
     vdot(<pQE.x,pQE.y,pQE.z>,vCamD)
     )<0)
     #local fResult=false;
   #end

   // if all points are right of the view return false
   #local vN=vcross(vUR,vLR);
   #if(min(
     vdot(<pQS.x,pQS.y,pQS.z>,vN),
     vdot(<pQS.x,pQS.y,pQE.z>,vN),
     vdot(<pQS.x,pQE.y,pQS.z>,vN),
     vdot(<pQS.x,pQE.y,pQE.z>,vN),
     vdot(<pQE.x,pQS.y,pQS.z>,vN),
     vdot(<pQE.x,pQS.y,pQE.z>,vN),
     vdot(<pQE.x,pQE.y,pQS.z>,vN),
     vdot(<pQE.x,pQE.y,pQE.z>,vN)
     )>0)
     #local fResult=false;
   #end

   // if all points are below the view return false
   #local vN=vcross(vLR,vLL);
   #if(min(
     vdot(<pQS.x,pQS.y,pQS.z>,vN),
     vdot(<pQS.x,pQS.y,pQE.z>,vN),
     vdot(<pQS.x,pQE.y,pQS.z>,vN),
     vdot(<pQS.x,pQE.y,pQE.z>,vN),
     vdot(<pQE.x,pQS.y,pQS.z>,vN),
     vdot(<pQE.x,pQS.y,pQE.z>,vN),
     vdot(<pQE.x,pQE.y,pQS.z>,vN),
     vdot(<pQE.x,pQE.y,pQE.z>,vN)
     )>0)
     #local fResult=false;
   #end

   // if all points are left of the view return false
   #local vN=vcross(vLL,vUL);
   #if(min(
     vdot(<pQS.x,pQS.y,pQS.z>,vN),
     vdot(<pQS.x,pQS.y,pQE.z>,vN),
     vdot(<pQS.x,pQE.y,pQS.z>,vN),
     vdot(<pQS.x,pQE.y,pQE.z>,vN),
     vdot(<pQE.x,pQS.y,pQS.z>,vN),
     vdot(<pQE.x,pQS.y,pQE.z>,vN),
     vdot(<pQE.x,pQE.y,pQS.z>,vN),
     vdot(<pQE.x,pQE.y,pQE.z>,vN)
     )>0)
     #local fResult=false;
   #end

   // if all points are above the view return false
   #local vN=vcross(vUL,vUR);
   #if(min(
     vdot(<pQS.x,pQS.y,pQS.z>,vN),
     vdot(<pQS.x,pQS.y,pQE.z>,vN),
     vdot(<pQS.x,pQE.y,pQS.z>,vN),
     vdot(<pQS.x,pQE.y,pQE.z>,vN),
     vdot(<pQE.x,pQS.y,pQS.z>,vN),
     vdot(<pQE.x,pQS.y,pQE.z>,vN),
     vdot(<pQE.x,pQE.y,pQS.z>,vN),
     vdot(<pQE.x,pQE.y,pQE.z>,vN)
     )>0)
     #local fResult=false;
   #end

   (fResult)
#end

#macro ProjectedBoxSize(pL,vR,vU,vD,pS,pE)
   #local p000=vtransform(<pS.x,pS.y,pS.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p001=vtransform(<pS.x,pS.y,pE.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p010=vtransform(<pS.x,pE.y,pS.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p011=vtransform(<pS.x,pE.y,pE.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p100=vtransform(<pE.x,pS.y,pS.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p101=vtransform(<pE.x,pS.y,pE.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p110=vtransform(<pE.x,pE.y,pS.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );
   #local p111=vtransform(<pE.x,pE.y,pE.z>,transform { 
Matrix(vnormalize(vR),vnormalize(vU),vnormalize(vD),pL) inverse } );

   #local iRet=3;

   #if(p000.z>0 & p011.z>0)
     #local p000=p000/p000.z;
     #local p011=p011/p011.z;
     #local 
pQ=(p011-p000)*abs(vlength(vD))*<image_width/vlength(vR),image_height/vlength(vU),1>;
     #local iQ=floor(max(abs(pQ.x),abs(pQ.y)));
     #if(iQ>iRet) #local iRet=iQ; #end
   #end

   #if(p001.z>0 & p010.z>0)
     #local p001=p001/p001.z;
     #local p010=p010/p010.z;
     #local 
pQ=(p010-p001)*abs(vlength(vD))*<image_width/vlength(vR),image_height/vlength(vU),1>;
     #local iQ=floor(max(abs(pQ.x),abs(pQ.y)));
     #if(iQ>iRet) #local iRet=iQ; #end
   #end

   #if(p100.z>0 & p111.z>0)
     #local p100=p100/p100.z;
     #local p111=p111/p111.z;
     #local 
pQ=(p111-p100)*abs(vlength(vD))*<image_width/vlength(vR),image_height/vlength(vU),1>;
     #local iQ=floor(max(abs(pQ.x),abs(pQ.y)));
     #if(iQ>iRet) #local iRet=iQ; #end
   #end

   #if(p101.z>0 & p110.z>0)
     #local p101=p101/p101.z;
     #local p110=p110/p110.z;
     #local 
pQ=(p110-p101)*abs(vlength(vD))*<image_width/vlength(vR),image_height/vlength(vU),1>;
     #local iQ=floor(max(abs(pQ.x),abs(pQ.y)));
     #if(iQ>iRet) #local iRet=iQ; #end
   #end

   (iRet)
#end


Post a reply to this message

From: Stephen
Subject: Re: Interlocking Heightfields.
Date: 13 May 2008 03:13:41
Message: <crfi24908oujsb114u027u9o8h238rmgcp@4ax.com>
On Mon, 12 May 2008 14:03:05 +0200, "Thomas de Groot"
<t.d### [at] internlDOTnet> wrote:

>I just finished my Bridge entry, so I have time to spare :-)

Well done Thomas, you have made my problem go away. I was making the
same image. :)
I wonder how many people had the same idea?

I really like yours and will have to give it 20/20 for concept :)
-- 

Regards
     Stephen


Post a reply to this message

From: Thomas de Groot
Subject: Re: Interlocking Heightfields.
Date: 13 May 2008 03:21:34
Message: <4829417e$1@news.povray.org>
"Robert McGregor" <rob### [at] mcgregorfineartcom> schreef in bericht 
news:web.482899ea8c5c8be8bd1b3ad10@news.povray.org...
> "Thomas de Groot" <t.d### [at] internlDOTnet> wrote:
>
>> I just finished my Bridge entry, so I have time to spare :-)
>> I shall have a look at this and report back.
>
> And I just viewed your entry, very nice job Thomas! Wonderful use of 
> theme.

Thank you Robert! Much appreciated indeed.
This was one of those rare instances where everything clicked into place 
smoothly. Generally, the creative process is much rougher for me.

>
> Now if I could only think of something... I often seem to have this 
> problem of
> my brain not "clicking" on what to render until the last few days (and
> sometimes too late, as in The Mother Hive, alas, I missed that one by a 
> day...)

Don't think too much about it. Inspiration uses to hit when one least 
expects it.
I expect (and demand) at least a *wow* image from you!  :-)

Thomas


Post a reply to this message

From: Thomas de Groot
Subject: Re: Interlocking Heightfields.
Date: 13 May 2008 03:34:34
Message: <4829448a$1@news.povray.org>
"Kenneth" <kdw### [at] earthlinknet> schreef in bericht 
news:web.4828b3b78c5c8be878dcad930@news.povray.org...
>
> That looks right to me--you've already figured it out! Though the rotation 
> may
> not be necessary, as the spotted pattern is a 3-D pattern, and will 
> produce
> results at *any* angle.

I am not sure, but as far as I have been able to determine, the rotation is 
only needed when using a pigment{image_map  etc} as an image is oriented in 
the x-y plane. In the other cases, the rotation can be used to change the 
aspect of the pattern.

Thomas


Post a reply to this message

From: Thomas de Groot
Subject: Re: Interlocking Heightfields.
Date: 13 May 2008 03:47:23
Message: <4829478b$1@news.povray.org>
"Stephen" <mcavoysAT@aolDOTcom> schreef in bericht 
news:crfi24908oujsb114u027u9o8h238rmgcp@4ax.com...
>
> Well done Thomas, you have made my problem go away. I was making the
> same image. :)
Ouch! That is bad, Stephen! I don't like to 'cut the grass from under your 
feet' (like they say in French). Even if the images may be similar, we still 
need some comparisons.

I wonder now, if submitted images should not be hidden to the public until 
voting time? Wasn't that how it was at the IRTC?

> I wonder how many people had the same idea?
Well, there might be a significant lot...

>
> I really like yours and will have to give it 20/20 for concept :)
You are too kind, Stephen :-)

Thomas


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.