largo_winch
31-05-2011, 09:45
hello petr.
last weekend I saw "tron legacy". I notice at the beginning the tron movie making the "grid". brigth lines and grid patterns created a city (virtual). What could be a good way to translate this effect to "tbgl"? How could be a good start? Perhaps you have any idea. thanks in advance.
bye, largo
ErosOlmi
31-05-2011, 10:09
I'm not a great expert of TBGL (my brain get lost into 3D worlds ) but have you seen examples in \thinBasic\SampleScripts\TBGL\Basic\ directory?
In particular, just for starting, please have a look at "TBGL_Demo07_DisplayList.tBasic" and "TBGL_Demo09_SpecialFX_Fog.tBasic".
Ciao
Eros
Petr Schreiber
31-05-2011, 10:52
Hi!,
Tron Legacy is visually really fine tuned, I saw it recently as well and liked the style.
Just to sync us - by beginning, do you mean the part 0:30 to 0:58 here?:
http://www.youtube.com/watch?v=-rnmQR18esc
Petr
largo_winch
31-05-2011, 17:52
hell petr, yes: I am meaning scenes from 0:30 to (circa) 1:02 minutes.
Just to sync us - by beginning, do you mean the part 0:30 to 0:58 here?:
thanks eros for link, yes, some of the tbgl example I know and old ones from bonus pack, but unfortunately they are all without "entity" character. in my opinion it would helpful to have a new powerful game with all new features of "tbgl" is capable of making.
to run a simple random line (vertex polygon) from left to right doesn't make it really better (will not fulfill the task to rebuild such great movie intro!) I can imagine. that's hard stuff of tron legacy film, I love it!
bye, largo
Petr Schreiber
31-05-2011, 18:01
Thanks for the confirmation,
I have an idea how to achieve it with help of entity system and actor + animator templates. I need to do some code tests first, but stay tuned, I will post the approach here.
Petr
largo_winch
31-05-2011, 18:08
short reply before I log out: could be good to start this project as common synergy work?
I don't like predefined solutions. ;) thanks a lot, bye, largo
Petr Schreiber
31-05-2011, 18:34
Sure,
why not! I will be happy to co work with you and others, there are never enough code examples. If we can produce few reusable code units (tBasicU), it will be even better.
So here are my ideas from which I would start before writing first line of code:
Real time or off line?
The first question would be if I want to code something usable in real time, or if I want to generate high precision, yet computionally expensive "offline" version, usable as generator of discrete frames, which can be joined to video later.
I presume the real time version will be more straightforward and it won't imply any dependancy on external video editing software and such.
The scene
The whole scene can be seen as two components:
digital outlines
"real" world
By the digital outline I mean the cool lines which fly by the contours of the objects. The "real" world is the night city. I don't think any of us owns a helicopter, so the night city will be CG as well.
There is important link between the camera and the outlines - they are somehow in sync.
Modeling the outlines
I see it as advantageous to see the outline effect as collection of individual single "running lines". Each running line can be stored as continuous set of triplets [x, y, z], maybe additionally personalised by color, glow color, frequency of color pulse and finally the head color (head of the line seems brighter). I would see it advantageous to build the running line from actor_object template.
When you create new code unit based on this template, you can see it pregenerates empty TYPE definition, to describe "object" properties, custom Create and Destroy methods, which allow to instantiate the object + Render method, which takes care of rendering, which can take completely custom form and shape.
Each RunningLine would have few methods ("smart" functions), to be able to:
add/remove curved line point
specify the properties such as color
control the line "flow"
One interesting thing - if we want the TYPE to hold array of points the running line goes through, we have (at least) 2 options:
store the way points in hard dimensioned array to hold the information, and pray we will not need more points than array has
store the way points in dynamic array
The second approach is clearly more flexible, but problem is, that TYPEs do not support dynamic arrays. But there are workarounds around this:
define dynamic string as member of UDT (ThinBASIC unique feature) and use it as memory buffer, manipulated via logical variable approach (= overlay virtual array over it)
dynamically allocate memory buffer in own control, store the pointer to it in the UDT, and then again overlay virtual/logical array over it
All the lines could be animated alone, or, for educational effect, by another entity based on animator_object template. This is very similar to actor one, but it allows to add and remove "slave" entities to the animator based entity.
That means - you can first define and create multiple "instances" of RunningLine object (from actor template) and then create single instance of RunningLineAnimator (from animator template), add the references to RunningLine to it, and animate it from there.
Modeling the real scene
The real scene can be pre modeled using any 3D modeler supporting OBJ file format, TBGL has tools to convert it to M15 later.
That is rough draft of how I would do it, let me know what do you think about it.
Petr
largo_winch
01-06-2011, 17:15
hi petr, all others. thanks for brainstorming and I can agree / follow your explanations except "digital outlines" (don't understand clear what's your meaning).
I have done a little example with an *.m15 ojbect (very simple). perhaps it's better to create "tronlines" with tbgl_line and sphere addended?
I've studied your boid example and have made such thoughts around this tron example. but I haven't checked all features of boid examples I see what powerful structure this have ;)
here we are: see my first "tronlines" example. make critics. perhaps it's just a good beginning or if false all work was in vain! (not serious)
you will create fully "city-build" as object? (hugh!) can't imagine how you will build this one except to use bitmaps as backgrounds?
camera movements will be exciting task, I am sure, but that's for next time to think about it for me.
realtime scenes are ok.
Each RunningLine would have few methods ("smart" functions), to be able to:
add/remove curved line point
specify the properties such as color
control the line "flow"
that's good and ok too! I like your script paper! :)
more to come next day.
all my project in zip file (there are three files with two models). I am waiting for feedback!
bye, largo
Petr Schreiber
01-06-2011, 17:48
Hi!,
by digital outlines, I meant that thing which you call "tronline". I checked your code, looks good to me, but there is one thing potentially dangerous - you for example repeatedly load model in RenderMyImage function.
I think loading of resources should be done once - in tronlines_Create. The Create method is ideal for initial setup and loading.
Creating line using model might be possible, but then we will not have freedom of defining the shape of the line from program. I would vote for dynamically created geometry here. For the same reason, I would probably avoid display lists - they are fantastic for static geometry, but if we want the lines "live", they need to be generated on the fly.
Output of your program looks nice, more than the intro like the "game board" of the motorcycles tournament later in the movie.
From my side, I created little concept in parallel, which allows to define the line first, and then you can decide how big part will be visible.
Check it out in the attached code. You can see that the RunningLine has all the code it needs in one unit - in Create function it has initialization and in Render function it has render code.
You can use left/right arrow to rotate view, and PageUp/PageDown to make the line grow.
If you imagine the cube replaced with nice building model, and the RunningLine fine tuned visually, it is something close to the effect we saw in the Tron intro.
Petr
P.S. Thanks to your code, I discovered bug in TBGL, which does not allow using dynamically allocated display lists (tbgl_NewListSpace) with models. I already fixed the problem and it will be present in next release of ThinBASIC.
In the meantime, you can download updated version here: The latest TBGL module (http://www.thinbasic.com/community/showthread.php?10909-The-latest-TBGL-version)
Petr Schreiber
01-06-2011, 19:17
To explain better how to use actor template, I will demonstrate it on example of grid. In example in sample scripts, the grid is usually represented in hard coded way ~like this:
local i, j as long
TBGL_BeginPoly %GL_LINES ' Starts polygon definition based on 2 vertex lines
TBGL_Color 0,255,0 ' Defines color
For i = -10 To 10
For j = -10 To 10
TBGL_Vertex -10, 0, j ' Adds vertex
TBGL_Vertex 10, 0, j ' Adds vertex
TBGL_Vertex i, 0, -10 ' Adds vertex
TBGL_Vertex i, 0, 10 ' Adds vertex
Next
Next
TBGL_EndPoly
It works OK for the purpose of the example, but it has one big problem:
to customize it, you have to hardcode limits to the code directly
That means - such a code is hard to re-use in other projects.
So what shall we do? Create better version of it. It can be based on actor_object template from ThinAIR.
When you create new file based on this template, you see this:
'
' Custom <object> actor entity
' , 06-01-2011
'
' -----
Type <object>
End Type
'[!] Constructor and destructor
Function <object>_Create( sScene As Long ) As Long
Dim eEntity As Long = TBGL_EntityGetFreeID(sScene)
Dim data As <object>
TBGL_EntityCreateFuncSlot(sScene, eEntity, 0, "<object>_Render")
TBGL_EntitySetUserData(sScene, eEntity, data)
Return eEntity
End Function
Function <object>_Destroy(sScene As Long, eEntity As Long)
' -- Destructor is not that needed as TBGL has garbage collection...
TBGL_EntityDestroy(sScene, eEntity)
End Function
'[!] Rendering
Function <object>_Render()
Dim element As TBGL_tEntityIdentifier At TBGL_CallingEntity
Dim data As <object> At TBGL_EntityGetUserDataPointer(element.scene, element.entity)
End Function
'[!] Methods
Function <object>_Method(sScene As Long, eEntity As Long)
Dim data As <object> At TBGL_EntityGetUserDataPointer(sScene, eEntity)
End Function
It is some kind of code skeleton. The first step you will do is to "personalize" this skeleton to get code base for parametrizable grid usable in entity system.
To do so, you can safely press CTRL+R and replace "<object>" with "ParametrizableGrid". You will get this:
'
' Custom ParametrizableGrid actor entity
' , 06-01-2011
'
' -----
Type ParametrizableGrid
End Type
'[!] Constructor and destructor
Function ParametrizableGrid_Create( sScene As Long ) As Long
Dim eEntity As Long = TBGL_EntityGetFreeID(sScene)
Dim data As ParametrizableGrid
TBGL_EntityCreateFuncSlot(sScene, eEntity, 0, "ParametrizableGrid_Render")
TBGL_EntitySetUserData(sScene, eEntity, data)
Return eEntity
End Function
Function ParametrizableGrid_Destroy(sScene As Long, eEntity As Long)
' -- Destructor is not that needed as TBGL has garbage collection...
TBGL_EntityDestroy(sScene, eEntity)
End Function
'[!] Rendering
Function ParametrizableGrid_Render()
Dim element As TBGL_tEntityIdentifier At TBGL_CallingEntity
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(element.scene, element.entity)
End Function
'[!] Methods
Function ParametrizableGrid_Method(sScene As Long, eEntity As Long)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
End Function
The first thing we need to do is to think, what properties will ParametrizableGrid allow to setup. Let's say we need these:
width of the grid
height of the grid
step of the lines
color of the lines representing grid
width of the lines representing grid
optional immunity to light in scene (to preserve contrast look)
These properties should be filled in to the newly "born" ParametrizableGrid TYPE:
Type ParametrizableGrid
width As Single ' [m]
height As Single ' [m]
stepping As Single ' [m]
lineColorR As Byte
lineColorG As Byte
lineColorB As Byte
lineWidth As Long ' [pixels]
immuneToLight As Long ' [T/F]
End Type
That should do it for the start. Now - we should initialize these values to defaults. This should be done in the constructor, which is in this case the ParametrizableGrid_Create function. After filling it in, it becomes:
Function ParametrizableGrid_Create( sScene As Long ) As Long
Dim eEntity As Long = TBGL_EntityGetFreeID(sScene)
Dim data As ParametrizableGrid
data.width = 10
data.height = 10
data.lineColorR = 255
data.lineColorG = 255
data.lineColorB = 255
data.lineWidth = 1
TBGL_EntityCreateFuncSlot(sScene, eEntity, 0, "ParametrizableGrid_Render")
TBGL_EntitySetUserData(sScene, eEntity, data)
Return eEntity
End Function
Let's stop for a while here - what does the Create function does besides property initialization?
It creates new entityID, which is unique and not previously used
Dim eEntity As Long = TBGL_EntityGetFreeID(sScene)
It tells TBGL we will render the entity in our own way, and that the rendering will occur in ParametrizableGrid_Render function:
TBGL_EntityCreateFuncSlot(sScene, eEntity, 0, "ParametrizableGrid_Render")
It binds our custom data (properties) to the entity:
TBGL_EntitySetUserData(sScene, eEntity, data)
It returns the newly created entityID, so we can store it somewhere later to reference exactly this entity:
Return eEntity
The rendering routine is pregenerated for you, and it can immediately access the entity specific data (properties):
'[!] Rendering
Function ParametrizableGrid_Render()
Dim element As TBGL_tEntityIdentifier At TBGL_CallingEntity
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(element.scene, element.entity)
End Function
To make it draw our grid, we can fill the classic TBGL code in:
Function ParametrizableGrid_Render()
Dim element As TBGL_tEntityIdentifier At TBGL_CallingEntity
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(element.scene, element.entity)
Dim i As Single
If data.immuneToLight = TRUE Then
TBGL_PushStateProtect %TBGL_LIGHTING
End If
' -- Give it color we like
TBGL_Color data.lineColorR, data.lineColorG, data.lineColorB
' -- Give it width we like
TBGL_LineWidth data.lineWidth
' -- Render the lines
TBGL_BeginPoly %GL_LINES
' -- Horizontal lines
For i = -data.width/2 To data.width/2 Step data.stepping
TBGL_Vertex i, 0, -data.height/2
TBGL_Vertex i, 0, data.height/2
Next
' -- Vertical lines
For i = -data.height/2 To data.height/2 Step data.stepping
TBGL_Vertex -data.width/2, 0, i
TBGL_Vertex data.width/2, 0, i
Next
TBGL_EndPoly
' -- It is polite to return changed states to defaults
TBGL_Color 255, 255, 255
TBGL_LineWidth 1
If data.immuneToLight = TRUE Then
TBGL_PopStateProtect
End If
End Function
So till now, we have created something similar to the original grid. To make it customizable, we add interface to the entity - functions to safely manipulate the contents of properties, which are by default ~invisible to user of our code unit.
These special functions can be seen as analogy to methods in OOP. The template for method is pregenerated for you:
'[!] Methods
Function ParametrizableGrid_Method(sScene As Long, eEntity As Long)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
End Function
To make sure we reference the proper entity, each of the "methods" is started by scene and entity id, which identify the entity precisely, and the first line in method retrieves the custom data for us.
So to make our setup of the grid comfortable, we might add these routines:
'[!] Methods
Function ParametrizableGrid_SetWidthHeight(sScene As Long, eEntity As Long, width As Single, height As Single)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
data.width = width
data.height = height
End Function
Function ParametrizableGrid_SetStepping(sScene As Long, eEntity As Long, stepping As Single)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
data.stepping = stepping
End Function
Function ParametrizableGrid_SetLineColor(sScene As Long, eEntity As Long, R As Byte, G As Byte, B As Byte)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
data.lineColorR = R
data.lineColorG = G
data.lineColorB = B
End Function
Function ParametrizableGrid_SetLineWidth(sScene As Long, eEntity As Long, lineWidth As Single)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
data.lineWidth = lineWidth
End Function
Function ParametrizableGrid_SetLightImmunity(sScene As Long, eEntity As Long, immuneToLight As Long)
Dim data As ParametrizableGrid At TBGL_EntityGetUserDataPointer(sScene, eEntity)
data.immuneToLight = immuneToLight
End Function
With this setup, we can now create multiple copies of grid, each with unique properties, and the grid rendering routine is always called by scene entity engine thanks to the magic line in "constructor". Creating two grids is then as simple as:
%eGridBlue = ParametrizableGrid_Create(%sScene)
ParametrizableGrid_SetWidthHeight(%sScene, %eGridBlue, 10, 5)
ParametrizableGrid_SetStepping(%sScene, %eGridBlue, 0.5)
ParametrizableGrid_SetLineColor(%sScene, %eGridBlue, 0, 128, 255)
ParametrizableGrid_SetLineWidth(%sScene, %eGridBlue, 3)
%eGridGreen = ParametrizableGrid_Create(%sScene)
ParametrizableGrid_SetWidthHeight(%sScene, %eGridBlue, 10, 10)
ParametrizableGrid_SetStepping(%sScene, %eGridBlue, 1.0)
ParametrizableGrid_SetLineColor(%sScene, %eGridBlue, 0, 255, 128)
ParametrizableGrid_SetLineWidth(%sScene, %eGridBlue, 1)
TBGL_EntitySetRot(%sScene, %eGridBlue, 90, 0, 0)
As you can see on the last line, besides the custom functions, you can still cast classic entity system commands on the entity as usual.
It is good idea to save the actor based reusable entities as tBasicU files, as they are nothing more than code units, not executable alone.
I attach again sample code for study and experiments. As you can see on the screenshot, two grids have independent setup and they are immune to light, but they do not disable light for box, which needs it.
Petr
I haven't seen the new movie yet, so the video link to opening was nice to watch. Looking forward to see what you guys come up with.
Patrice Terrier
05-06-2011, 09:27
The "particle lines" project, could be something that could help you out.
See it here:
http://www.jose.it-berater.org/smfforum/index.php?topic=3874.0
...
Petr Schreiber
05-06-2011, 14:11
Hi Patrice,
thanks for the tip, it looks really nice!
Petr