Worklog for Sweenie

Worklog 1

Return to Worklogs

OgreRally(Posted 2005-10-12)
Since I done a rally-sim in Tokamak and ODE, I felt I had to do it in Newton as well :o)



http://www.svenberra.net/OgreDemo.zip

--- Controls ---

Arrow-keys to accelerate, reverse and steer.
Space to flip car(hit space several times)
C to toggle skybox
S to toggle shadows
D to toggle drivetype (RWD, FWD & AWD)

As usual the friction-handling sucks and this is because
of me being a lazy coder and not because of Newton.



Ogre is fun(Posted 2005-07-14)
Been playing with Ogre the last days.
It's pretty powerful.

Here are some screenies...





Download Demos (4.5 Mb)
(!!! Exit the demos by pressing Escape, DON'T close the window yourself)
The Bumpmap & Terraindemo requires Shadersupport, though the Terraindemo can be modified to work without shaders(See terrain.cfg)



Ogre, what a beast(Posted 2005-07-06)
While fighting my way through the inner workings of DirectX I managed to gain quite alot of experience to advance a couple of levels.
With strengthen confidence and several potions of coffee I decided to once again tackle the beast that has defeated me so many times before.
This time I defeated the Ogre and tamed it.
(Been playing alot of RPGs lately *grin* )

Anyway, I wanted to try a different wrapping approach this time.
Wrapping an api or something like that is very easy, but what I find most troublesome is all the API-declarations that has to be made to make the wrapped functions available to another language.

Wrapping everything in Ogre3D would take a lifetime(at least for me) and by the time the wrapper is in a somewhat usable state, man would probably have moved to mars.

Currently I have wrapped enough in Ogre to create Entities(Models), Cameras, Lights(with shadows),SceneNodes,terrains, paged terrains, BSP-levels and Overlays(HUDs, text and such).

That took me about 5 hours.
To get it working in Blitz3D, Bmax, Visual Basic 6, VB.Net or any other language that supports API-declarations I only need to declare 7 API-functions.

DoCommand(Function$)
SetIntParam(Index,Value)
SetFloatParam(Index,Value)
SetPtrParam(Index,Value)
GetIntParam(Index)
GetFloatParam(Index)
GetPtrParam(Index)

The application and the DLL shares a buffer of parameters.
Before the application tell the DLL to execute a function, the application fills in the necessary parameters in the buffer.
The DLL executes the function and return the results(if any) in the buffer.

This method introduces some overhead, but i've done some tests and the speed difference isn't that much and the ease of wrapping makes it worth it.

Some sample code...
SetIntParam(0,ST_INTERIOR)
SetIntParam(1,True)
SetPtrParam(0,Null)
Command("Ogre_Init")

'This will Initialize Ogre.
'The first parameter tells it to use the BSP SceneManager
'The second parameter tells it to show the Configuration Dialog at startup
'The third parameter is a pointer to a window handle.
'If you supply a handle, Ogre will render into that window instead of creating it's own window.



To simplify the above, you can make a function like this.

Function Ogre_Init(SceneType,ShowDialog,ExtWin:Byte Ptr)
 SetIntParam(0,SceneType)
 SetIntParam(1,ShowDialog)
 SetPtrParam(0,ExtWin)
 Command("Ogre_Init")
End Function


Well, I'm gonna get back to work now...



DirectX 9 Renderer(Posted 2005-06-15)
I finally managed to get skinned meshes working.



Demo -> http://www.svenberra.net/skinmeshtest.zip



DirectX 9 Renderer(Posted 2005-06-13)
It now handles loading of x files.
Psionic's dwarf has been equipped with a sword using 3 different materials which are attached to the left hand as a child.


If you load 50 copies of the dwarf, the same texture will be used but there will be 50 unique meshes.
But if you clone the model the cloned models will share the same mesh.

Like this...
Local Dwarf:ModelEntity = ModelEntity.Load("Dwarf.x")

Local DwarfClone:ModelEntity = ModelEntity.Clone(Dwarf)



Next step is to support animations and skinmeshes.



DirectX 9 Renderer(Posted 2005-06-09)
Been struggling with a texturemanager which will keep track of all used(and unused) textures.
Everything will be handled by managers eventually.

Here is a demo of it in action...(very simple demo)

http://www.svenberra.net/DxTest.zip



Shader is in...(Posted 2005-05-02)
Doesn't look like much and needs more work to be easy to use, but at least it's working...

(Lighting is done by a shader)



DirectX 9 Renderer(Posted 2005-05-02)
Since gman has done such an excellent work with his wrapper of Irrlicht I decided to drop my wrapper.

While waiting for his wrapper I have fiddled with a rendering-engine of my own using DirectX 9 only(Sorry, Mac & Linux owners)

So far it has worked out pretty well.
The engine currently supports...

* Vertex & Indexbuffers (Using a meshbuilder to simplify the creation of meshes)
* Texturesupport (wow!)
* Materialsupport
* Textrendering(using any windowsfont)
* Sprite/2D-rendering support with alpha-blending.
* Parent-Child hierarchy of rendered meshes using a Matrixstack.

To be done(shortly)...
* Lights
* Shaders(probably HLSL)

To be done(later on)...
* Not decided yet. :)

Screenshot:


Sample sourcecode:
Strict
Import "dxengine.lib"
Include "DxInclude.bmx"

Graphics 640,480,0
Local Hwnd:Int = GetActiveWindow()

InitEngine(Hwnd,640,480,0,False,True,True) 'Fullscreen(False), Vertical Sync(True), Hardware(True)

Local Cube:BaseMesh = MeshBuilder.CreateCube(1.0,1.0,1.0,1,1) 

Local BmaxLogo = LoadTexture("B-max.png")
Local WoodTex = LoadTexture("wood.jpg")

Local Sprite = CreateSprite()
Local AlphaEnabled = True

Local Font = CreateTextFont(24,"Arial")

SetupCamera(-1,-1,-5,-1,-1,1)

While Not KeyDown(KEY_ESCAPE)

 If KeyHit(KEY_A) Then AlphaEnabled = Not AlphaEnabled

 Clear(0,0,200)
 BeginScene()

  Cube.TurnLocal(0.01,0.01,0.01)
  SetTexture(0,WoodTex)
  Cube.Render()

  SpriteBegin(Sprite,AlphaEnabled)
   SpriteDraw(Sprite,BmaxLogo,0,0,0,0,MouseX()-225,MouseY()-225,$FFFFFFFF)
  SpriteEnd(Sprite)

  RenderText(Font,"Press 'A' to toggle Sprite Alphablending",5,5,1.0,1.0,1.0,1.0)

 EndScene()

 FlushMem()
Wend

ShutdownEngine()





Tokamak(Posted 2004-01-23)
Don't you just hate when you make a typo somewhere and you can't see it.
I was working on the jointlimits last night and couldn't get them to work.
Even set them up like in one of the Tokamakdemos and they still wouldn't work.
I checked the wrappersource carefully to spot any mistakes but everything was correct.

I was about to give up when I remebered the DECLS file.
It turned out that I had swapped the function declarations and after a quick correction everything worked as it should.

So when something doesn't work and your about to give up,
doublecheck, character by character.



Tokamak(Posted 2004-01-21)
Currently I'm changing the function names so that it groups them more to it's own class.
like, TOKSIM_, TOKRB_, TOKAB_, TOKJOINT_ and TOKGEOM_

So a simple setyp will look like this...

TOKSIM_CreateSimulator(1,0,0,-10,0)

; The Body
Rbody1 = TOKRB_Create()
TOKRB_AddBox(Rbody1,2.0,2.0,2.0)
TOKRB_SetMass(Rbody1,3.0)
TOKRB_SetBoxInertiaTensor(Rbody1,2.0,2.0,2.0,3.0)
TOKRB_SetPosition(RBody1,0.0,5.0,0.0)

;The Joint

Joint1 = TOKJOINT_Create(1,Rbody1,0)

;The first parameter takes the connection type which is one of...
; 1 = RigidBody To World
; 2 = RigidBody To RigidBody
; 3 = RigidBody To AnimatedBody
;The third parameter takes a RigidBody or AnimatedBody
; Leave it at 0 if the first connectiontype is used.

[Edit]
Oops! Forgot the jointtype. :-)

TOKJOINT_SetType(Joint1,1)
;The second parameter takes the jointtype
;which can be one of...
;1 = Ball&Socket
;2 = Ball&Socket2(Don't know if working)
;3 = Hinge
;4 = Slide(Don't know if working either)

TOKJOINT_SetPositionWorld(Joint1,1.0,1.0,1.0)
;Note that it called SetPositionWorld now instead of
;SetPositionGlobal

TOKJOINT_Enable(True)
; You can now enable or disable the joint, it's disabled by default.


Things left to do:

* Position and orientation of Geometry(about the bodies)
* Breakage (which makes geometry break loose from the body on impact and become it's own body)
* Collisionresponse & Collisioninfo
* Collision with arbitrary mesh.(MemoryLeaks has been spotted but the Tokamakguys are on it)
* Jointlimits
* Materialdefinition and assigning materials to geometry(which handles friction and restitution)
* Particles



Tokamak wrapper (part 2)(Posted 2004-01-14)
Gaahhh!, I wrote the whole worklog a couple of minutes ago but forgot to set the title so I lost everything I wrote.

Ok, second attempt.

--------------------

The joints should have been done by now, but unfortunately they aren't.
I was hoping to have some qualitytime with Blitz and Tokamak during my christmas vacation but it didn't turn out that way.

I also had some problems with the GetPitch, Yaw and Roll functions. I couldn't get the Quaternion to Euler conversion working correctly. Sudden spins and jerks could appear.
However, I got another conversionfunction from Josh Klint and with some slight modifications it's finally working.
Thanks Josh!.

Now the joints.

There are two types of joints in Tokamak.
Balljoints and Hingejoints.

To simulate a balljoint with your hands, put two fingertips together and keep the fingers straight. Now rotate them but never let the fingertips disconnect.
That should give you an idea how balljoints work.

The hingejoint works just like a hinge.

But you could also create a hinge by using two balljoints.
Again use your fingertips, but this time use two fingers from each hand.

You can even create a rotor/wheel joint with two balljoints.
Take an object that has the shape of a wheel or something.
Put a fingertip on each side of the object in the center and now the object is constrained to only rotate around the axis that the fingers lies on.
Though I haven't tested this yet, It should work.
I've successfully tried it in other physicsengines.

The next time I should have implemented the joints.



Tokamak wrapper(Posted 2003-12-10)
Most of the functions for creating rigid & animated bodies are finished.
By the way,
In Tokamak Rigid Bodies are the bodies that move around, affected either by gravital forces or external forces caused by collision or the user.
Animated bodies are static bodies that can only be positioned and rotated by the user.

I have thought of different ways to handle the objects in Blitz, but have decided to let the users handle this themselves.
When calling the function that creates the RB, it simply returns a handle/pointer to the RB.
When you want to retrieve info from the RB, just pass this handle to the function of your choice.

For every collision between two bodies a callback is made with collisioninfo such as...
* Pointers to the two bodies that collided
* Point of collision, both local and world coordinates
* Which geometries that was involved(bodies are made up of one or several primitives called Geometry)
* CollisionNormal
* Velocity
* MaterialIndex of geometry involved

These values will be put in a list that can be traversed to get the collisionstates.
That is, after an update( done using a function called Advance ), these values will be available. Before Tokamak updates again, this list will be cleared.

Setting up a simple simulation of one Rigid Body and one Animated Body could look like this.

CreateSimulator(1,1,0.0,-9.8,0.0)
;Parameters are:
;Nr of RB's, Nr of AB's, Gravity X,Y & Z

RB = CreateRigidBody()
AddRBGeomBox(RB,2.0,2.0,2.0,1.0)
;RB, Width, Height, Depth, Mass

SetRBPosition(RB,0.0,10.0,0.0)
Cube = CreateCube()

AB = CreateAnimatedBody()
AddABGeomBox(AB,10.0,2.0,10.0)
;AB, Width, Height, Depth
SetABPosition(AB,0.0,-5.0,0.0)
Floor = CreateCube()
ScaleEntity Floor,5,1,5
PositionEntity Floor,0,-5,0

While Not KeyHit(1)

CurrentTime = MilliSecs()
Elapsed# = (CurrentTime-LastTime)/1000.0
LastTime = CurrentTime

Advance(Elapsed#)
;Elapsed time in seconds

PositionEntity Cube,GetRBX#(RB),GetRBY#(RB),GetRBZ#(RB)
RotateEntity Cube,GetRBPitch#(RB),GetRBYaw#(RB),GetRBRoll#(RB)

RenderWorld
Flip False

Wend
DestroySimulator()
;Notice that I don't need much code to clean up after myself.
;Just a single call to DestroySimulator and Tokamak will take care of this. :)


One thing that can feel a little bothersome is the fact
that the simulator needs to know how many bodies that will exist before it's created.
But remember that this is the maximum nr of bodies you define.
If you know that there will only be a maximum of 5 rigid bodies then you just set this value to 5.
If you know that there will be a nr of 1 to 300 bodies, then you set the value to 300.
Settings this value higher than it needs to be will only waste your memory.
You can't change this value while the simulator is running.
If you want to do this, you'll have to destroy the simulator and recreate and reposition all the bodies again.

When destroying(freeing) the simulator, all bodies and joints created will automatically be destroyed by Tokamak.
Likewise if you destroy a rigidbody, every object created by this body will be destroyed.

You can also use Tokamak to handle particles. Nice :)

Next time I will report the progress of the joints.