Rotating textures around texture centre
Blitz3D Forums/Blitz3D Programming/Rotating textures around texture centre
| ||
The function RotateTexture() rotates a texture about it's top-left corner. Is there any way to set the rotation to happen around the texture's centre, which is a far more useful action? eg. I've some a lightmap texture of some under-bridge strip-lighting that maps squarely over my 'car'. When it drives forwards I use PositionTexture() to move the texture backwards giving the illusion of motion. When my car turns the camera turn too, so the player is always driving up the screen. As such I want the texture to rotate about it's centre. At the moment the lightmap just gets skewed. I can't figure a solution, either through texture manipulation or clever UV rigging. Has anyone got this type of effect working? Cheers. |
| ||
Well, I guess you may try with LoadAnimTexture, providing a texture strip, each frame with a different angle texture rotation. Then, depending on the angle turn of the car, use the appropriate texture animation frame. It should also result faster than RotateTexture command IMO. Anyway, I think it would be easyer when I read that you rotate the camera, and not the car; in this case, should be possible to apply always the same texture (frame). I mean, if the bridge is always at 90 degrees in respect of the street, it would cast always the same 'shadow' on the car - assuming a vertical lighing - so where's the problem ? Am I missing something obvious here ? Are you using TurnEntity to turn your car, aren't you ? Because if you use RotateMesh instead, then you may get the texture screwed up.. =) Another solution would be using a black (negative) spot light parented above the car, and switch it on each time it passes under a bridge. For black light I mean a light color of -255,-255,-255: LightColor light_under_bridge,-255,-255,-255Just switch it on when the car is under the bridge, and then set it off when out.. it may give you a good bridge-shadow effect without any texture-rotation hassle.. Sergio. |
| ||
My example's not necessarily a specific implementation. I'm experimenting towards some 'stuff' :) I'll give another example, which is a specular highlight map. Conventional specular lights are lousy for low-resolution models, showing jaggy vertices. At the moment I can use a map of a couple of spot highlights, and use 'Add' texture blending. Let's say I've got two directional light from the top left and top right. I have two spots in the top left and top right corners on my texture. Now if I rotate the lights around the player, I need the spots to rotate in the texture, around the texture's centre. Your idea of an animated texture would work in some instances and was one I hadn't thought of, though i guess for smooth animations there'd be a pretty massive texture size! |
| ||
The code archive is your friend: http://www.blitzbasic.com/codearcs/codearcs.php?code=420 |
| ||
Thanks for the info and suggestions thus far. I've given this some work and got so far, but can't perfect it. My trig skills leave a lot to be desired!! Here is a test program I've written, with model and texture: www.davidcoombes.f2s.com/test.zip If that doesn't work, you can access it from the link at www.davidcoombes.f2s.com The cursor keys control 'vehicle' rotation and forwards/backwards. The camera is fixed behind the 'vehicle'. As the vehicle turns, the camera turns with it. As such the 'reflected' texture, mapped to the model's UV, is supposed to rotate. When the vehicle drives forwards, up the screen, the texture needs to scroll down the screen. Try the program and it kinda works. The texture scrolls okay. But there's jumps, and the rotation is off-centre and not uniform. At first I tried to work out the maths, but when that didn't work a tried a few guesswork hacks which haven't worked either ;) Can anyone solve this mathematical conundrum? I'll add the source code here for those smart enough not to need to see it in action! Graphics3D 1024,768,32,1 Const FPS=60 SetBuffer BackBuffer() HidePointer tex=LoadTexture("Textures/lights.png",1) TextureBlend tex,3 geom_Body=LoadMesh("models/testbase.3ds") EntityTexture geom_Body,tex,0,0 EntityColor geom_Body,150,160,188 cam=CreateCamera(geom_body) PositionEntity cam,0,150,-150 ; Position camera above and behind tank CameraZoom cam,8 PointEntity cam,geom_Body light=CreateLight() LightColor light,255,255,255 period=1000/FPS time=MilliSecs()-period u_position#=0 v_position#=0 While Not KeyHit(1) Repeat elapsed=MilliSecs()-time Until elapsed q=0 ticks=elapsed/period tween#=Float(elapsed Mod period)/Float(period) For k=1 To ticks time=time+period If k=ticks Then CaptureWorld EndIf ; Move tank If KeyDown(200) ; Press UP cursorkey v_position#=v_position#-0.01 Else If KeyDown(208) ; Press DOWN cursorkey v_position#=v_position#+0.01 EndIf ; Turn tank If KeyDown(203) ; Press LEFT cursorkey TurnEntity geom_Body,0,2.0,0 u_position#=u_position#-0.01 angle#=angle#+2 Else If KeyDown(205) ; Press RIGHT cursorkey TurnEntity geom_Body,0,-2.0,0 u_position#=u_position#+0.01 angle#=angle#-2 EndIf TransTex(tex,angle#,u_position#,v_position#) UpdateWorld Next ;...every frame RenderWorld tween Text 16,16, v_position# Flip False Wend ;End Function TransTex(texture,angle#,u#,v#) RotateTexture texture,angle# x#=Cos(angle)/2 y#=Sin(angle)/2 v_disp#=v Mod 2.0 u_disp#=u Mod 2.0 ; PositionTexture texture,(x-.5)-y,(y-.5)+x ; PositionTexture texture,(Sin(angle)*v_disp)-(Cos(angle)*u_disp),(Cos(angle)*v_disp)+(Sin(angle)*u_disp) PositionTexture texture,(x-.5)-y-(((Sin(angle)*v_disp)-(Cos(angle)*u_disp))/2),(y-.5)+x+(((Cos(angle)*v_disp)+(Sin(angle)*u_disp))/2) End Function |
| ||
Is this is what you are after? |
| ||
That's wonderful! Absolutely perfect, straight out the box. Many, many thanks! |