Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 014: "Spider Web"

Georg you’re just too cool for school. nice spider.

J.

Awesome work people. I’m loving the turnout for this one. Here’s my half-baked effort:


 strand = 0
 strandNum = 6.0
 newWeb = #()
 
 fn drawLineBetweenTwoPoints pointA pointB =
 (
 	ss = SplineShape pos:pointA
 	addNewSpline ss
 	addKnot ss 1 #corner #line PointA
 	addKnot ss 1 #corner #line PointB
 	updateShape ss
 	
 	
 
 	for i = 1.0 to strandNum do
 	(
 		knotPos = ((i/(strandNum+1)) as float)
 		print knotPos
 		refineSegment ss 1 i knotPos
 		updateShape ss
 	)
 	
 	--refineSegment ss 1 i knotPos
 	updateShape ss
 	ss
 )
 
 fn drawCircles webStrands =
 (
 	baseWebs = webStrands.count 
 	for  x = 1 to baseWebs do
 	(
 		for i = 1.0 to strandNum do
 		(
 			
 			PointA = getKnotPoint webStrands[x] 1 i
 			if (x+1) > baseWebs then a = 1 else a = (x+1)
 			PointB = getKnotPoint webStrands[a] 1 i
 			ss = SplineShape pos:pointA
 			addNewSpline ss
 			addKnot ss 1 #corner #line PointA
 			addKnot ss 1 #corner #line PointB
 			updateShape ss	
 			refineSegment ss 1 1 0.5
 			updateShape ss	
 		)
 		
 		for i = 1.0 to strandNum do
 		(
 			
 			PointA = getKnotPoint webStrands[x] 1 i
 			if (x+1) > baseWebs then a = 1 else a = (x+1)
 			PointB = getKnotPoint webStrands[a] 1 ((strandNum+1)-i)
 			ss = SplineShape pos:pointA
 			addNewSpline ss
 			addKnot ss 1 #corner #line PointA
 			addKnot ss 1 #corner #line PointB
 			updateShape ss
 			refineSegment ss 1 1 0.5
 			updateShape ss		
 		)
 
 	)
 	
 )
 
 
 tool webLine
 (
 	local webPoint1
 	local webPoint2
 	
 	on mousePoint clickno do
 	(
 		if clickno == 2 then webPoint1 = worldPoint 
 		if clickno == 3 then
 		(
 			webPoint2 = worldPoint 
 			print webPoint1
 			print webPoint2
 			strand +=1
 			newWeb[strand] = drawLineBetweenTwoPoints webPoint1 webPoint2 
 		)
 		
 		if clickno == 4 then webPoint1 = worldPoint 
 		if clickno == 5 then
 		(
 			webPoint2 = worldPoint 
 			print webPoint1
 			print webPoint2
 			strand +=1
 			newWeb[strand] = drawLineBetweenTwoPoints webPoint1 webPoint2 
 			
 			drawCircles newWeb
 		)
 
 	)
 
 )
 
 
 rollout spiderWeb "Spider Web" width:162 height:177
 (
 	button webBtn "Web" pos:[31,29] width:91 height:30
 	spinner strandSpn "Strands" pos:[36,108] width:78 height:16 range:[1,100,strandNum]
 	spinner sagSpn "Sag	 " pos:[38,84] width:78 height:16 range:[0,100,0]
 	button createBtn "Create" pos:[35,133] width:83 height:30
 	
 	on webBtn pressed do
 	(
 		startTool webLine numPoint: 2
 	)
 	on strandSpn changed val do
 	(
 		strandNum = val
 	)
 	on sagSpn changed val do
 	(
 		--
 		--
 	)
 	on createBtn pressed  do
 	(
 		--
 		--
 	)
 )
 
 createDialog spiderWeb
 

Instructions:[ol]
[li]Press the WEB button.[/li][li]Click in two points where you want to place the web (Use snap to verts for maximum effect)[/li][li]Click in two more points for the cross support[/li][li]The web will generate automatically.[/li][li]If you want to create more webbing that crosses these ones, follow steps 1 – 3 again. The web will automatically link up and cross over the other one. Repeat ad nauseum.[/li][/ol]You’ll see the obvious flaws and errors. I unfortunately didn’t have much time, so they’re still all square.

One day i’ll hopefully finish it. A pretty poor effort on my part.

hey blue,

that’s a great effort! I you’ve gone to all the effort and it looks sensational!

a suggestion?

  • maybe you could incorporate a random number (or specified) of divisions on the frame segments.
  • also, if you change it to allow multi-spline shapes then you could stretch webs between frames.

J.

Incidently, i’ll leave this one up until next week. I’ll have a new challenge for over the holidays.

Really guys, a damn good effort this time around. It’s so good to see you all motivated!

Hi tea monkey,

yes maabe a little under-done, but I like the way you can continue to build on your web by drawing more start / ends.

good work, maybe you’ll have a little more time to fininsh it.

maybe I’ll have some time to write one myself LOL

J.

The lastest update:

[ul]
[li]added the ability to pick a line object as well as a splineshape for a custom frame (will only web the first spline)[/li][li]added droop to the radial strands[/li][li]exposed control to more features[/li][li]added water droplets and materials[/li][li]increased segment density for center of web[/li][li]added segment length effect on gravity[/li][li]started work on branching of strands (in the UI but doesn’t do anything yet)[/li][/ul]

-------------------------------------------------
 -------------------------------------------------
 -- spiderWebGenerator
 -- written by: Blue
 -- version 1.5
 -- history:
 --	Thursday, Dec 07, 2006  - added segment length gravity option
 --							- added materials
 --							- exposed more functions
 --							- refined droop smoothing
 --	Wednesday, Dec 06, 2006 - added anchor strand droop
 --							- added water drops
 --	Tuesday, Dec 05, 2006   - changed framing method to spline
 --							- added gaps
 --							- added gravity
 --							- added UI
 --	Monday, Dec 04, 2006	- started development
 --
 -- TODO:
 --	add branching
 --
 -------------------------------------------------
 -------------------------------------------------
 global spiderWebROLL
 (
 	centerNode = undefined
 	webShape
 	webShapeNgon
 	webShapeCustom
 	webSpline
 	knotPositionArray
 	centerPos = [0,0,0]
 	webBendLow = 0.05
 	webBendHigh = 0.05
 	try(DestroyDialog spiderWebROLL)catch()
 	-------------------------------------------------
 	-- main UI
 	-------------------------------------------------
 	rollout spiderWebROLL "Blues Spider Web Generator v1.5" width:300 height:345
 	(
 		fn splineFilter obj = classof obj == SplineShape or classof obj == line
 
 		fn enableCreatWebButton =
 		(
 			try
 			(
 				if webShape.name != undefined then spiderWebROLL.createWeb.enabled = true
 			)
 			catch(spiderWebROLL.createWeb.enabled = false)
 		)
 		
 		button createFrame "Template Web Frame" height:20 width:135 across:3 offset:[6,0]
 		button frameSwap "<-" height:20 width:20 offset:[1,0]
 		pickbutton customFrame "Pick Custom Frame" height:20 width:135 offset:[-27,0] filter:splineFilter
 		label step2Label "Edit the Web Frame to adjust placement of points and" align:#left
 		label step21Label "add points as needed." align:#left
 		pickButton webCenter "Overide Center Node - undefined" height:20 width:270 across:2 offset:[10,0]
 		button resetCenter "X" height:20 width:20 offset:[67,0]
 		spinner webSegs "Web Segs :" width:80 height:16 range:[4,100,24] type:#integer across:2 align:#left
 		checkbox webSegsRandom "Random Seg Length" height:15 checked:true align:#left
 		spinner webThickness "Web Thickness " range:[.001,10.0,0.02] width:80 align:#left
 		checkbox webbingGapsRandom "Random Gaps" width:92 height:15 checked:true across:2 align:#left
 		spinner webbingGapsRandomPercent "Gap % " width:80 height:16 range:[0,100,15] align:#left
 		checkbox webbingBranching "Random Branching" height:15 checked:true across:2 align:#left
 		spinner webbingBranchingPercent "Branching % " width:100 height:16 range:[0,100,15] align:#left
 		checkbox webbingBendEnabled "Webbing Bend" width:95 height:15 checked:true across:2 align:#left
 		checkbox webbingBendRandom "Randomize Bend" width:105 height:15 checked:false align:#left
 		checkbox webbingGravity "Gravity" width:57 height:15 checked:true across:2 align:#left
 		spinner webbingGravityStrength "Strength " width:90 height:16 range:[0,1000,5.0] align:#left
 		checkbox bendConsiderLength "Consider strand segment length for gravity effect" checked:true
 		spinner webDroopMod "Droop Strength " width:90 height:16 range:[.001,3.0,1.5] across:2 align:#left
 		spinner webDroopSmooth "Droop Smooth " width:90 height:16 range:[.001,1.0,0.25] align:#left
 		checkbox webWater "Add water drops" height:15 checked:false across:2 align:#left
 		radioButtons webWaterType "" labels:#("Spheres","Blobby") default:1 columns:2 align:#left
 		spinner webWaterCount "Drops " width:80 height:16 range:[1,50000,2000] type:#integer across:2 align:#left
 		spinner webWaterSize "Drops Size " width:80 height:16 range:[.001,100,.25] align:#left
 		button createWeb "Create Web From Web Frame" height:40 width:290 offset:[-1,0] enabled:false
 		timer deleteSplineWeb "" interval:100 active:false
 		timer branchWebSegments "" interval:100 active:false
 		timer webWaterTimer "" interval:100 active:false
 		
 		on createFrame pressed do
 		(
 			webShapeNgon = ngon radius:30 nSides:8
 			webShapeNgon.name = "Web Frame"
 			frameSwap.text = "<-"
 			webShape = webShapeNgon
 			convertTo webShapeNgon SplineShape
 			enableCreatWebButton()
 		)
 		on frameSwap pressed do
 		(
 			if frameSwap.text == "<-" then
 			(
 				frameSwap.text = "->"
 				webShape = webShapeCustom
 				enableCreatWebButton()
 			)
 			else
 			(
 				frameSwap.text = "<-"
 				webShape = webShapeNgon
 				enableCreatWebButton()
 			)
 		)
 		on customFrame picked obj do
 		(
 			webShapeCustom = obj
 			convertTo obj SplineShape
 			frameSwap.text = "->"
 			webShape = webShapeCustom
 			customFrame.text = obj.name
 			enableCreatWebButton()
 		)
 		on webCenter picked node do
 		(
 			centerNode = node
 			webCenter.text = "Overide Center Node - " + node.name
 			centerPos = centerNode.pos
 		)
 		on resetCenter pressed do
 		(
 			centerNode = undefined
 			webCenter.text = "Overide Center Node - undefined"
 		)
 		on webbingBendEnabled changed state do
 		(
 			if state == true then
 			(
 				webbingBendRandom.enabled = true
 				webbingGravity.enabled = true
 				bendConsiderLength.enabled = true
 				webbingGravityStrength.enabled = true
 				webDroopMod.enabled = true
 				webDroopSmooth.enabled = true
 				if webbingBendRandom.checked == true then
 				(
 					webBendLow = 0.01
 					webBendHigh = 0.05
 				)
 				else
 				(
 					webBendLow = 0.05
 					webBendHigh = 0.05
 				)
 			)
 			else
 			(
 				webbingBendRandom.enabled = false
 				webbingGravity.enabled = false
 				bendConsiderLength.enabled = false
 				webbingGravityStrength.enabled = false
 				webDroopMod.enabled = false
 				webDroopSmooth.enabled = false
 				webBendLow = 0.0
 				webBendHigh = 0.0
 			)
 		)
 		on webbingBendRandom changed state do
 		(
 			if state == true then
 			(
 				webBendLow = 0.01
 				webBendHigh = 0.05
 			)
 			else
 			(
 				webBendLow = 0.05
 				webBendHigh = 0.05
 			)
 		)
 		on deleteSplineWeb tick do
 		(
 			deleteSplineWeb.active = false
 			subobjectlevel = 0
 		)
 		on branchWebSegments tick do
 		(
 			branchWebSegments.active = false
 			
 			updateShape webSpline
 		)
 		on webWaterTimer tick do
 		(
 			webWaterTimer.active = false
 			webSpline.render_displayRenderMesh = true
 			addmodifier webSpline (edit_poly())
 			waterDropParticles = PArray emitter:webSpline formation:0 speed:0 Speed_Variation:0 Birth_Rate:10 Total_Number:(webWaterCount.value) quantityMethod:1 viewPercent:100 Emitter_Start:0f Emitter_Stop:0f Display_Until:100000f life:100001f Life_Variation:0f size:(webWaterSize.value) Size_Variation:25 Growth_Time:0f Fade_Time:0f seed:(random 1 64000) particleType:(webWaterType.state - 1) standardParticle:7 iconSize:10 iconHidden:off pos:webSpline.pos name:"Web Water Droplets"
 			waterDropParticles.wirecolor = blue
 			waterDropParticles.material = standardMaterial name:"Web Water Drops" twoSided:on diffuse:(color 55 55 105) ambient:(color 55 55 105) specular:(color 255 255 255) glossiness:55 specularLevel:95 opacityMap:(falloff color1:(color 32 32 32)) reflectionMap:(falloff map2:(falloff map2:(Raytrace ()) type:3))
 		)
 		on createWeb pressed do
 		 (
 			 try
 			(
 				if isDeleted webShape != true then
 				(
 					 disableSceneRedraw()
 					splineDivisions = webSegs.value
 					knotPositionArray = #()
 					webMajorWidth = 0
 					webShape.renderable = false
 					for i = 1 to (numKnots webShape 1) do
 					(
 						append knotPositionArray (getKnotPoint webShape 1 i)
 					)
 					for i = 1 to knotPositionArray.count do
 					(
 						if i != knotPositionArray.count then
 						(
 							if (distance knotPositionArray[i] knotPositionArray[i+1]) > webMajorWidth then webMajorWidth = (distance knotPositionArray[i] knotPositionArray[i+1])
 						)
 						else
 						(
 							if (distance knotPositionArray[i] knotPositionArray[1]) > webMajorWidth then webMajorWidth = (distance knotPositionArray[i] knotPositionArray[1])
 						)
 					)
 					if centerNode == undefined then
 					(
 						centerPos = [0,0,0]
 						for i in knotPositionArray do
 						(
 							centerPos += i
 						)
 						centerPos /= knotPositionArray.count
 					)
 					else
 					(
 						try(centerPos = centerNode.pos)catch()
 					)
 					webSpline = SplineShape name:"Web"
 					for i = 1 to knotPositionArray.count do
 					(
 						addNewSpline webSpline
 						addKnot webSpline i #corner #line  centerPos
 						addKnot webSpline i #corner #line  knotPositionArray[i]
 						updateShape webSpline
 						subdivideSegment webSpline i 1 splineDivisions
 						subdivideSegment webSpline i 3 3
 						subdivideSegment webSpline i 2 3
 						subdivideSegment webSpline i 1 3
 						subdivideSegment webSpline i 1 3
 						setKnotType webSpline i (splineDivisions + 14) #corner
 						setKnotType webSpline i 1 #corner
 						for j = 2 to (splineDivisions + 13) do
 						(
 							setKnotType webSpline i j #smooth
 						)
 						updateShape webSpline
 					)
 					if webSegsRandom.checked == true then
 					(
 						for i = 1 to knotPositionArray.count do
 						(
 							for j = 2 to (splineDivisions + 13) do
 							(
 								scaledPos = ((getKnotPoint webSpline i j)-(((getKnotPoint webSpline i j) - ((getKnotPoint webSpline i (j-1))))*(random -.5 .5)))
 								setKnotType webSpline i j #smooth
 								setKnotPoint webSpline i j scaledPos
 								updateShape webSpline
 							)
 						)
 					)
 					if webbingGravity.checked == true and webbingGravity.enabled == true then
 					(
 						gravityStrength = webbingGravityStrength.value * webDroopMod.value
 						for i = 1 to knotPositionArray.count do
 						(
 							distanceToCenter = distance (getKnotPoint webSpline i (splineDivisions +14)) centerPos
 							for j = 1 to (splineDivisions +13) do
 							(
 								scalePosLinear = gravityStrength - (gravityStrength * ((distance (getKnotPoint webSpline i j) centerPos) / distanceToCenter))
 								scalePosExponential = (gravityStrength - (gravityStrength * ((distance (getKnotPoint webSpline i j) centerPos)^gravityStrength / distanceToCenter^gravityStrength)))
 								scalePos = ((scalePosExponential * (1 - webDroopSmooth.value)) + (webDroopSmooth.value * scalePosLinear))
 								setKnotPoint webSpline i j ((getKnotPoint webSpline i j) - [0,0,scalePos])
 								updateShape webSpline
 							)
 						)
 					)
 					addNewSpline webSpline
 					webbingSpline = knotPositionArray.count + 1
 					ringPoint = 2
 					addKnot webSpline webbingSpline #corner #curve (getKnotPoint webSpline 1 ringPoint)
 					for i = 2 to (splineDivisions + 13) do
 					(
 						for j = 1 to knotPositionArray.count do
 						(
 							addKnot webSpline webbingSpline #corner #curve (getKnotPoint webSpline j i)
 						)
 					)
 					updateShape webSpline
 					if webbingBendEnabled.checked == true then
 					(
 						for i = (knotPositionArray.count * (splineDivisions + 12)) to 1 by -1 do
 						(
 							subdivideSegment webSpline (knotPositionArray.count + 1) i 1
 							updateShape webSpline
 						)
 						webArcCount = ((splineDivisions + 12) * (knotPositionArray.count * 2))
 						for i = 2 to webArcCount by 2 do
 						(
 							setKnotSelection webSpline webbingSpline #(i) keep:true
 						)
 						updateShape webSpline
 						selectedKnots = getKnotSelection webSpline webbingSpline
 						for i =  1 to selectedKnots.count do
 						(
 							if bendConsiderLength.checked == true then
 							(
 								bendEffectMod = ((distance (getKnotPoint webSpline webbingSpline (selectedKnots[i]-1)) (getKnotPoint webSpline webbingSpline (selectedKnots[i]+1))) / webMajorWidth)
 							)
 							else
 							(
 								bendEffectMod = 1
 							)
 							if webbingGravity.checked == true then
 							(
 								scaledPos = ((getKnotPoint webSpline webbingSpline selectedKnots[i])-(((getKnotPoint webSpline webbingSpline selectedKnots[i]) - centerPos)*(random webBendLow webBendHigh)))
 								scaledPos = (getKnotPoint webSpline webbingSpline selectedKnots[i]) - scaledPos
 								scaledPos = (getKnotPoint webSpline webbingSpline selectedKnots[i]) - (([0,0,((abs(scaledPos[1]) + abs(scaledPos[2]) + abs(scaledPos[3]))/3)])*webbingGravityStrength.value*bendEffectMod)
 							)
 							else
 							(
 								scaledPos = ((getKnotPoint webSpline webbingSpline selectedKnots[i])-(((getKnotPoint webSpline webbingSpline selectedKnots[i]) - centerPos)*(random webBendLow webBendHigh)))
 							)
 							setKnotPoint webSpline webbingSpline selectedKnots[i] scaledPos
 							setKnotType webSpline webbingSpline selectedKnots[i] #smooth
 							updateShape webSpline
 						)
 					)
 					if webbingGapsRandom.checked == true then
 					(
 						for i = (numSegments webSpline webbingSpline) to 2 by -2 do
 						(
 							if (random 0 100.0) < webbingGapsRandomPercent.value then
 							(
 								setSegSelection webSpline webbingSpline #(i,(i-1)) keep:true
 							)
 							updateShape webSpline
 						)
 						max modify mode
 						select webSpline
 						subobjectlevel = 2
 						splineOps.delete webSpline
 						updateShape webSpline
 						deleteSplineWeb.active = true
 					)
 					x = 1
 					if webbingBranching.checked == true then
 					(
 						branchWebSegments.active = true
 					)
 					webSpline.pivot = webSpline.center
 					webSpline.render_renderable = true
 					webSpline.render_thickness = webThickness.value 
 					webSpline.wirecolor = yellow
 					webSpline.material = standardMaterial name:"Web" diffuse:(color 255 255 235) ambient:(color 255 255 235) specular:(color 255 255 235) glossiness:30 specularLevel:30
 					if webWater.checked == true then
 					(
 						webWaterTimer.active = true
 					)
 					x = 1
 				)
 				else enableCreatWebButton()
 			)catch
 			(
 				enableCreatWebButton()
 			)
 			enableSceneRedraw()
 			gc()
 		)
 	)
 	createdialog spiderWebROLL style:#(#style_minimizebox, #style_titlebar, #style_sysmenu, #style_border)
 )
 

Thanks for the suggestions J

 The template frame is just a quick starting point, you can edit in as many points as you want and move them around if you like.[]( http://forums.cgsociety.org/attachment.php?attachmentid=106039&stc=1) 

Hey Blue,

That’s one hell of a tool for making spider webs. Simply amazing.

Light

Thanks Light, I seem to have become just slightly obsessed with the spider web concept

 rdg

Blue,
very clever water dropplets!

Georg

Page 3 / 4