How can I capture world...
Blitz3D Forums/Blitz3D Beginners Area/How can I capture world...
| ||
I need to figure out a way to capture all of the objects' locations and save to a file. I am working on a machine simulator for bending sheet metal parts. I am thinking that I want the user to be able to set the machine settings for each bend on the sheet metal part and then click a button to save the settings. The sheet metal part can have many bends, so I need to be able to save many machine settings. For example: Image a box without a lid. It will have 5 sides...a left, right, back, front and bottom. To make a sheet metal box like that it will start off flat and look similar to a cross. If you fold up each of the 4 legs of the cross, you will end up with a 5 sided box. So I have a "machine" programmed in Blitz that allows the user to import a flat sheet metal part from a CAD system. The user can move the flat part on the screen and also move parts of the machine around until the part and machine "fit" like the user wants. Once the machine setup is correct, I want the user to be able to click on a button that will "save" all of these positions...the part positions and machine positions. For each bend on the part, I will need to be able to save the part and machine positions. Ultimately, I want to be able to recall these part and machine positions and play them back on the screen and maybe even change the order of the playback. I feel confident that I can write a file to save this information but I need help with how to "Capture all of the positions so that I can write them to the file. So...Is it easy to capture all of the positions of my entities (X, Y, Z, angles etc)? If so, can you give me a hint of how it can be done? Thanks, David |
| ||
You need to keep track of the entities, in either an array, or a type list. You can't really do this, without the above. Then, it's just a case of looping through each entity and calling EntityX(), EntityY() and EntityZ(), and EntityPitch(), EntityYaw() and EntityRoll(). |
| ||
Ross C, You always seem to be here (there?) to answer my questions. Thanks for that. If I understand correctly... If I have 4 entities like Gage1, Gage2, Part1 and Part2, I can code something like: Open "C:\Temp\capture.txt" for output as #1 Print #1, EntityX(Gage1) & "," & EntityY(Gage1) & "," & EntityZ(Gage1) & "," & EntityPitch(Gage1) & "," & EntityYaw(Gage1) & "," & EntityRoll(Gage1) Print #1, EntityX(Gage2) & "," & EntityY(Gage2) & "," & EntityZ(Gage2) & "," & EntityPitch(Gage2) & "," & EntityYaw(Gage2) & "," & EntityRoll(Gage2) Print #1, EntityX(Part1) & "," & EntityY(Part1) & "," & EntityZ(Part1) & "," & EntityPitch(Part1) & "," & EntityYaw(Part1) & "," & EntityRoll(Part1) Print #1, EntityX(Part2) & "," & EntityY(Part2) & "," & EntityZ(Part2) & "," & EntityPitch(Part2) & "," & EntityYaw(Part2) & "," & EntityRoll(Part2) Close #1 Then, when I am ready to reset all of my entities back to a previously saved state, just read that data back in and use commands like: PositionEntity and RotateEntity I know the open file syntax above is not Blitz. I will have to adjust that when the time comes. Is there some other easy way to loop through all of my entities? Right now, I think that I only need locations for 4 entities but for future reference, is there a easy way? Thanks, David |
| ||
; Reading and writing custom types to files using ReadFile, WriteFile and CloseFile ; Initialise some variables for the example Type HighScore Field Name$ Field Score% Field Level% End Type Best.HighScore = New HighScore Best\Name = "Mark" Best\Score = 11657 Best\Level = 34 ; Open a file to write to fileout = WriteFile("mydata.dat") ; Write the information to the file WriteString( fileout, Best\Name ) WriteInt( fileout, Best\Score ) WriteByte( fileout, Best\Level ) ; Close the file CloseFile( fileout ) ; Open the file to Read filein = ReadFile("mydata.dat") ; Lets read the Greatest score from the file Greatest.HighScore = New HighScore Greatest\Name$ = ReadString$( filein ) Greatest\Score = ReadInt( filein ) Greatest\Level = ReadByte( filein ) ; Close the file once reading is finished CloseFile( fileout ) Print "High score record read from - mydata.dat " Print Write "Name = " Print Greatest\Name Write "Score = " Print Greatest\Score Write "Level = " Print Greatest\Level WaitKey() This is an example from the manual. |
| ||
You'll need to use either arrays or type objects.Type Machine_Part Field name$ Field entity End Type m.machine_part = new machine_part m\name$ = "Gage1" m\entity = createsphere() ; just for example m\name$ = "Gage2" m\entity = createsphere() ; just for example m\name$ = "Part1" m\entity = createsphere() ; just for example m\name$ = "Part2" m\entity = createsphere() ; just for example Open "C:\Temp\capture.txt" for output as #1 For m.machine_part = Each machine_part Print #1,EntityX(m\entity)& "," & EntityY(m\entity) & "," & EntityZ(m\entity) Next That will loop through every entity you have created in that type and save them to the text file. Obviously not the correct syntax used, but you get my drift :o) |
| ||
Thanks Joseph, That will be helpful. David |
| ||
Thanks Ross C. That will keep me busy for a while. David |
| ||
Another way to parse your entities would be to create a pivot and parent all your top level (normally unparented) entities to that. You could then simply recurse the child lists originating with that pivot. Eg. Graphics 800, 600, 0, 2 SetBuffer BackBuffer() Global G_world = CreatePivot() ; Example entities. CreateSphere( CreateSphere( G_world ) ) Function RecurseAllEntities( entity ) ; Perform whatever operation you need to regarding 'entity' here. Local num, i num = CountChildren( entity ) For i = 1 To num RecurseAllEntities( GetChild ( entity, i ) ) Next End Function RecurseAllEntities( G_world ) End |
| ||
Thank you Bill. I see how that works. I will keep that method in my back pocket for later use. David |
| ||
Am I missing something with writing files? I can't seem to find how to append data to a plain text file. In VB, you can use something like: Open "C:\Temp\junk.txt" for append as #1 Print #1, "Some text" close #1 I cannot seem to find out how to open a file in Blitz for append. I want to work with a plain text file. Is this possible? Here is the code that I am currently working with... fileout=writefile("C:\Temp\junk.txt") writeline(fileout, "Some Text") closefile(fileout) If Blitz does not have any built-in methods to append data to a plain text file, then I can do it other ways but I was hoping for a simple solution. Thanks for any help, David |
| ||
That code saves it as a plain text file for me. Jusy make sure that the path is valid. I had to change the path for it to work. |
| ||
KillerX, I meant that I need to write to that file on more than one occassion. For example: I want the user to click a button and data will get written to that file. Later on, I want the user to click a button again and have more information written to that same file. I do not see where I can reopen an existing file to append data to the file. I can figure out other ways to do it but I was hoping for a built-in easy solution to append plain text data to an existing file. Thanks, David |
| ||
I believe you have to write the whole file again. You can insert data i'm sure though, but it's a bit trickier. |
| ||
OK. I thought maybe I just missed something in the help file that allows appending data to a plain text file. I will have to get more creative then. I can allow the user to click a button and save data to text files that get named by my code and when I need all of the data to be in one file, I can just read the directory for all of the text files that were created and copy the contents of each file into my one big combined file and then delete all of the individual files. Maybe I will think of some better solution later but that should work for me for now. Thanks, David |
| ||
Ross C, By the way, with your help, I am now able to save all of my entities positions to a text file as many times as I want and then read those files back in to review the positions that were saved. It works very good. Thanks, David |
| ||
Doesn't OpenFile work for appending data to files ? |
| ||
I saw that in the help but it talked about using FilePos and SeekFile but the files will be of unknown length and I was not sure how to find the end of the file. However, it just occured to me that I can use OpenFile and use some code like this to read the entire file before writing any new stuff to it... ;Create a new text file and write some text to it FileOut=WriteFile("C:\Temp\Junk.txt") WriteLine(FileOut, "Line1") CloseFile(FileOut) ;Open an existing text file, read to the end of it and then write more text to it FileOut=OpenFile("C:\Temp\Junk.txt") While Not EOF(FileOut) Hold$ = ReadLine(FileOut) Wend ;Now that we are at the end of the file, let's write some new text to it WriteLine(FileOut, "More text.") ;Close the file now CloseFile(FileOut) So, this should work for me. If there is an easier way, please let me know. Thanks for the tip. David |
| ||
Easiest is just saving over the top of the file tbh. Basically rewriting everything. Since you will probably have a save file function anyway, it should be easy :o) |
| ||
use filesize() to get the end of the file. NOTE when using OpenFile() the file has to exists. you could use WriteFile() to create the file then use OpenFile() to append to itfilename$ = "test.txt" file = OpenFile(filename$) SeekFile(file,FileSize(filename$)) WriteLine(file,"hello") CloseFile(file) |
| ||
Thanks Kev. Thanks looks simpler and probably faster too. Ross C, My issue is that I allow the user to move things on the screen and when everything is where the user wants it, he can press a save button and all of the entities locations will get saved. But most of the time, the user will need to move the stuff on the screen again and will need to save the new locations in addition to the previously saved locations. The user will need to do this multiple times, sometimes as many as 25 times. Finally, after moving things around on the screen and saving the locations, the user will need to push a button and play back each of the saved locations to verify that he located everything properly. Sometimes, it will be necessary for the user to change the order of the saved locations too. For example, if the user moves things on the screen and saves the locations, they get saved as Step1. Then the user might need to move the stuff on the screen again and save the new locations as Step2. After clicking a button to play back the 2 steps, the user might choose to swap the order of the steps so that Step2 is before Step1. I know this is probably very confusing to you since you do not know exactly what I am trying to do with this program. I suppose that I could write all of this stuff to an array rather than a file. I just chose a file since I am much more familiar with working with files than arrays. Thanks, David |
| ||
use types this way you have full control of the saved locations, should a user wish to move a save position then you could simply modify the order of the types list. hence should the user wish to save new position add them to the type list. |
| ||
Kev, I am not sure that I understand what you mean as I am just learning to use Types thanks to Ross C. Do you have some simple code for me to look at? Example: 1. display a simple single cube. 2. allow the user to move it then press a button to save the location 3. allow the user to move it again then press a button to save the location again 4. press a button to play back the two saved locations with a waitkey in between steps This is what I think you mean... Type Positions Field StepNumber Field EntityNumber Field XPos Field YPos Field ZPos Field Pitch Field Yaw Field Roll End Type Then when the user wants to save a step, add to the list. Then give some way to reorder the list and maybe even delete steps from the list? Thanks, David |
| ||
hollifd, heres a very basic example and not put together well, what it does is take the position of the cube and store it in the type each time space is pressed. pressing f1 and then the mousebutton will loop through the positions in the type; ; ; Type Tobject Field ob_id Field entity Field x#,y#,z# Field pitch#,Yaw#,roll# End Type Graphics3D 640,480,16,2 SetBuffer BackBuffer() camera = CreateCamera() PositionEntity camera,0,0,0 cube = CreateCube() PositionEntity cube,0,0,15 While Not KeyDown(1) If KeyHit(59) Then For o.Tobject = Each Tobject PositionEntity o\entity,o\x#,o\y#,o\z# UpdateWorld RenderWorld Text 100,100,"press mouse button for next position" MouseWait Flip Next EndIf If KeyHit(57) Then o.Tobject = New Tobject o\entity = cube ; this could be the selected entity o\x# = EntityX(o\entity) o\y# = EntityY(o\entity) o\z# = EntityZ(o\entity) EndIf If KeyDown(203) MoveEntity cube,-.3,0,0 EndIf If KeyDown(205) MoveEntity cube,.3,0,0 EndIf UpdateWorld RenderWorld Text 10,10,"space to snap position" Text 10,30,"f1 to play positions" Flip Wend End this code will add ten items to a type list and then loop though and if the index of the type = 6 a new type is inserted before and after number 6, to show this ive marked the new entrys as -1 ; ; ; Type Tobject Field ob_id Field entity Field x#,y#,z# Field pitch#,Yaw#,roll# End Type For add_item = 0 To 10 o.Tobject = New Tobject o\ob_id = add_item Next ; this loops through until the type\ob_id=6, we then insert one item before and mark is as -1 For o.Tobject = Each Tobject If o\ob_id = 6 Then insert_o.Tobject = New Tobject insert_o\ob_id = -1 Insert insert_o Before o EndIf Next ; this loops through until the type\ob_id=6, we then insert one item after and mark is as -1 For o.Tobject = Each Tobject If o\ob_id = 6 Then insert_o.Tobject = New Tobject insert_o\ob_id = -1 Insert insert_o After o EndIf Next ; standard loop of types in the Tobject list For o.Tobject = Each Tobject Print o\ob_id Next MouseWait End both example's are basic but will point you in the right direction, i hope. |
| ||
Kev, Now I understand better what you are doing. I am having family in this weekend but I want to study this more early next week to get a better grip on Types as I am sure this is the way to go and will make life much easier and my coding much better. I have coded some of this already without using Types and the code is very messy and very long. Thanks again, David |