MyCylinder modification
Blitz3D Forums/Blitz3D Programming/MyCylinder modification
| ||
Hi, I use the MyCylinder code from the archives... http://www.blitzbasic.com/codearcs/codearcs.php?code=863 I have noticed that the 'bottom' of the cylinder is not joined, i.e. imagine a sheet of paper bent and joined to form a cylinder, the two edges of the join have their own vertexes but in a Blitz cylinder the tris share vertexes. Does that make sense? Is there a GURU out there how can modify the creation of the cylinder (using the above code) to make a cylinder (with segments) that is joined? Many thanks, and you will get a special thank you in my application!!! |
| ||
I have noticed that the 'bottom' of the cylinder is not joined, i.e. imagine a sheet of paper bent and joined to form a cylinder, the two edges of the join have their own vertexes but in a Blitz cylinder the tris share vertexes. You sure? As far as I'm aware, blitz cycliners (and spheres, cones) have a 'seam' where duplicate verts are used - they're needed to UV map it correctly. |
| ||
Hmm, that is a bugger. The reason I see it is I use the RippleMesh code it 'tears' the seam. It doesn't when using a regular cylinder. |
| ||
Have you tried using the createcylinder() or a cylinder from a modelling package? To see if the problem still occurs? |
| ||
I use the MyCylinder code from the archives... www.blitzbasic.com/codearcs/codearcs.php?code=863 i need to use that |
| ||
I need to use it as it has the segments code in it. Anyone? There must be a bb god out there who can help... |
| ||
As big10p says you will get a discontinuity as the uvalue wraps from 1 to 0. There are ways to disguise this though, depending on your texture you could just mirror part of the texture and run the uvalues from 0 to 0.5 and then back to 0. Or you could run the uvalues from 0 to 1 and then back to 0 so you have the texture wrapped round the cylinder twice. As to joining up the verts so there is no seam around the body of the cylinder, I think it goes something like this.. Change the ring segment loops to For i=0 To (verticalsegments-2) And change the tri fill to ; Fill in ring segment sides with triangles For v=1 To (verticalsegments) If v=verticalsegments Then tl=tRing(0) tr=tRing(v-1) bl=bRing(0) br=bRing(v-1) Else tl=tRing(v) tr=tRing(v-1) bl=bRing(v) br=bRing(v-1) EndIf AddTriangle(thissurf,tl,tr,br) AddTriangle(thissurf,bl,tl,br) Next to get the texture wrapped twice try.. udiv#=Float(2.0/(verticalsegments)) And If i<verticalsegments/2 thisUPos#=thisUPos#-udiv# Else thisUpos=thisUpos+udiv instead of thisUPos#=thisUPos#-udiv# in the loops for the ring segments. You may have to tweak some of this though, I have not really tested it properly, but I expect you get the idea. |
| ||
Hi David, thanks, to be honest I do not get the idea! I have tried what you suggested but it doesn't appear to work correctly - it looks very odd now, could you please send me a complete example. Many thanks!!!! |
| ||
I suppose you could create a very small fillet between the cylinder and the cap, and use the extra ring of vertices to change the vertex co-ords. |
| ||
Hey DJWoodgate, any news on a working example? Please mate, grovel, grovel. |
| ||
[quote] I suppose you could create a very small fillet between the cylinder and the cap, [/qupte] Mmmmmm Fillet....Chicken Fillet....KFC Chicken Fillet Tower Burgers oohhh yummmy! (Aint it lunchtime yet?) |
| ||
Sorry i have not had much time to look at this. The problem is the rather simplistic way I have calculated ThisUpos. Obviously it must go to 0 and back to 1, but as it stands it will only do this properly with an even number of sides and besides which mirroring things like this requires a texture to suit. Now I was going to attempt to fix this but then I noticed Todds' original code had a problem with smoothing the normals across the seam in some cases. This is due to a slight offfset in the vertex positions between the first and final calculated x position (most noticeable with X anyway) on the circumference of the main body and is I think due to floating point precision issues on the result returned from the cos function which is started at 90 degrees and ends at 450 degrees. The way siderotangle is stepped by means of addition probably compounds the issue and adds a little more innacuracy. It occured to me this might be relevant to your ripple function, whatever that does, and so to fix that modify the Siderotangle step code in the two loops to If i<(verticalsegments-1) Then SideRotAngle#=SideRotAngle#+div# Else Siderotangle#=90 This should ensure that the finals verts will be positioned in exactly the same place as the first ones which may help. |
| ||
Aha. Actually if you are using that ripple code by Halo shipped with the samples, then you could modify that to treat the XYZ coords at the same Y in the same way and thus avoid tearing along the seam. I have made a quick mod to show what I mean. I expect you will be able to improve on this.; Halo's ripple mesh code modified for use with Todd Riggins Segmented cylinder. ;========================================================== Function ripple(mesh,omesh,depth#=0.1,speed#=0.1,freq#=200) Local k,surf,surf2,index,add#,pos#,newx#,newy#,newz#,time=MilliSecs() For k=1 To CountSurfaces(mesh) surf=GetSurface(mesh,k) surf2=GetSurface(omesh,k) For index=0 To CountVertices(surf)-1 newy#=VertexY(surf2,index) pos=newy*freq If wrapvalue#(time*speed+pos,0,720)>230 Or wrapvalue#(time*speed+pos,0,720)<270 add#=(Sin(time*speed+pos)*depth) newx#=VertexX(surf2,index)+add*VertexNX(surf2,index) newz#=VertexZ(surf2,index)+add*VertexNZ(surf2,index) Else add=depth*-1 newx#=VertexX(surf2,index)+add*VertexNX(surf2,index) newz#=VertexZ(surf2,index)+add*VertexNZ(surf2,index) EndIf VertexCoords surf,index,newx,newy,newz Next Next UpdateNormals mesh End Function Edit. Changed it a bit so you can use updatenormals on the mesh. |
| ||
Where / what / who / why is wrapvalue# |
| ||
Ah sorry, I guess you are not using Halo's code then. Have a look in the 3d samples folder under halo and meshfx. Anyway this is the wrapvalue function he uses... ;==================== Function wrapvalue#(value#,lo#,hi#) i=Floor(value/(hi-lo)) r#=i*(hi-lo) Return (value-r)+lo End Function Edit... Well although that is elegant, it still has some issues so I am looking to improve it, particularly when lo is negative and hi is positive or hi or lo are large numbers. I can't currently figure out how to modify it though so here is an alternative Function wrapvalue#(value#,low#,high#) If value<low Then value=high-(low-value) Mod (high-low) If value>=high Then value=low+(value-high) Mod (high-low) Return value End Function Here is another amended and more simplified version of the ripple function. ; Halo's ripple mesh code modified for use with Todd Riggins Segmented cylinder. ;========================================================== Function ripple(mesh,omesh,depth#=0.1,speed#=0.1,freq#=200) Local k,surf,surf2,index,add#,pos#,newx#,newy#,newz#,time=MilliSecs() And $FFFFFF For k=1 To CountSurfaces(mesh) surf=GetSurface(mesh,k) surf2=GetSurface(omesh,k) For index=0 To CountVertices(surf)-1 newy#=VertexY(surf2,index) pos#=newy*freq add#=Sin(wrapvalue(pos+time*speed,0,360))*depth newx#=VertexX(surf2,index)+add*VertexNX(surf2,index) newz#=VertexZ(surf2,index)+add*VertexNZ(surf2,index) VertexCoords surf,index,newx,newy,newz Next Next UpdateNormals mesh End Function In fact as this is pretty cylinder specific we can change it to deal with the end caps. ; Halo's ripple mesh code modified for use with Todd Riggins Segmented cylinder. ;========================================================== Function ripple(mesh,omesh,depth#=0.1,speed#=0.1,freq#=200) Local k,surf,surf2,index,add#,pos#,newx#,newy#,newz#,mag# Local time=MilliSecs() And $FFFFFF For k=1 To CountSurfaces(mesh) surf=GetSurface(mesh,k) surf2=GetSurface(omesh,k) verts=CountVertices(surf)-1 For index=0 To verts newx = VertexX(surf2,index) newy = VertexY(surf2,index) newz = VertexZ(surf2,index) pos = newy * freq add = Sin(wrapvalue(pos+time*speed,0,360)) * depth mag = Sqr(newx*newx+newz*newz) newx = newx + add * newx * mag newz = newz + add * newz * mag VertexCoords surf,index,newx,newy,newz Next Next UpdateNormals mesh End Function In fact I now see you are probably using the ripplemesh code on the archives, which is very much a different kettle of fish. I guess you could do something like that with a seamed mesh, but you will have to preprocess the mesh information to capture verts into a list of some sort and ensure coincident verts receive identical transforms, unless of course you can otherwise ensure that verts with the same X Y and Z will receive the same transform, which is something to ponder. |
| ||
Hi David, tried your code but it strange horrid things! I use this ripple mesh code from the archives... and the cylinder code also from the archives... Added em together, try running this, you will see the tear, can you fix this? I will give you special credits in my app :-) NICE ONE! TRY THIS CODE..... ; ID: 939 ; Author: Olive ; Date: 2004-02-20 07:58:15 ; Title: Tunnel Effect ; Description: A tunnel effect like in demos ; CreateMyCylinder Example ; ---------------------- ; By Pigmin (alias Olive) 02-20-2004 ; ; pigmin@... ; ; meet me at http://www.blitz3dfr.com (forum section) ; ; ; ; With wonderfull function : ; ; CreateMyCylinder ; ---------------------- ; By: Todd Riggins 12-22-2003 ; ; a CreateCylinder blitz-like function. Does the Same thing. Just wanted to do ; this to see how to actaully create a cylinder with the addvertex/addtriangle ; commands. Just thought I would share. ; ----------------- ; 2004-2-19 1:10:00 ; - Added ring segments. Ring Segment param of zero acts like the ; blitz-like Function. IE: no ring segments. ; - The added ring segments adds vertices to help bend cylinder tunnels or angle ; pipe meshs. Ofcoarse, you will need to add your own code to manipulate the ; cylinder's vertices. ; 2004-2-18 21:00:00 ; - Fixed normal vectors problem: Needed to have cylinder ends as seperate surface ; ; Left sphere is created by the CreateMyCylinder function. ; Right sphere is created by blitz's CreateCylinder command. ; ; Controls: ; - Use mouse to rotate the cylinders ; - wireframe toggle ; - Esc key to escape ; rediminsionable arrays Dim tRing(0) Dim bRing(0) Type TCtrlPoint Field x# Field y# End Type Const MAX_CTRL_POINTS = 16 Const TWIST# = 30 Global CtrlPoints.TCtrlPoint[MAX_CTRL_POINTS] Global CtrlPointsPhase% = 0 Global CtrlPointsPhase2% = 0 Graphics3D 640,480,0,2 SetBuffer BackBuffer() AmbientLight 32,0,0 camera=CreateCamera() CameraRange camera,.1,2000 light=CreateLight() RotateEntity light,90,0,0 ; enter how many segments the sphere has Global vsegs=32 Global rsegs=MAX_CTRL_POINTS ;Texture tex=CreateTexture(32,32,1+8) SetBuffer(TextureBuffer(tex)) colR = 128 For j = 0 To 31 Step 8 colR = 64 - colR For i = 0 To 31 Step 8 colR = 64 - colR Color colR,colR,colR Rect(i,j,8,8,1) Next Next SetBuffer (BackBuffer()) ScaleTexture tex,.25,.25 ;Texture2 tex2=CreateTexture(64,64,1+4+8) SetBuffer(TextureBuffer(tex2)) For j = 0 To 16 colR = Rand(10,64) colG = Rand(0,128) colB = Rand(0,180) Color colR,colG,colB Rect(Rand(0,63),Rand(0,63),Rand(1,2),Rand(1,31)) Rect(Rand(0,63),Rand(0,63),Rand(1,31),Rand(1,2)) Next SetBuffer (BackBuffer()) ScaleTexture tex2,.1,.25 TextureBlend tex,2 TextureBlend tex2,3 ; Create Cylinder manually mycylinder=CreateMyCylinder(vsegs,rsegs,False,0) ScaleMesh mycylinder,6,40,6 RotateMesh mycylinder,90,0,0 FlipMesh mycylinder PositionEntity mycylinder,0,0,39 EntityTexture mycylinder,tex,0,0 EntityTexture mycylinder,tex2,0,1 mycylindercopy = CopyMesh(mycylinder) HideEntity mycylindercopy ;allocate control points For i = 0 To MAX_CTRL_POINTS CtrlPoints[i] = New TCtrlPoint CtrlPoints[i]\x# = (i*260/MAX_CTRL_POINTS) CtrlPoints[i]\y# = (i*460/MAX_CTRL_POINTS) Next ; key helper wkey=0 xx#=0 cnt#=0 freqX = 1 freqY = 1 While Not KeyDown( 1 ) Tunnel_effect(mycylinder, mycylindercopy, CtrlPointsPhase, CtrlPointsPhase2) CtrlPointsPhase = CtrlPointsPhase + freqX CtrlPointsPhase2 = CtrlPointsPhase2 + freqY ripplemesh(mycylinder,1,1,2) If (Not Rand(0,200)) freqY = Rand(0,4) EndIf If (Not Rand(0,400)) freqX = Rand(1,4) EndIf PositionTexture Tex,0,cnt# PositionTexture Tex2,cnt#,cnt# cnt#=cnt#+.01*(freqX+freqY)*.5 If KeyDown(17) And wkey=0 wkey=1 EndIf If KeyDown(17)=False And wkey=1 wkey=0 If wframe=0 wframe=1 Else wframe=0 EndIf If wframe=0 WireFrame False If wframe=1 WireFrame True EndIf RenderWorld Flip Wend End ; --------------------------------------------------------- Function CreateMyCylinder(verticalsegments,ringsegments=0,solid=True,parent=0) Local tr,tl,br,bl; side of cylinder Local ts0,ts1,newts; top side vertexs Local bs0,bs1,newbs; bottom side vertexs If verticalsegments<3 Or verticalsegments>100 Then Return 0 If ringsegments<0 Or ringsegments>100 Then Return 0 thiscylinder=CreateMesh(parent) thissurf=CreateSurface(thiscylinder) If solid=True thissidesurf=CreateSurface(thiscylinder) EndIf div#=Float(360.0/(verticalsegments)) height#=1.0 ringSegmentHeight#=(height#*2.0)/(ringsegments+1) upos#=1.0 udiv#=Float(1.0/(verticalsegments)) vpos#=1.0 vdiv#=Float(1.0/(ringsegments+1)) SideRotAngle#=90 ; re-diminsion arrays to hold needed memory. ; this is used just for helping to build the ring segments... Dim tRing(verticalsegments) Dim bRing(verticalsegments) ;render end caps if solid If solid=True XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) ts0=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) bs0=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) ts1=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) bs1=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) For i=1 To (verticalsegments-2) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) newts=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) newbs=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) AddTriangle(thissidesurf,ts0,ts1,newts) AddTriangle(thissidesurf,newbs,bs1,bs0) If i<(verticalsegments-2) ts1=newts bs1=newbs EndIf Next EndIf ; ----------------------- ; middle part of cylinder thisHeight#=height# ; top ring first SideRotAngle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=upos# thisVPos#=0 tRing(0)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) For i=0 To (verticalsegments-1) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=thisUPos#-udiv# tRing(i+1)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) Next For ring=0 To (ringsegments) ; decrement vertical segment thisHeight=thisHeight-ringSegmentHeight# ; now bottom ring SideRotAngle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=upos# thisVPos#=thisVPos#+vdiv# bRing(0)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) For i=0 To (verticalsegments-1) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=thisUPos#-udiv# bRing(i+1)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) Next ; Fill in ring segment sides with triangles For v=1 To (verticalsegments) tl=tRing(v) tr=tRing(v-1) bl=bRing(v) br=bRing(v-1) AddTriangle(thissurf,tl,tr,br) AddTriangle(thissurf,bl,tl,br) Next ; make bottom ring segmentthe top ring segment for the next loop. For v=0 To (verticalsegments) tRing(v)=bRing(v) Next Next UpdateNormals thiscylinder Return thiscylinder End Function Function Tunnel_Effect(mesh, mesh_original, phase, phase2) cntsurf = CountSurfaces(mesh) surf=GetSurface(mesh,cntsurf) surf_original=GetSurface(mesh_original,cntsurf) cnt=CountVertices(surf) For s=0 To rsegs deltax# = Cos(CtrlPoints[s]\x# + phase)*(TWIST#/(s+1)) deltay# = Sin(CtrlPoints[s]\y# + phase2)*(TWIST#/(s+1)) firstVertice = s*(vsegs+1) endVertice = firstVertice + vsegs For a=firstVertice To endVertice x#=VertexX#(surf_original,a) y#=VertexY#(surf_original,a) z#=VertexZ#(surf_original,a) x#=x#+deltax# y#=y#+deltay# VertexCoords surf,a,x#,y#,z# Next Next UpdateNormals mesh End Function Function ripplemesh(mesh,speed#,density#,depth#) count=MilliSecs()*speed For scount=1 To CountSurfaces(mesh) surface = GetSurface(mesh,scount) numverts=CountVertices(surface)-1 For i=0 To numverts a#=Cos(count+(i*density))*speed b#=Sin(count+(i*density))*speed c#=-b;Sin(count+(i*density))*speed nx#=VertexNX(surface,i)*depth ny#=VertexNY(surface,i)*depth nz#=VertexNZ(surface,i)*depth x#=VertexX(surface,i) y#=VertexY(surface,i) z#=VertexZ(surface,i) VertexCoords surface,i,x#+(a*nx),y#+(b*ny),z#+(c*nz) Next Next End Function |
| ||
I am not very good at this stuff, but I doubt that ripplemesh code on the archives is going to be of much help to you, it lacks stability for a start. I would modify your tunnel effect function, which is IMO a lot more capable. The idea, I think, is to superimpose a "ripple" on the basic deltax and deltay tunnel distortion you are already producing. I have made an attempt, But it is still not working properly. |
| ||
Please stick with it mate -- I would be very grateful |
| ||
OK, I have solved a few issues. Still not perfect, and the ripples it does provide are tawdry affairs, so you will be able to improve on this. Use the F key to select the ripple scheme - nothing special, just some values I was playing with. The A key autoincrements ripple values, Ins/Del, Home/End and Page Up/Page Down keys manually alter the ripples, +/- on the numeric pad changes the depth and the R key resets. The space key just rotates the cylinder so you get an external view of the distortion applied. Edit. BTW Although not particularly noticeable in this code, if you do see bad normals being generated, then it may be partly due to the use of scalemesh so you could use scaleentity instead. I have not made that change here though as the twisting you do for your tunnel effect introduces enough irregularity to stop this occuring for the most part. I think it is a problem with updatenormals. ; ID: 939 ; Author: Olive ; Date: 2004-02-20 07:58:15 ; Title: Tunnel Effect ; Description: A tunnel effect like in demos ; CreateMyCylinder Example ; ---------------------- ; By Pigmin (alias Olive) 02-20-2004 ; ; pigmin@... ; ; meet me at www.blitz3dfr.com (forum section) ; ; ; ; With wonderfull function : ; ; CreateMyCylinder ; ---------------------- ; By: Todd Riggins 12-22-2003 ; ; a CreateCylinder blitz-like function. Does the Same thing. Just wanted to do ; this to see how to actaully create a cylinder with the addvertex/addtriangle ; commands. Just thought I would share. ; ----------------- ; 2004-2-19 1:10:00 ; - Added ring segments. Ring Segment param of zero acts like the ; blitz-like Function. IE: no ring segments. ; - The added ring segments adds vertices to help bend cylinder tunnels or angle ; pipe meshs. Ofcoarse, you will need to add your own code to manipulate the ; cylinder's vertices. ; 2004-2-18 21:00:00 ; - Fixed normal vectors problem: Needed to have cylinder ends as seperate surface ; ; Left sphere is created by the CreateMyCylinder function. ; Right sphere is created by blitz's CreateCylinder command. ; ; Controls: ; - Use mouse to rotate the cylinders ; - wireframe toggle ; - Esc key to escape ; rediminsionable arrays Dim tRing(0) Dim bRing(0) Type TCtrlPoint Field x# Field y# End Type Const MAX_CTRL_POINTS = 24 Const TWIST# = 30 Global CtrlPoints.TCtrlPoint[MAX_CTRL_POINTS] Global CtrlPointsPhase% = 0 Global CtrlPointsPhase2% = 0 Graphics3D 640,480,0,2 SetBuffer BackBuffer() AmbientLight 32,0,0 camera=CreateCamera() CameraClsColor camera, 255,0,0 CameraRange camera,.1,1000 light=CreateLight() RotateEntity light,45,0,0 ; enter how many segments the sphere has Global vsegs=24 Global rsegs=MAX_CTRL_POINTS ;Texture tex=CreateTexture(32,32,1+8) : ScaleTexture tex,.25,.25 SetBuffer(TextureBuffer(tex)) colR = 128 For j = 0 To 31 Step 8 colR = 64 - colR For i = 0 To 31 Step 8 colR = 64 - colR Color colR,colR,colR Rect(i,j,8,8,1) Next Next SetBuffer (BackBuffer()) ;Texture2 tex2=CreateTexture(64,64,1+4+8) : ScaleTexture tex2,.1,.25 SetBuffer(TextureBuffer(tex2)) For j = 0 To 16 colR = Rand(10,64) colG = Rand(0,128) colB = Rand(0,180) Color colR,colG,colB Rect(Rand(0,63),Rand(0,63),Rand(1,2),Rand(1,31)) Rect(Rand(0,63),Rand(0,63),Rand(1,31),Rand(1,2)) Next SetBuffer (BackBuffer()) TextureBlend tex,2 TextureBlend tex2,3 ; Create Cylinder manually mycylinder=CreateMyCylinder(vsegs,rsegs,False,0) ScaleMesh mycylinder,6,40,6 RotateMesh mycylinder,90,0,0 FlipMesh mycylinder PositionEntity mycylinder,0,0,40 EntityTexture mycylinder,tex,0,0 EntityTexture mycylinder,tex2,0,1 mycylindercopy = CopyMesh(mycylinder) HideEntity mycylindercopy ;allocate control points For i = 0 To MAX_CTRL_POINTS CtrlPoints[i] = New TCtrlPoint CtrlPoints[i]\x# = (i*260/MAX_CTRL_POINTS) CtrlPoints[i]\y# = (i*460/MAX_CTRL_POINTS) Next xx#=0 cnt#=0 freqX = 1 freqY = 4 rippx# = 0.0 rippy# = 0.0 rippz# = 0.0 depth# = 2.0 While Not KeyDown( 1 ) If (Not Rand(0,200)) freqY = Rand(0,4) EndIf If (Not Rand(0,400)) freqX = Rand(1,4) EndIf CtrlPointsPhase = CtrlPointsPhase + freqX CtrlPointsPhase2 = CtrlPointsPhase2 + freqY cnt=wrapvalue(cnt#+.01*(freqX+freqY)*.5,0,1) PositionTexture Tex,0,cnt# PositionTexture Tex2,cnt#,cnt# If KeyHit(19) Then ; R rippx=0 : rippy=0 : rippz=0 EndIf If KeyDown(29) Then Multiplier#=1 Else Multiplier#=0.1 rippx=rippx+(KeyDown(210)-KeyDown(211))*multiplier ; ins/del rippy=rippy+(KeyDown(199)-KeyDown(207))*multiplier ; home/end rippz=rippz+(KeyDown(201)-KeyDown(209))*multiplier ; page up/page down depth=depth+(KeyDown(078)-KeyDown(074))*multiplier ; numeric +/- If KeyHit(30) Then autoinc=Not autoinc If autoinc Then rippx=rippx+multiplier rippy=rippy+multiplier rippz=rippz+multiplier EndIf form=(form+KeyHit(33)) Mod 4 Tunnel_effect(mycylinder,mycylindercopy,CtrlPointsPhase,CtrlPointsPhase2,rippx,rippy,rippz,cnt*360,depth,form) If KeyHit(17) Then wire=Not wire : WireFrame wire If KeyDown(57) Then RotateEntity mycylinder,-90,0,0 Else RotateEntity mycylinder,0,0,0 RenderWorld Color 255,255,255 Text 0,0,"Ripple x "+RippX+" Ripple Y "+RippY+" Ripple Z "+RippZ+" Depth "+Depth+" Form "+form Flip Wend End Function Tunnel_Effect(mesh, mesh_original, phase, phase2, fx#, fy#, fz#, offset#, depth#, form) Local v# cntsurf = CountSurfaces(mesh) surf=GetSurface(mesh,cntsurf) surf_original=GetSurface(mesh_original,cntsurf) cnt=CountVertices(surf) For s=0 To rsegs deltax# = Cos(wrapvalue(Ctrlpoints[s]\x# + phase,0,360))*(TWIST#/(s+1)) deltay# = Sin(wrapvalue(Ctrlpoints[s]\y# + phase2,0,360))*(TWIST#/(s+1)) firstVertice = s*(vsegs+1) endVertice = firstVertice + vsegs For a=firstVertice To endVertice x#=VertexX#(surf_original,a) y#=VertexY#(surf_original,a) z#=VertexZ#(surf_original,a) Select form Case 0 addx#=Sin(wrapvalue(z*x*fx+offset,0,360))*depth addy#=Cos(wrapvalue(z*y*fy+offset,0,360))*depth Case 1 If a=endVertice Then v=firstVertice Else v=a ; mind the gap ! addx#=Sin(wrapvalue(v*fx,0,360))*depth addy#=Cos(wrapvalue(v*fy,0,360))*depth Case 2 addx#=Cos(wrapvalue(x*fx+offset,0,360))*depth addy#=Sin(wrapvalue(y*fy+offset,0,360))*depth addz#=-addx Case 3 inc=inc+1 : v = (inc Mod vsegs)*S ; mind the gap ! addx#=Sin(wrapvalue(v*fx+offset,0,360))*depth addy#=-Cos(wrapvalue(v*fy+offset,0,360))*depth addz#=Sin(-wrapvalue(v*fz+offset,0,360))*depth End Select mag#=Sqr(x*x+y*y+z*z) x#=x#+addx*(x/mag)+deltax y#=y#+addy*(y/mag)+deltay z#=z#+addz*(z/mag) VertexCoords surf,a,x#,y#,z# Next Next UpdateNormals mesh End Function Function wrapvalue#(value#,lo#,hi#) i=Floor(value/(hi-lo)) r#=i*(hi-lo) Return (value-r)+lo End Function ; --------------------------------------------------------- Function CreateMyCylinder(verticalsegments,ringsegments=0,solid=True,parent=0) Local tr,tl,br,bl; side of cylinder Local ts0,ts1,newts; top side vertexs Local bs0,bs1,newbs; bottom side vertexs If verticalsegments<3 Or verticalsegments>100 Then Return 0 If ringsegments<0 Or ringsegments>100 Then Return 0 thiscylinder=CreateMesh(parent) thissurf=CreateSurface(thiscylinder) If solid=True thissidesurf=CreateSurface(thiscylinder) EndIf div#=Float(360.0/(verticalsegments)) height#=1.0 ringSegmentHeight#=(height#*2.0)/(ringsegments+1) upos#=1.0 udiv#=Float(1.0/(verticalsegments)) vpos#=1.0 vdiv#=Float(1.0/(ringsegments+1)) SideRotAngle#=90 ; re-diminsion arrays to hold needed memory. ; this is used just for helping to build the ring segments... Dim tRing(verticalsegments) Dim bRing(verticalsegments) ;render end caps if solid If solid=True XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) ts0=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) bs0=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) ts1=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) bs1=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) For i=1 To (verticalsegments-2) SideRotAngle#=SideRotAngle#+div# XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) newts=AddVertex(thissidesurf,XPos#,height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) newbs=AddVertex(thissidesurf,XPos#,-height,ZPos#,XPos#/2.0+0.5,ZPos#/2.0+0.5) AddTriangle(thissidesurf,ts0,ts1,newts) AddTriangle(thissidesurf,newbs,bs1,bs0) If i<(verticalsegments-2) ts1=newts bs1=newbs EndIf Next EndIf ; ----------------------- ; middle part of cylinder thisHeight#=height# ; top ring first SideRotAngle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=upos# thisVPos#=0 tRing(0)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) For i=0 To (verticalsegments-1) If i<(verticalsegments-1) Then SideRotAngle#=SideRotAngle#+div# Else Siderotangle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=thisUPos#-udiv# tRing(i+1)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) Next For ring=0 To (ringsegments) ; decrement vertical segment thisHeight=thisHeight-ringSegmentHeight# ; now bottom ring SideRotAngle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=upos# thisVPos#=thisVPos#+vdiv# bRing(0)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) For i=0 To (verticalsegments-1) If i<(verticalsegments-1) Then SideRotAngle#=SideRotAngle#+div# Else Siderotangle#=90 XPos#=-Cos(SideRotAngle#) ZPos#=Sin(SideRotAngle#) thisUPos#=thisUPos#-udiv# bRing(i+1)=AddVertex(thissurf,XPos#,thisHeight,ZPos#,thisUPos#,thisVPos#) Next ; Fill in ring segment sides with triangles For v=1 To (verticalsegments) tl=tRing(v) tr=tRing(v-1) bl=bRing(v) br=bRing(v-1) AddTriangle(thissurf,tl,tr,br) AddTriangle(thissurf,bl,tl,br) Next ; make bottom ring segmentthe top ring segment for the next loop. For v=0 To (verticalsegments) tRing(v)=bRing(v) Next Next UpdateNormals thiscylinder Return thiscylinder End Function |
| ||
David, you are a god! Would you like a free copy of the full version of my app when its ready? Also would you like to be a beta tester? MANY MANY THANKS! By the way the app is Vorboils - check out www.boiledsweets.com/vorboils |
| ||
LOL. More godless than godlike I fear. Glad I was able to help though. Nice colorful looking screensaver, so yes cheers and I am willing to test it for you on my old win98 system if you want. While I am thinking about it you can perhaps avoid some of those calls to wrapvalue in the tunnel function. The Sin and Cos functions get a bit moody if their arguments are really large, as was the case in Halo's code which used millisecs, but that will probably not be a problem here as long as you do not let the ripple fx values run away. |