Forum Replies Created
-
AuthorPosts
-
There are basically 2 problems here.
Base Entity class defaults to hidden so ‘nonentity’ (and all it’s children) are hidden. I will probably add a ‘Pivot’ style subclass shows itself, but in the meantime if you’re using an entity as a pivot you’ll need to manually set entity.Visible=True. It’s useful right now for entities to default to hidden for various reasons.
Also, mojo3d isn’t really thinking about what an entities matrix should be after changing it’s parent. I’ll probably change this so if you set an entities parent to null, it retains it’s world matrix and if you set it to non-null it retains its local matrix – make sense?
With this is mind, this works for me in v1.1.09:
Monkey123456If Keyboard.KeyHit (Key.Space)Local matrix:=child.Matrixchild.Parent=Nullchild.Matrix=matrixEndifThis stuff should be fixed soon.
Here’s a little demo of centering a view within another view – in this case, a GridView within a window.
The key here is set the view want to be centered’s layout to “float” and its gravity to .5,.5. This causes the view to ‘float’ in the center of it’s frame. Ditto you can uses different gravity values to float at top left, bottom right, bottom center etc.
(Note: I found a little bug in GridView while doing this that causes overlap between child gadgets in a gridview – fixed in develop branch).
Monkey123456789101112131415161718192021222324252627282930313233343536#Import "<std>"#Import "<mojo>"#Import "<mojox>"Using std..Using mojo..Using mojox..Class MyWindow Extends WindowMethod New()Super.New( "Simple Mojo Gui App",640,480,WindowFlags.Resizable )local gridView:=New GridView( 1,3 )gridView.AddView( New Label( "Sprite" ),0,0 )gridView.AddView( New Label( "Text" ),0,1 )gridView.AddView( New Button( "Button" ),0,2 )gridView.Layout="float"gridView.Gravity=New Vec2f( .5,.5 )ContentView=gridViewEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()End‘Var’ parameters aren’t in yet but are likely to be added very soon.
Yes, these will be added soon, working on lighting/transparency right now.
There’s usually some people here:
https://discordapp.com/channels/388657095656079380/388710778808565761
Are you afraid of iterators?
A little bit maybe! Can never quite remember the syntax…
(I’d tried switching the above code to a list.)
Strange, you should be able to remove-while-you iterate through lists, eg:
Monkey1234567891011121314151617181920212223#Import "<std>"Using std..Function Main()Local list:=New IntListFor Local i:=0 Until 10list.Add( i )NextPrint list.Count() '10?For Local it:=Eachin listlist.Remove( it )NextPrint list.Count() '0?EndThis is really easy to ‘hack’ into lists, but not into stacks. Either way, it offends my sensibilities as a gentleman programmer so I don’t do that any more! But I do get why it’s popular, it’s probably the easiest to grasp even if it is inefficient and error prone.
what would be the best way to handle removing an object mid-iteration
There are several ways to approach this, including:
- Use iterator methods Bump() and Erase() to do it the ‘nice’ way.
- Use a separate ‘kill’ list containing items you want to destroy later. Once you’ve gone through the main ‘live’ list, iterate through the kill list and kill anything there from the live list.
- Use some other far out method, eg:
Monkey12345678910111213Local put:=0For Local get:=0 Until stack.Length'update returns false to remove from stack...'If Not stack[get].Update() Continue'still alive...stack[put]=stack[get]put+=1Nextstack.Resize( put )This effectively does a simultaneous iterate/erase/compact pass. It’s based on the idea of ‘double buffering’ containers, another approach where you build the ‘next’ live list while processing the ‘current’ one, and then swap them afterwards.
And last but not least, the recommend way using iterators:
Monkey12345678910111213141516171819202122232425262728293031323334#Import "<std>"Using std..Function Main()Local list:=New IntListFor Local i:=0 Until 10list.Add( i )NextLocal it:=list.All()While Not it.AtEndIf it.Current & 1 'remove odd integers...it.Erase()Elseit.Bump()EndifWendFor Local i:=Eachin listPrint inextEndThe is no transparency yet apart from sprites.
The problem is to do with removing items from a container while you’re iterating though the same container. It’s a bit like doing this:
Monkey12345678910111213141516171819#Import "<std>"Using std..Function Main()Local stack:=New IntStackFor Local i:=0 Until 10stack.Add( i )NextFor Local i:=0 Until 10Print "Deleting item "+stack[ i ]stack.Erase( i )NextEndThis may or may not things clearer, but the problem here is that after you delete an item, the current item then becomes the next item (ie: all items ‘shift down’) but then the ‘Next’ statement ‘skips over’ that next item so you end up missing every second item! Worse than that, after removing an item, depending on the type of container involved, it may be very hard to even get to the next item as the current item is no longer really valid. For example, with a linked list, after removing an item the ‘next’ and ‘succ’ fields of the link node may (should) not be valid so there’s no way to get to the next item. I ended up fudging around this with lists in monkey2 because the outcry over not being able to remove items while you were iterating through a list from ex-blitz users was just too much to deal with (and because I avoid lists these days anyway). Looks like I fudged stacks too…
The bigger idea here is it’s dangerous to modify a container while you’re iterating through it without being very careful, and the iterator.Erase() approach is one way to do that safely. The compiler can only really do so much to help here without things become very complex/slow as it has to deal with situations like nested eachin loops with the same container (eg: for collision checking) etc. In fact, to do it properly, a container would have to track every iterator to items within the container, which would of course incur significant overhead and be very slow.
It’s just something I don’t do any more, and there are generally lots of alternatives, eg: instead of:
Monkey1234For Local pb:PhysBox = Eachin boxespb.model.Destroy ()boxes.Remove (pb)Next…which wont even work properly due to the ‘skipped items’ issue, you can of course simply go…
Monkey12345For Local pb:PhysBox = Eachin boxespb.model.Destroy ()Nextboxes.Clear()Which works properly and doesn’t involve any potentially slow ‘Remove’ operations.
I also find this useful sometimes (for stacks/deques only):
Monkey12345678While Not stack.Empty'Local item:=stack.Top 'get copy of top itemstack.Pop() 'remove it'item.DestroyItOrWhatever()WendThis also destroys all items in a stack, but it does it in such a way that the stack remains valid at all times so it’s always safe to add items to it at any time in the loop. I use this idea a lot in compilers, as they frequently have to deal with ‘todo’ lists and this is a nice way to process a todo list.
The argument for sizeof should be a value not a type, eg: libc.sizeof( proc ), but that error isn’t exactly helpful, will fix.
You can’t use mx2 arrays in an extern like that, because an mx2 array is NOT the same as a C array.
The easiest way to handle C arrays is to use a Ptr instead of an array (in C, arrays ARE pointers), eg: change ‘int[32]’ to ‘Int Ptr’. You’ll still be able to access it via [] etc, but be aware that the compiler wont be able to sanity check static array sizes.
As per the excellent unicode-for-all doc, I would suggest explicitly using Struct PROCESSENTRY32W, ie: the wide char version where TCHAR is ushort, something like…
Monkey123456789101112131415ExternStruct PROCESSENTRY32WField dwSize:UIntField cntUsage:UInt...Field szExeFile:UShort PtrEndFunction Main()Local proc:PROCESSENTRY32Wproc.dwSize=libs.sizeof(proc)...EndYou don’t need to ‘New’ structs although it doesn’t really hurt.
Collision groups/masks are just the way bullet does it and I may yet change it for mojo3d.
Both mask and group are just (16 bit) bitmasks, and both (entity1->mask & entity2->group) AND (entity2->mask & entity1->group) must be non-0 for entities to collide. I think – I find it really confusing myself too!
Safest thing to do is just make mask and group the same for all entities (non-0 though), and all entities can then collide. They default to 1 anyway.
This stuff is very much in flux right now, but I am working on it this week/right now.
This is because the compiler can’t work out the dependancies involved correctly.
It does a pretty good job of simpler stuff like:
Monkey123Global Z:=X*YGlobal Y:=X*2Global X:=10…but with your example above, TEST is dependant upon Test.List (so Test.List must be inited first) via the Test.Count function (actually, via a function call *within* the Test.Count function), but the compiler isn’t smart enough to work out dependancies via function calls like this – and probably never will be I’m afraid so I’m not quite sure what the solution is! For now you’ll have to work around it…
This had changed some months ago. I think it’s to avoid calling uninitialized fields..
This is unrelated really – it used to be that you could call a method on a null object as long as the method never read/wrote any fields, but no longer. But here, we’re talking about a function, not a method.
You can use Material.TextureMatrix, Material.ScaleTextureMatrix etc to transform texture coordinates in realtime.
See tests/water.monkey2 for ScaleTextureMatrix example.
Going by the FPS in your screenshot, it looks like you have SwapInterval set to 0, in which case cpu usage *should* be very high as there is no syncing going on – the app is just drawing as fast as it can, and frames will be thrown away if you’re drawing them faster than the monitor can display. It’s like a repeat/forever loop with nothing in it – cpu usage in this case will hit 100% for a core too.
It’s only when an app ‘blocks’, ie: goes to sleep waiting for something to happen, that cpu usage goes down. This is what SwapInterval=1 achieves – when buffers are swapped, cpu goes to sleep while waiting for vertical blank. With SwapInterval=0, cpu never goes to sleep, ie: 100% usage.
By using >1 core, the nvidia driver is actually being really clever. It’s using some serious theading in order to draw as much stuff as it can because it assumes this is what you want. It doesn’t know you’re not doing some fancy preprocessing or whatever, so it just renderers as fast as it can.
But the new version should be forcing SwapInterval to 1 by default anyway so something’s up there – maybe you have it ‘forced’ to 0 in nvidia control panel? Make sure the ‘vertical sync’ option in nvidia control panel is set to ‘Use the 3D Application’ setting.
Anyway, think we’ve been chasing different ‘issues’ here a bit! My problem was that even with SwapInterval=1 (ie: 60FPS), all 3d stuff was still taking 100% of 1 core and that at least appears to be fixed so I’m happy anyway.
And bah, I only get 93FPS with cubes and SwapInterval=0, 377FPS is very impressive!
Fixes up now in develop branch!
-
AuthorPosts