/* spring_plugin_1.a8s */ /* * 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. * */ /* * 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", "spring"); #parameter("sides", int, 6, 3, 16); #parameter("diameter", float, 10.0, 0.001, 99999, scale); #parameter("offset", float, 20.0, 0.0, 99999, scale, scale_x); #parameter("segments", int, 30, 1, 1000); #parameter("cycles", float, 3, 0.01, 100.0, scale_z); #parameter("spread", float, 15.0, 0.01, 100.0, scale, scale_y); #return($spring); #button(17, 25, 2, 0x00000fc6, 0x00007079, 0x00008009, 0x00010f89, 0x00013871, 0x000107e1, 0x0000c003, 0x0000300d, 0x00000ff9, 0x00007079, 0x00008009, 0x00010f89, 0x00013871, 0x000107e1, 0x0000c003, 0x0000300d, 0x00000ff9, 0x00007079, 0x00008009, 0x00010f89, 0x00013871, 0x000107e1, 0x0000c002, 0x0000300c, 0x00000ff0); shape $spring; /* Will hold the resulting mesh */ int $numSides; /* Number of sides on cross section */ float $diameter; /* Diameter of cross section */ float $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"); $diameter = parameter("diameter"); $offset = parameter("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; float $angle, $cosa, $sina; int $faceIndex, $i, $edgeIndex; /* Now build it: */ $radius = $diameter*0.5; /* $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. */ $spring.Open(); for $i = 0 to $numSides - 1 do { $texIndex[$i] = $spring.AddTexCoord(($u[$i], 0)); $vtxIndex[$i] = $spring.AddPoint($p[$i]); } $vtxIndex[$numSides] = $vtxIndex[0]; $texIndex[$numSides] = $texIndex[0]; /* First end cap: */ $faceIndex = $spring.OpenFace(0, 4); for $i = 0 to $numSides - 1 do { $spring.TexCoordN($texIndex[$i]); $spring.VertexN($vtxIndex[$i]); } $spring.CloseFace(); /* Set edge sharpness to rounded after 3 subdivisions: */ for $i = 0 to $spring.GetNumSides($faceIndex) do { $edgeIndex = $spring.GetEdgeIndex($faceIndex, $i); $spring.SetEdgeSharpness($edgeIndex, 3); } int $seg; point3 $p1; int $oldIndex, $newIndex, $temp; float $y, $percent; $oldIndex = 0; $newIndex = 17; for $seg = 1 to $segments do { /* 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] = $spring.AddPoint($p1); $texIndex[$newIndex + $i] = $spring.AddTexCoord(($u[$i], $percent)); } $vtxIndex[$newIndex + $numSides] = $vtxIndex[$newIndex]; $texIndex[$newIndex + $numSides] = $spring.AddTexCoord(($u[$numSides], 1)); /* Define faces for current segment: */ for $i = 0 to $numSides - 1 do { $spring.OpenFace(0, 4); $spring.TexCoordN($texIndex[$oldIndex + $i]); $spring.VertexN($vtxIndex[$oldIndex + $i]); $spring.TexCoordN($texIndex[$newIndex + $i]); $spring.VertexN($vtxIndex[$newIndex + $i]); $spring.TexCoordN($texIndex[$newIndex + $i + 1]); $spring.VertexN($vtxIndex[$newIndex + $i + 1]); $spring.TexCoordN($texIndex[$oldIndex + $i + 1]); $spring.VertexN($vtxIndex[$oldIndex + $i + 1]); $spring.CloseFace(); } /* Swap indexes */ $temp = $oldIndex; $oldIndex = $newIndex; $newIndex = $temp; } /* Final end cap: */ $faceIndex = $spring.OpenFace(0, 4); for $i = 0 to $numSides - 1 do { /* $oldIndex is last face */ $spring.TexCoordN($texIndex[$oldIndex + $i]); $spring.VertexN($vtxIndex[$oldIndex + $i]); } $spring.CloseFace(); /* Set edge sharpness to rounded after 3 subdivisions: */ for $i = 0 to $spring.GetNumSides($faceIndex) do { $edgeIndex = $spring.GetEdgeIndex($faceIndex, $i); $spring.SetEdgeSharpness($edgeIndex, 3); } /* Don't forget to close the shape or your changes might be lost! */ $spring.Close(); /* Fall off the end and your finished. */