Rotating textures around texture centre

Blitz3D Forums/Blitz3D Programming/Rotating textures around texture centre

Shifty Geezer(Posted 2005) [#1]
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.


semar(Posted 2005) [#2]
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,-255
Just 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.


Shifty Geezer(Posted 2005) [#3]
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!


Beaker(Posted 2005) [#4]
The code archive is your friend:
http://www.blitzbasic.com/codearcs/codearcs.php?code=420


Shifty Geezer(Posted 2005) [#5]
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



DJWoodgate(Posted 2005) [#6]
Is this is what you are after?




Shifty Geezer(Posted 2005) [#7]
That's wonderful! Absolutely perfect, straight out the box. Many, many thanks!