/* snailshell based on spring_plugin_1.a8s */ /* All I added/changed was to allow a start and end diameter, and a start * and end offset. If you set the start and end values the same, you get * the original spring. - NickE */ /* Original: * This script constructs a Mesh in the shape of a coiled spring * aligned along the Y-axis. * * Parameters: * * sides - sides on polygon extruded to from the coil. * diameter - diameter of polygon. * offset - radius of center of coil from center of Y-axis. * segments - total number of segments along coil. * cycles - number of revolutions for coil. * spread - vertical displacement between center of coils. * * Copyright 2006 R. Steven Glanville. Permission granted for * modification and use, including commercial use. Source * distribution must include this copyright. * */ /* Original: * Directives to install as Mesh plugin in Object editor. * * Plugin kind and name - defined by #plugin directive: * * arg1: string, editor kind. "object" is for the Object editor * arg2: string, plug-in kind. "mesh" is for a parameteric shape * arg3: string, name used in Anim8or interface to feref to this shape * * Parameters - defined by #parameter directives: * * arg1: string, parameter name * arg2: type name (int or float) * arg3: initial value * arg4: minimum value * arg5: maximum value * arg6+: Zero or more semantics for interaction: * scale - Scale commands apply to this value * scale_x - Non-uniform X scaling applies * scale_y - Non-uniform Y scaling applies * scale_z - Non-uniform Z scaling applies * * Return value - #return directive gives variable that will hold the result * when the script is finished. It nust be declared in the scrips. For a * Parameteric Shape it must be of type shape. * * Icon for toolbar - defined by #button directive. * * arg1: width in pixels. Max value of 32 but anything above 25 doesn't * all show up. * arg2: height in pixels Mas value of 32 but again it's best to stay * at 25 or less. * arg3: number of colors - must be 2 * arg4+ "height" number of 32 bit hex values. The right most "width" bits * are used as a bit map with 1's being the icon and 0's the background. * */ #plugin("object", "mesh", "spiral"); #parameter("sides", int, 6, 3, 16); #parameter("start_diameter", float, 1.0, 0.001, 99999, scale); #parameter("end_diameter", float, 35.0, 0.001, 99999, scale); #parameter("start_offset", float, 0.0, 0.0, 99999, scale, scale_x); #parameter("end_offset", float, 5.0, 0.0, 99999, scale, scale_x); #parameter("segments", int, 60, 1, 1000); #parameter("cycles", float, 3, 0.01, 100.0, scale_z); #parameter("spread", float, 12.0, 0.01, 100.0, scale, scale_y); #return($spiral); #button(17, 25, 2, 0x0000000000, 0x0000000000, 0x0000000000, 0x00000003c0, 0x0000000c20, 0x0000003190, 0x0000004648, 0x0000009824, 0x0000012392, 0x0000014c4a, 0x0000015129, 0x00000152a5, 0x0000014895, 0x0000012715, 0x0000009025, 0x0000004cc9, 0x0000002312, 0x0000001824, 0x00000004c8, 0x0000000310, 0x0000000020, 0x00000001c0, 0x0000000000, 0x0000000000, 0x0000000000); shape $spiral; /* Will hold the resulting mesh */ int $numSides; /* Number of sides on cross section */ float $start_diameter; /* Diameter of cross section */ float $end_diameter; /* Diameter of cross section */ float $start_offset; /* Radius of spring coil */ float $end_offset; /* Radius of spring coil */ int $segments; /* Segments along length of coil */ float $cycles; /* Times coil wraps around */ float $spread; /* Distance between centers of coils */ /* Get spring parameters from Anim8or: */ $numSides = parameter("sides"); $start_diameter = parameter("start_diameter"); $end_diameter = parameter("end_diameter"); $start_offset = parameter("start_offset"); $end_offset = parameter("end_offset"); $segments = parameter("segments"); $cycles = parameter("cycles"); $spread = parameter("spread"); /* Declare some working variables: */ point3 $p[16]; float $u[17]; /* U component of texture coordinates */ point3 $p0; int $vtxIndex[34]; int $texIndex[34]; float $radius, $t,$radius_step,$offset_step,$offset; float $angle, $cosa, $sina; int $faceIndex, $i, $edgeIndex; /* Now build it: */ $radius = $start_diameter*0.5; $radius_step = (($end_diameter * 0.5) - ($start_diameter * 0.5)) / $segments; $offset_step = ($end_offset - $start_offset) / $segments; $offset = $start_offset; /* $numSides = min(16, $numSides); /* Only room for 16 sides */ /* Define a '$numSides' sided N-gon: */ for $i = 0 to $numSides - 1 do { $u[$i] = (1.0*$i)/$numSides; $t = (2*3.14159*$i)/$numSides; $p[$i] = (sin($t)*$radius + $offset, cos($t)*$radius, 0); } $u[$numSides] = 1.0; /* Tilt it to face along the coil: */ $angle = atan($spread/(2*3.14159*$offset)); $cosa = cos($angle); $sina = sin($angle); for $i = 0 to $numSides - 1 do { $p0 = $p[$i]; $p[$i].y = $cosa*$p0.y - $sina*$p0.z; $p[$i].z = $sina*$p0.y + $cosa*$p0.z; } /* A new, empty mesh is assigned to $spring before the script runs. */ /* Open a mesh or you can't edit it. */ $spiral.Open(); for $i = 0 to $numSides - 1 do { $texIndex[$i] = $spiral.AddTexCoord(($u[$i], 0)); $vtxIndex[$i] = $spiral.AddPoint($p[$i]); } $vtxIndex[$numSides] = $vtxIndex[0]; $texIndex[$numSides] = $texIndex[0]; /* First end cap: */ $faceIndex = $spiral.OpenFace(0, 4); for $i = 0 to $numSides - 1 do { $spiral.TexCoordN($texIndex[$i]); $spiral.VertexN($vtxIndex[$i]); } $spiral.CloseFace(); /* Set edge sharpness to rounded after 3 subdivisions: */ for $i = 0 to $spiral.GetNumSides($faceIndex) do { $edgeIndex = $spiral.GetEdgeIndex($faceIndex, $i); $spiral.SetEdgeSharpness($edgeIndex, 3); } int $seg; point3 $p1; int $oldIndex, $newIndex, $temp; float $y, $percent; $oldIndex = 0; $newIndex = 17; for $seg = 1 to $segments do { /* Calculate next sized n-gon */ $radius = $radius + $radius_step; $offset = $offset + $offset_step; for $i = 0 to $numSides - 1 do { $u[$i] = (1.0*$i)/$numSides; $t = (2*3.14159*$i)/$numSides; $p[$i] = (sin($t)*$radius + $offset, cos($t)*$radius, 0); } $u[$numSides] = 1.0; /* Transform points in cross section to next position: */ $percent = ($seg*1.0)/$segments; $angle = (2*3.14159*$cycles)*$percent; $sina = sin($angle); $cosa = cos($angle); $y = ($spread*$cycles)*$percent; for $i = 0 to $numSides - 1 do { $p0 = $p[$i]; $p1.x = $cosa*$p0.x + $sina*$p0.z; $p1.y = $p0.y + $y; $p1.z = -$sina*$p0.x + $cosa*$p0.z; $vtxIndex[$newIndex + $i] = $spiral.AddPoint($p1); $texIndex[$newIndex + $i] = $spiral.AddTexCoord(($u[$i], $percent)); } $vtxIndex[$newIndex + $numSides] = $vtxIndex[$newIndex]; $texIndex[$newIndex + $numSides] = $spiral.AddTexCoord(($u[$numSides], 1)); /* Define faces for current segment: */ for $i = 0 to $numSides - 1 do { $spiral.OpenFace(0, 4); $spiral.TexCoordN($texIndex[$oldIndex + $i]); $spiral.VertexN($vtxIndex[$oldIndex + $i]); $spiral.TexCoordN($texIndex[$newIndex + $i]); $spiral.VertexN($vtxIndex[$newIndex + $i]); $spiral.TexCoordN($texIndex[$newIndex + $i + 1]); $spiral.VertexN($vtxIndex[$newIndex + $i + 1]); $spiral.TexCoordN($texIndex[$oldIndex + $i + 1]); $spiral.VertexN($vtxIndex[$oldIndex + $i + 1]); $spiral.CloseFace(); } /* Swap indexes */ $temp = $oldIndex; $oldIndex = $newIndex; $newIndex = $temp; } /* Final end cap: */ $faceIndex = $spiral.OpenFace(0, 4); for $i = 0 to $numSides - 1 do { /* $oldIndex is last face */ $spiral.TexCoordN($texIndex[$oldIndex + $i]); $spiral.VertexN($vtxIndex[$oldIndex + $i]); } $spiral.CloseFace(); /* Set edge sharpness to rounded after 3 subdivisions: */ for $i = 0 to $spiral.GetNumSides($faceIndex) do { $edgeIndex = $spiral.GetEdgeIndex($faceIndex, $i); $spiral.SetEdgeSharpness($edgeIndex, 3); } /* Don't forget to close the shape or your changes might be lost! */ $spiral.Close(); /* Fall off the end and your finished. */