How can I compute which side of my cube is up?
Blitz3D Forums/Blitz3D Programming/How can I compute which side of my cube is up?
| ||
I have been searching around for some examples of surfacecollision, can anyone please hi-light any examples of this code in action so I can work out which side of the cubes is 'up', the cubes when they are loaded each have separate sides as set by the default cube model within Ultimate Unwrap 3D. I'll only be attempting to which side is up once the cubes are static. [EDIT] |
| ||
The side that is pointing up is the one whose normals , when transformed from local space to world space have a y component which is greater than 0 ( prob best to use .5 incase of any inaccuracies ) i.e. tformnormal faceNx, faceNy, faceNz, CUBEmesh, 0 if tformedy() > .5 ;this face is facing upwards endif |
| ||
Thanks Stevie, will try this out this morning, still loving the fact that yesterday I fancied generating a program to bounce some dice around. Stevie, this is the code I've been attempting to use to calculate which side is up, however all seven dice seem to be reporting that faceNy is 'up'. Below is how I am loading the cubes, the cubes have each side individually identified: [EDIT] [EDIT] |
| ||
Using the Normals is nice, of course, but a Caveman like me would rather simply check the Y position of the children (top, bottom, side etc.) and then declare the topmost as the side that faces upward. IF the pivots of the children are not on the sides, but all in the center of the cube then you may use some additional Pivots instead. Maybe not that elegant, but at least it follows the KISS philosophy. :) |
| ||
@ Bp, My example was partially pseudocode, you need to set the faceNx etc.. components yourself. I also assumed you didn't use children to represent the sides of the cube as you didn't make this clear in your original post. I see that you load in children for each side which is a bit overkill if you ask me - in which case jfk's solution would probably be best. Stevie |
| ||
append a entity to each side from a cube (maybe a pivot) create a highpoint over the map (sun) and test the entitydistance from the pivots to the sun is annother way |
| ||
@jFK, I will attempt to find the Y position of the children. I'm not sure where (if indeed there are any) pivots attached to the children, so I may add some additional pivots for each child and then see which has the highest Y position. If I come unstuck attacking from trying to establish which has the highest Y co-ordinate then I will try Panno's suggestion. @Stevie, I appreciate I might be overdoing it somewhat with children for each side, I have not set faceNx componenets before, although if you know of a good example displaying typical code which sets faceNx components I'd appreciate it(;-). Thanks for the help, BP. |
| ||
@ Bp, I don't have time to go into the normals solution but assuming that the children have a local position which is offset against the parent mesh ( i.e. not 0,0,0 ) then you can use something like this ... Function WhichFaceIsUp$( Count ) HighestSide$ = "" BestHeight# = 0 For side = 1 To 6 child = GetChild( mesh_with_children( count ) , side ) If EntityY( child, 1 ) > BestHeight HighestSide = EntityName( child ) BestHeight = EntityY( child, 1 ) EndIf Next Return HighestSide End Function It returns the Name of the side but you can change that to return the child pointer or it's side number and deal with it from there. Stevie |
| ||
@Stevie, thankyou very much, I tried briefly to marry up some pivots to my child sides prior to dinner this evening & was not having much success, I look forward to giving this a whirl when I get back on my Dev PC. @jfk, was just impressing my daughter with my skill at being able to do one side (wow I here you cry) of a rubiks cube, I think I peaked at doing two sides of a cube tops when I was younger - evidence I'd too much more interesting stuff to do, erm like program battleships in Basic on a Spectrum. Had to try your version of blitzcube - quite impressive! |
| ||
Hmm, I have discovered that I am successfully loading children of the mesh at load time and attempting to address the memory location of the child to an array. However, the children of the mesh do not appear to inherit the co-ordinates of the parent mesh when it is positioned at run time, they simply stay at 0.0 which is causing a bit of a headache. I've been inserting various debug to find out why the children do not seem to be inheriting the parent mesh attributes to no avail. I check that the parent has children assocaited with it at load time with: Then I position the entities with: For x=1 To 7 PositionEntity mesh_with_children(x),(-60+(x*30)),-20,DiceStartz RotateEntity mesh_with_children(x),180,0,0 ;will this change dice side up - no Next Then when I check the location of the main die mesh & the associated childrens EntityY parameter what is returned is the main mesh outputs the co-ordinate which was set (-20), I have changed this to +20 now - however the children all reflect 0.0. Is there some command I need to execute to ensure the children are all updated at the same time as the main mesh ? dicetemp = FindChild(cube_mem(dice_x),"back_grp") Text 40,280,"Dice Number: " Text 180+(dice_x*60),280,dice_x Text 40,360+(Counts*44),"dicetemp EntityY = " Text 180+(dice_x*60),360,EntityY(dicetemp) Text 40,422,"top_side(Count) EntityY = " Text 180+(dice_x*60),422,+EntityY( top_side(dice_x)) ;Text 40,444,"bottom_side(Count) EntityY = "+EntityY( bottom_side(dice_x)) ;Text 40,466,"left_side(Count) EntityY = "+EntityY( left_side(dice_x)) ;Text 40,488,"right_side(Count) EntityY = "+EntityY( right_side(dice_x)) ;Text 40,512,"back_side(Count) EntityY = "+EntityY( back_side(dice_x)) ;Text 40,534,"front_side(Count) EntityY = "+EntityY( front_side(dice_x)) Text 40,310,"mesh_with_children(Count) EntityY = " Text 180+(dice_x*60),334,EntityY(mesh_with_children(dice_x)) Flip WaitKey Next |
| ||
So seeing as my mesh's children are misbehaving can someone please show me an example of code that will allow me to append 6 entities to each cube in question, then all I should hopefully have to do is check which entity is the highest. Unless someone can tell me why my children are misbehaving. I'm beginning to suspect I may have needed to do something else within UU3D to make the children attach to the main cube - or maybe some command in Blitz3D after I've found the children. Or when a PositionEntity is called is it necessary to position the child meshes, I wouldn't have thought so.... useful threads: http://www.blitzbasic.com/Community/posts.php?topic=83868#946841 beginning to wonder If I am experiencing the same issue as LunC within the following thread: http://www.blitzbasic.com/Community/posts.php?topic=76352 Which may explain why I keep getting 0.0 for my childs - if they are all centred on the middle of the parent entity. How can I confirm all the children are slap bang in the middle of the parent as I suspect? |
| ||
Have been working with the loop index code to determine which face is up & I may've had an epiphany (;-) I think my logic which has resulted in the following debug results is sound, however it appears that after getchild is executed on a loaded mesh with respect to EntityY({child- side 3 for example}),1 then the subsequent EntityY on the remaining sides returns 0. I do not know the reason for this, but it causes an inherent problem with me trying to discern the different heights of different children of one cube. I posted a modified version of Stevie's code below the image which displays the cubes sides debug info in the image. I proved this by incrmeneting the loop original index value from 1 to 3, hence the reason why the third side of the cube is displaying a value for EntityY: [EDIT] I could not get an array to work inside a function so I'd to go all long hand: |
| ||
This Text 180+(dice_x*60),466,+(EntityY( bottom_side(dice_x), 1 )) works better than this Text 180+(dice_x*60),466,+(EntityY( bottom_side(dice_x)) And has indeed revealed that my child entities appear to be slap bang in the centre of my cubes. |
| ||
Here is a demo using normals of a standard blitz cube and no child entities. I've used vertexcolor so that you can see what it's doing. When you create and texture the cube in your modeller, you will know what value each side has so adjust the returned values to suit. Graphics3D 640,480,32,1 Global DICE = DICEcreate() Global LIGHT = CreateLight() Global CAM = CreateCamera() PositionEntity CAM, 0,0,-5 While Not KeyHit(1) TurnEntity DICE, .05, 0, .05 RenderWorld() Color 255,255,255 Text 0,0, "The Dice Value is : " + DICEvalue( DICE ) Color 255,0,0 : Text 0,30, "Top: 1" Color 0,0,255 : Text 0,40, "Bottom: 6" Color 0,255,255 : Text 0,50,"Right: 2" Color 255,255,0 : Text 0,60,"Left: 5" Color 0,255,0 : Text 0,70, "Front: 3" Color 128,0,128 : Text 0,80,"Rear: 4" Flip Wend ;==================================================================== ;==================================================================== ;==================================================================== Function DICEvalue( mesh ) BestVert = - 1 BestHeight# = 0 s = GetSurface( mesh, 1 ) For t = 0 To CountTriangles( s ) - 1 Step 2 v0 = TriangleVertex( s, t, 0 ) TFormNormal VertexNX( s, v0 ) , VertexNY( s, v0 ), VertexNZ( s, v0 ), mesh, 0 If TFormedY() > BestHeight BestHeight = TFormedY() BestVert = v0 EndIf Next If VertexNY( s, BestVert ) = 1 Value = 1 ;Top If VertexNY( s, BestVert ) = - 1 Value = 6 ;Bottom If VertexNX( s, BestVert ) = 1 Value = 2 ;Right If VertexNX( s, BestVert ) = - 1 Value = 5 ;Left If VertexNZ( s, BestVert ) = 1 Value = 3 ;Front If VertexNZ( s, BestVert ) = - 1 Value = 4 ;Rear Return Value End Function ;==================================================================== ;==================================================================== ;==================================================================== Function DICEcreate() mesh = CreateCube() EntityFX mesh, 2+4 s = GetSurface( mesh, 1 ) For v = 0 To CountVertices(s)-1 If VertexNY( s, v ) = 1 VertexColor s, v, 255,0,0 If VertexNY( s, v ) = - 1 VertexColor s, v, 0,0,255 If VertexNX( s, v ) = 1 VertexColor s, v, 0,255,255 If VertexNX( s, v ) = - 1 VertexColor s, v, 255,255,0 If VertexNZ( s, v ) = 1 VertexColor s, v, 0,255,0 If VertexNZ( s, v ) = - 1 VertexColor s, v, 128,0,128 Next Return mesh End Function |
| ||
Thanks Stevie, I will give this a try shortly - I really appreciate the assistance. I was kind of reaching the banging my head against the monitor stage - hypothetically speaking (;-) Have just tried it on the laptop - thanks Stevie, this will be priceless with helping to develop my knowledge with respect to entity manipulation. I implemented the code within my main dice manipulator, alas when I assign any mesh to an ODE/mesh it loses the ability for info to be extracted regarding which side is up. It has got me contemplating the nuances of applying gravitational math, that'll be physics to the cubes to retain the ability to establish which way is up. Whilst the challenge of invoking some basic (erm, not so basic really) gravitational and rotational velocity to the cubes mathematically, I passed my O level physics but that was 22 years ago - I'm not up to it at the moment. |
| ||
I was AFK, kind of. Thanks for what you said about the blitzcube. This was a nice finger exercise :) Something that can be finished in a few days, unlike fullfledged game projects, like fps or so. Again, the cube problem. Let me suggest: when using pivots, since they are invisible, you may use CreateCube instead and alter it to CreatePivot later, when everything works. Just scale the cubes very small. Position them, parent them to the Dice, on the sides etc. They even don't have to be placed correctly on the surface, it's only important that they are aligned correctly. EG: dim piv(5) for i=0 to 5 piv(i)=createcube() scaleentity piv(i),0.1,0.1,0.1 entityparent piv(i),dice next translateentity piv(0), 1, 0, 0 translateentity piv(1),-1, 0, 0 translateentity piv(2), 0, 1, 0 translateentity piv(3), 0,-1, 0 translateentity piv(4), 0, 0, 1 translateentity piv(5), 0, 0,-1 I don't know, if ODE works together with Blitzs Entity Hierarchies. But if ODE doesn't move the children, then you maybe have to cheat somehow. Not sure if UpdateWorld is required here. Oh, and if your mesh is loaded with an offset center (you said something about -20 ??) then you may use a command like FitMesh to reset the center Pivot. And I think you don't have to use LoadAnimMesh (if you don't really need to identify the sides by their names - I don't know if this is mandatory. If the sides are always the same then I think it's not neccessary) To check what side is up you only have to filter the topmost pivot out. eg: thisit=-1 top_y#=-1000 for i=0 to 5 y#=entityy(piv(i),1) if y>top_y# then top_y#=y thisit=i endif next now the variable thisit should hold the number of the side that is up. You may use an additional array, like dim piv_name$(5) and name them accordingly in the creation loop. BTW if the eyes of the dice correspond with the indicies the way I created them - I guess no :) but I think you can fix that easily, with some fiddling. Hope this helps. Stevies Solution looks pretty good. You have the choice :) |
| ||
@jfk, thanks for the alternative suggestion - will try this out tomorrow now that I've resolved my minor problem where IDEal wouldn't start, no Microsoft application wanted to start with various cryptic error messages, my wifes camera wouldn't connect to the PC - needed to delete a file buried in the registry to permit the RPCServer to start. So, it wasn't really a minor problem - due to the fact I'm studying programming with the Open University and my Msoft IDE would not start. Happy dayz ;) Have had an initial stab at your pivot code - it certainly looks promising - thanks for the extra clarification from your initial post - the prospect of generating my own physics code was not overly appealing but now I've slept on it I do like a challenge! I really hope I can attach some pivots & cheat with the ODE mesh cubes - all in good time. |
| ||
I've made an initial stab at understanding the pivot angle of attack, however I have discovered some confusing results. For some reason some pivots are never considered as 'highest', I need to do some more analysis. Here is the code so far: |
| ||
@ Bp, you have a habbit of repeating code unnecessarily ;) This is all you need: thisit=-1 top_y#=-1000 For i = 0 To 5 y# = EntityY( piv(i) , 1 ) If y > top_y# Then top_y# = y thisit = i EndIf Next For i = 0 To 5 If thisit = i EntityColor piv(i), 255,0,0 Else EntityColor piv(i), 255,255,255 EndIf Next |
| ||
@Stevie, thanks, my debug has a way of running away with itself and ends up overcomplicating stuff. That works a treat on both the cubes created & the ODE/mesh cubes. ;) I've just got to check out fitmesh to re-centre the model I am using. ![]() |