TurnEntity (Around Axis)
BlitzMax Forums/MiniB3D Module/TurnEntity (Around Axis)
| ||
Hi, so I tried it myself, searched for it and tried it again, but I cannot figure out how I am able to acheive what I want. The "local" Rotation is a real mess. In my opinion local means to rotate around the axis of an object. But thats not the case. Instead it rotates around the local Z axis, the global Y axis and an weird yaw-dependant X axis. I know, it is like in B3D, i found that out so far, but can someone please help me to implement a _real_ local rotation? I tried so far: (Dirty code, I know) Import sidesign.minib3d Graphics3D(640, 480) Type rotater Field cone:TEntity Field axisX:TEntity Field axisY:TEntity Field axisZ:TEntity Method init() cone:TEntity = CreateCone() axisX:TEntity = CreateCylinder(8, 1, cone) ScaleEntity(axisX, 0.1, 3, 0.1) EntityColor(axisX, 255, 0, 0) RotateEntity(axisX, 0, 0, 90) axisY:TEntity = CreateCylinder(8, 1, cone) ScaleEntity(axisY, 0.1, 3, 0.1) EntityColor(axisY, 0, 255, 0) axisZ:TEntity = CreateCylinder(8, 1, cone) ScaleEntity(axisZ, 0.1, 3, 0.1) EntityColor(axisZ, 0, 0, 255) RotateEntity(axisZ, 90, 0, 0) EndMethod End Type rot1:rotater = New rotater rot1.init() rot1.cone.PositionEntity(5, 0, 0) rot1.cone.EntityColor(255, 255, 255) rot2:rotater = New rotater rot2.init() rot2.cone.PositionEntity(- 5, 0, 0) rot2.cone.EntityColor(150, 150, 150) camera:TEntity = CreateCamera() PositionEntity(camera, 0, 0, - 10) 'Wireframe(True) While Not KeyHit(KEY_ESCAPE) Cls TurnEntityAroundAxis(rot1.cone, KeyDown(KEY_UP) - KeyDown(KEY_DOWN), KeyDown(KEY_LEFT) - KeyDown(KEY_RIGHT), KeyDown(KEY_PAGEUP) - KeyDown(KEY_PAGEDOWN)) TurnEntity(rot2.cone, KeyDown(KEY_UP) - KeyDown(KEY_DOWN), KeyDown(KEY_LEFT) - KeyDown(KEY_RIGHT), KeyDown(KEY_PAGEUP) - KeyDown(KEY_PAGEDOWN)) RenderWorld Flip Wend End Function TurnEntityAroundAxis(pEntity:TEntity, Pitch:Float, Yaw:Float, Roll:Float) Local fPitch:Float = EntityPitch(pEntity) + Pitch * Cos(EntityRoll(pEntity)) Local fYaw:Float = Yaw + EntityYaw(pEntity) + Pitch * Sin(EntityRoll(pEntity)) DebugLog Sin(EntityRoll(pEntity)) Local fRoll:Float = EntityRoll(pEntity) + Roll RotateEntity(pEntity, fPitch, fYaw, fRoll) End Function Since the Z - Axis is the only real local axis, my plan was to rotate the object around the others dependant from EntityRoll but I have to admit I did not get the concept behind the rotation function. Then I looked up the source but hell I don't know no nothing about matrices :( Is here anyone who can give me some advices to solve my problem? greetings FTC |
| ||
I've just made these routines, they use Matrices and Quaternions for rotation. There is an internal function, called MQ_Turn, that rotates an entity around an axis: http://www.blitzmax.com/codearcs/codearcs.php?code=2498 Hopefully they help you. |
| ||
Thats great man! I really needed it. THANKS! greetings |
| ||
Uhm there is a problem still... When using the code with collision the Object's rotation is resetted. EntityYaw2 etc are delivering correct values though and MoveEntity2 local does work as well, but the Mesh itself is stuck in an fixed rotation. I guess there it has something to do with the matrices. greetings |
| ||
do you mean that the collisions are happening to an entity as if it isnt rotated? please provide code sample and model. |
| ||
It is possible that the code is not (fully) compatible with animated meshes? An example would be a good idea, since I only tested the code with standard CreateCube/CreateCone objects. Maybe you could try this version of TEntity. UpdateMat is changed to read the new matrix, and all the original commands refer to their counterparts. That could allready solve some of these issues, since for example TCollisions.bmx uses EntityX/Y/Z. Still, I would have to get further into it to be able to say more about it. Note that the commands are wrapped in an ugly manner at this point. As I said, it's just experimental code so far, and I'm cautious when it comes down to building in anything before it is properly tested and working. TEntity.bmx |
| ||
Blitz3d didnt support animated mesh collision, the collisions happened to the original mesh with no animation. |
| ||
Right, I looked into it and I saw indeed there was a problem with collisions. Now I've posted an update that I have tested with the minib3d samples/demo's. So collisions should be working properly now. |
| ||
I created a sample of my problem: http://www.freetimestudio.de/col_test.zip I do not want it to be animated, but LoadAnimMesh solves a few Renderingproblems Minib3d has. It uses the old version. With the new version however it does not render anything... greetings |
| ||
That's very nice, thanks. I don't have the older version anymore, but I tried the .exe you compiled, and it does indeed work incorrectly. When I tried the latest version, it then works correct, and renders. Try my .exe: http://abcbasic.comyr.com/col_test.zip |
| ||
I don't know whats wrong :( Even with the latest version I have nothing displayed. But the programm does not crash (I use Debuglog to find out that) greetings |
| ||
But the .exe I compiled, does it work? |
| ||
Ah, I know what it is .. My fault, sorry :/ stupid, I forgot to add UpdateEntities(). You can call it manually before using RenderWorld(), but it should be built-in. The reason I forgot that, is that RenderWorld is part of TGlobal. In TGlobal.bmx, in the Function RenderWorld, add the line: UpdateEntities(). Example here: TGlobal.bmx |
| ||
Does it work now? |
| ||
Patience with me please :) I don't have much time to work with Blitz at the moment. Yes it works now and your .exe workd as well :) But, like in Science, a solved Question creates more Questions, I got another thing to solve. Standard EntityPitch() gives me values from -"infinite" to +"infinite" and yours provide -90 to 90. Is it possible to get at least values from 0 to 360? ( or to infinite;-) ) That would make it much easier to handle the rotation. greetings, and great work! |
| ||
Thank you. I'm afraid that's not possible, because EntityPitch/Yaw/Roll extract their values from the matrix. That means the pitch is affected by the roll and yaw. I got those routines from the math library that is posted in the b3d thread. However, depending on what you are trying to do, you can work around that limitation by keeping track of this pitch yourself, for instance like this: |
| ||
Thanks for this suggestion. I tried it, but it revealed something bad :( With the original minib3d i have ~60 fps but with the modified one i have a maximum of 25 fps. Same Code, I just used different minib3d versions to compile it. actualRot:float = actualRot + (curRot:float - actualRot) * 0.1 Cube.RotateEntity(actualRot, 0, 0) The code itself works, just the thing with the lower frame rate. greetings |
| ||
!? That is a big difference indeed. The reason might be that my RotateEntity is slower. I tried to optimise the code for TEntity. You might give that a try. I replaced the my 'Rotate' with the original Rotate code: |
| ||
Whatever you did, that was the solution. I have stable 60 fps now. Still, when going up with the "rate" parameter of Graphics3D I am able to get about 250 fps with the original and 65 with yours. Of course there is more than one object and a scene and everything, but still, I think thats quite a difference. I don't have problems with the fps, it fits for me, but maybe, when using more objects it could become a problem. greetings :) |
| ||
Could you send an example? Then I could have a look later on this week. (At work tomorrow..) I believe there shouldn't be such a big difference between the two. |
| ||
I think quaternion rotations are always going to be slightly slower than euler ones as there is simply more calculations involved. |
| ||
I would have to make an example, because it is a big programm I am using the rotation in. I can't just cut out a little sample ;) But I am not at home for a couple of days. After that I will make a sample. If simonh is right, the definition of "slightly" has to be redone :D greetings |
| ||
I am back. here is my sample: SuperStrict Import sidesign.minib3d 'standard minib3d ~120 fps 'modded minib3d ~37 fps Type TTurningThingy Field HoldPivot:TEntity = CreateSphere() Field RotPivot:TEntity = CreateSphere(8, HoldPivot) Field ChildObjects:TList = CreateList() Function init:TTurningThingy(Pos:TVector, count:Int = 4, dist:Float = 10) Local tmp:TTurningThingy = New TTurningThingy For Local i:Int = 1 To count Local alpha:Float = ((360.0 / count)) * i Local y:Float = Sin(alpha) * dist Local z:Float = Cos(alpha) * dist Local ChildObject:TEntity = CreateSphere(8, tmp.RotPivot) ChildObject.EntityColor(Rnd(10, 255), Rnd(10, 255), Rnd(10, 255)) ChildObject.ScaleEntity(1, 2, 1) ChildObject.PositionEntity(0, y, z) ChildObject.RotateEntity(rnd(0,360),rnd(0,360),rnd(0,360)) tmp.ChildObjects.AddLast(ChildObject) Local someSprite:TSprite = CreateSprite(ChildObject) someSprite.PositionEntity(0, 5, 0) tmp.HoldPivot.PositionEntity(Pos.x, Pos.y, Pos.z) Next Return tmp End Function Method update() For Local tmp:TEntity = EachIn ChildObjects tmp.TurnEntity(0, 1, 1) Next RotPivot.TurnEntity(1, 0, 0) HoldPivot.TurnEntity(0, 1, 0) End Method End Type Graphics3D(640, 480, 32, 2, 1000) Local camera:TCamera = CreateCamera() camera.PositionEntity(0, 0, - 20) Local TurningList:TList = CreateList() For Local i:Int = 0 To 40 TurningList.AddLast(TTurningThingy.init(TVector.Create(Rnd(- 50, 50), Rnd(- 50, 50), Rnd(0, 100)))) Next Local old_ms:Int = MilliSecs() Local renders:Int Local fps:Int While Not KeyHit(KEY_ESCAPE) Cls For Local tmp:TTurningThingy = EachIn TurningList tmp.update() Next UpdateWorld() RenderWorld() Flip() renders = renders + 1 If MilliSecs() - old_ms >= 1000 old_ms = MilliSecs() fps = renders DebugLog fps + " FPS" renders=0 EndIf Wend ClearWorld() End I know, a little bit stupid maybe, but it is an abstraction of what I am doing. In my real code I use Models and Textures, thats why I increased the polys of the sample. I guess that it has much to do with the sprites, removing them does make the modded minib3d much faster while with simonh's version does not produce such a difference. |
| ||
Thank you, your example is quite helpful. I tried optimizing the code. It would need testing to see if everything still works properly, but maybe it runs faster? On my laptop, the original version runs at 7-8 fps, and the previous modded version 6-7 fps. With this adjustment, both run on 7-8 fps. TEntity.bmx |
| ||
it says 'interpolate matrix not found' |
| ||
This is just TEntity.bmx. It also requires TMatrix/TGlobal/TAnimation from the archive entry to work. "InterpolateMatrix" is part of TMatrix.bmx. |
| ||
Hm there is a speed-increase. But not a big one. I get ~ 44 fps. But there are no errors an everything seems to work just as well as before. greetings |
| ||
Right, well back to the drawing board.. I'll look further into it. |
| ||
I need this too, but I don't know where to get the TMatrix class code. I feel like I'm missing something?? |
| ||
It's in the archive: http://www.blitzmax.com/codearcs/codearcs.php?code=2498 |
| ||
Thanks! |