POV-Ray : Newsgroups : povray.binaries.images : sphere sphere sphere : Re: sphere sphere sphere Server Time
11 Aug 2024 09:25:58 EDT (-0400)
  Re: sphere sphere sphere  
From: IMBJR
Date: 9 Apr 2004 18:23:09
Message: <4077224d@news.povray.org>
"Chris Johnson" <chris(at)chris-j(dot)co(dot)uk> wrote in message
news:40771c73$1@news.povray.org...
> -[I had a version of this going down to level 6, but after 4 hours of
> parsing I gave up]-
> Have you considered writing a program in another language, and exporting
> pov-ray code? This might improve things a bit on the speed front.

It probably would, but I've not got the resources to do that.

>
> Which "level" is the image attached at? If I understand you correctly, its
> level 2? If so, six levels of recursion would create a massive number of
> spheres - about 30^6 = 730,000,000, if you keep the current "resolution"
of
> about 30 smaller spheres making up one big sphere. It should be OK with
> level 3 (27,000 spheres) though.

Level 4, which creates 1034 spheres. Remember, each sphere is not
necessarily created at the lowest level. If a sphere can fit into the master
sphere at level 1 then it will be created within the scene; plus, after each
sphere is determined it too is then octree-traversed at level 4.

Here's the code. You will probably find that it's quite inefficient. I've
probably not got the knack for writing good POV code for this sort of thing:

-- code begins:

#version 3.5;

#include "transforms.inc"

global_settings {
  assumed_gamma 1.0
  max_trace_level 100
}

#include "rad_def.inc"
global_settings {
  radiosity {
    Rad_Settings(Radiosity_OutdoorLQ, off, on) // Radiosity_OutdoorLight
  }
}

// Constants
// Split ratios
#declare xsr = 0.5;
#declare ysr = 0.5;
#declare zsr = 0.5;
// Level of detail of scan
#declare level_limit = 4; //4;
// Offset from edges of emitted area
#declare os = 0.5;

// ----------------------------------------

// Basic scene

/*
camera {
  location  <0.0, 0.0, -550.0>
  direction 1.5*z
  right     x*image_width/image_height
  look_at   <0.0, 0.0,  0.0>
}
*/

/*
light_source {
  <0, 0, 0>            // light's position (translated below)
  color rgb <1, 1, 1>  // light's color
  translate <0, 0, -300>
}
*/

background {
 color rgb <0.7,0.7,1>
}

sky_sphere {
  pigment {
    gradient y
    color_map {
      [0.0 rgb 0.1]
      [0.7 rgb 0]
    }
  }
}

#declare target_object =
sphere {
 <0,0,0>, 100
}

// ----------------------------------------

#macro all_inside_check(p1, p2, p3, p4, p5, p6, p7, p8)

#if (
  (p1 = 1) &
  (p2 = 1) &
  (p3 = 1) &
  (p4 = 1) &
  (p5 = 1) &
  (p6 = 1) &
  (p7 = 1) &
  (p8 = 1)
    )

 #declare all_inside = true;

#else

 #declare all_inside = false;

#end

#end

// ----------------------------------------

#macro emit(near_corner, far_corner)

#local fore_left_bottom_inside = inside(scan_object,
            near_corner);

#local fore_right_bottom_inside = inside(scan_object,
            <far_corner.x,
             near_corner.y,
             near_corner.z>);
#local fore_left_top_inside  = inside(scan_object,
            <near_corner.x,
             far_corner.y,
             near_corner.z>);
#local fore_right_top_inside = inside(scan_object,
            <far_corner.x,
             far_corner.y,
             near_corner.z>);
#local rear_left_bottom_inside = inside(scan_object,
            <near_corner.x,
             near_corner.y,
             far_corner.z>);
#local rear_right_bottom_inside = inside(scan_object,
            <far_corner.x,
             near_corner.y,
             far_corner.z>);
#local rear_left_top_inside  = inside(scan_object,
            <near_corner.x,
             far_corner.y,
             far_corner.z>);
#local rear_right_top_inside = inside(scan_object,
            far_corner);

all_inside_check(
     fore_left_bottom_inside,
     fore_right_bottom_inside,
     fore_left_top_inside,
     fore_right_top_inside,
     rear_left_bottom_inside,
     rear_right_bottom_inside,
     rear_left_top_inside,
     rear_right_top_inside,
    )

#if (all_inside = true)

 #local bright =
   texture {
    pigment {
     color rgb 1
    }
    finish {
     diffuse 1
     ambient 0.75
    }
   }
 #local dark =
   texture {
    pigment {
     color rgb 1
    }
    finish {
     diffuse 0.5
     ambient 0.25
    }
   }

 #local emit_object =
  sphere {
   (near_corner+far_corner)/2, dx/3
   texture {
    slope y
    texture_map {
     [0 bright]
     [1 dark]
    }
   }
  }

  #if (final_emit = on)
   object{emit_object}
 #else
  scan_3d(
   emit_object,
   min_extent(emit_object)-2,
   max_extent(emit_object)+2,
   1,on)

 #end

#end

#end

// ----------------------------------------

#macro emit_control()

#local emitted = off;

// Disimilars get emitted if they have not already been so:

#if (fore_left_bottom_data[1] = 0)
 emit(near_corner,
   near_corner+cv)
 #local emitted = on;
#end

#if (fore_right_bottom_data[1] = 0)
 emit(<near_corner.x+cx, near_corner.y, near_corner.z>,
   <far_corner.x, near_corner.y+cy, near_corner.z+cz>)
 #local emitted = on;
#end

#if (fore_left_top_data[1] = 0)
 emit(<near_corner.x, near_corner.y+cy, near_corner.z>,
   <near_corner.x+cx, far_corner.y, near_corner.z+cz>)
 #local emitted = on;
#end

#if (fore_right_top_data[1] = 0)
 emit(<near_corner.x+cx, near_corner.y+cy, near_corner.z>,
   <far_corner.x, far_corner.y, near_corner.z+cz>)
 #local emitted = on;
#end

#if (rear_left_bottom_data[1] = 0)
 emit(<near_corner.x, near_corner.y, near_corner.z+cz>,
   <near_corner.x+cx, near_corner.y+cy, far_corner.z>)
 #local emitted = on;
#end

#if (rear_right_bottom_data[1] = 0)
 emit(<near_corner.x+cx, near_corner.y, near_corner.z+cz>,
   <far_corner.x, near_corner.y+cy, far_corner.z>)
 #local emitted = on;
#end

#if (rear_left_top_data[1] = 0)
 emit(<near_corner.x, near_corner.y+cy, near_corner.z+cz>,
   <near_corner.x+cx, far_corner.y, far_corner.z>)
 #local emitted = on;
#end

#if (rear_right_top_data[1] = 0)
 emit(near_corner+cv,
   far_corner)
 #local emitted = on;
#end

// Decide on return data
#if (emitted = on)
 #declare return_data = array [2] {fore_left_bottom_data[0],1};
#else
 #declare return_data = array [2] {fore_left_bottom_data[0],0};
#end

#end

// ----------------------------------------

#macro scan_3d(scan_object,near_corner,far_corner,level,final_emit)

// Get locations etc.
#local dx = abs(far_corner.x - near_corner.x);
#local dy = abs(far_corner.y - near_corner.y);
#local dz = abs(far_corner.z - near_corner.z);
#local cx = dx*xsr;
#local cy = dy*ysr;
#local cz = dz*zsr;
#local cv = <cx,cy,cz>;

#if (level < level_limit) // Further downwards scanning?

 // fore left bottom
 scan_3d(scan_object,
   near_corner,
   near_corner+cv,
   level+1,final_emit)
 #local fore_left_bottom_data = return_data;

 // fore right bottom
 scan_3d(scan_object,
   <near_corner.x+cx, near_corner.y, near_corner.z>,
   <far_corner.x, near_corner.y+cy, near_corner.z+cz>,
   level+1,final_emit)
 #local fore_right_bottom_data = return_data;

 // fore left top
 scan_3d(scan_object,
   <near_corner.x, near_corner.y+cy, near_corner.z>,
   <near_corner.x+cx, far_corner.y, near_corner.z+cz>,
   level+1,final_emit)
 #local fore_left_top_data = return_data;

 // fore right top
 scan_3d(scan_object,
   <near_corner.x+cx, near_corner.y+cy, near_corner.z>,
   <far_corner.x, far_corner.y, near_corner.z+cz>,
   level+1,final_emit)
 #local fore_right_top_data = return_data;

 // rear left bottom
 scan_3d(scan_object,
   <near_corner.x, near_corner.y, near_corner.z+cz>,
   <near_corner.x+cx, near_corner.y+cy, far_corner.z>,
   level+1,final_emit)
 #local rear_left_bottom_data = return_data;

 // rear right bottom
 scan_3d(scan_object,
   <near_corner.x+cx, near_corner.y, near_corner.z+cz>,
   <far_corner.x, near_corner.y+cy, far_corner.z>,
   level+1,final_emit)
 #local rear_right_bottom_data = return_data;

 // rear left top
 scan_3d(scan_object,
   <near_corner.x, near_corner.y+cy, near_corner.z+cz>,
   <near_corner.x+cx, far_corner.y, far_corner.z>,
   level+1,final_emit)
 #local rear_left_top_data = return_data;

 // rear right top
 scan_3d(scan_object,
   near_corner+cv,
   far_corner,
   level+1,final_emit)
 #local rear_right_top_data = return_data;

 // Are all of the point sampled inside the target object?
 all_inside_check(fore_left_bottom_data[0],
      fore_right_bottom_data[0],
      fore_left_top_data[0],
      fore_right_top_data[0],
      rear_left_bottom_data[0],
      rear_right_bottom_data[0],
      rear_left_top_data[0],
      rear_right_top_data[0]
     )

 // All inside?
 #if (all_inside = true)

  // No "children" emitted?
  #if (
    (fore_left_bottom_data[1] = 0) &
    (fore_right_bottom_data[1] = 0) &
    (fore_left_top_data[1]  = 0) &
    (fore_right_top_data[1]  = 0) &
    (rear_left_bottom_data[1] = 0) &
    (rear_right_bottom_data[1] = 0) &
    (rear_left_top_data[1]  = 0) &
    (rear_right_top_data[1]  = 0)
      )

   #declare return_data = array[2] {fore_left_bottom_data[1], 0}

  #else // Some emitted, check others

   emit_control()

  #end // Children emitted check

 #else // Not all inside

  emit_control()

 #end // all_inside check

#else // No, get raw data

 #local fore_left_bottom_inside = inside(scan_object,
            near_corner);
 #declare return_data = array[2] {
          fore_left_bottom_inside,
          0 // Not emitted
         };

#end // End of level check

#end // End of macro

// ----------------------------------------

fog {
  fog_type   2
  distance   20 //10
  color      rgb 0.5
  fog_offset 0.1
  fog_alt    0.2
  turbulence 0.8
}


plane {
 y, 0
 texture {
  pigment {
   color rgb 0.5
  }
  finish {
   diffuse 1
   ambient 0
  }
 }
}

#declare final = union {
scan_3d(
 target_object,
 min_extent(target_object)-15,
 max_extent(target_object)+15,
 1,off)
}

#declare ye = max_extent(final).y-min_extent(final).y;

object{
 final
 transform{Center_Trans(final,x+y+z)}
 translate <0,ye/2,0>
 rotate <0,33,0>
}

camera {
  location  <0.0, ye*0.75, -350.0>
  direction 1.5*z
  right     x*image_width/image_height
  look_at   <0.0, ye/2,  0.0>
}

/*
light_source {
  <0, ye*0.75, -250>
  color rgb <1, 1, 1>
}
*/
-- code ends



>
> -Chris
>
>


Post a reply to this message

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