#####[ Tips for importing OBJ (Wavefront) 3D models ]##### Last updated: 2023/11/25 Game Maker 6-8 -------------- If importing using actual Game Maker, you will need some scripts as otherwise, you will need to find a Blender plugin to help you export the model as D3D. Use the following script to help GM6 and newer load OBJ 3D models. The script starts and stops between the dotted lines; do not copy/paste the dotted lines. Make sure to keep reading afterwards. ------------------------[scr_createFromOBJ]----------------------------- // MOSAIC Light 3D OBJ IMPORTER // (c) 2006. Zoltan Percsich. All Rights Reserved. // Don't edit this script filename=argument0; flipnormals = 1; if (argument1>0) flipnormals=-1; vertex_list1=ds_list_create();ds_list_clear(vertex_list1);ds_list_add(vertex_list1,0); vertex_list2=ds_list_create();ds_list_clear(vertex_list2);ds_list_add(vertex_list2,0); vertex_list3=ds_list_create();ds_list_clear(vertex_list3);ds_list_add(vertex_list3,0); normal_list1=ds_list_create();ds_list_clear(normal_list1);ds_list_add(normal_list1,0); normal_list2=ds_list_create();ds_list_clear(normal_list2);ds_list_add(normal_list2,0); normal_list3=ds_list_create();ds_list_clear(normal_list3);ds_list_add(normal_list3,0); texture_list1=ds_list_create();ds_list_clear(texture_list1);ds_list_add(texture_list1,0); texture_list2=ds_list_create();ds_list_clear(texture_list2);ds_list_add(texture_list2,0); faces_list=ds_list_create();ds_list_clear(faces_list); fp=file_text_open_read(filename); for (i=0;file_text_eof(fp)==false;i+=1) { row=file_text_read_string(fp);row=string_replace_all(row," "," "); if (string_char_at(row,1)=="v" && string_char_at(row,2)==" ") { row=string_delete(row,1,string_pos(" ",row)); vx=real(string_copy(row,1,string_pos(" ",row))); row=string_delete(row,1,string_pos(" ",row)); vy=real(string_copy(row,1,string_pos(" ",row))); row=string_delete(row,1,string_pos(" ",row)); vz=real(string_copy(row,1,string_length(row))); ds_list_add(vertex_list1,vx); ds_list_add(vertex_list2,vy); ds_list_add(vertex_list3,vz); } if (string_char_at(row,1)=="v" && string_char_at(row,2)=="n") { row=string_delete(row,1,string_pos(" ",row)); nx=real(string_copy(row,1,string_pos(" ",row))); row=string_delete(row,1,string_pos(" ",row)); ny=real(string_copy(row,1,string_pos(" ",row))); row=string_delete(row,1,string_pos(" ",row)); nz=real(string_copy(row,1,string_length(row))); ds_list_add(normal_list1,nx); ds_list_add(normal_list2,ny); ds_list_add(normal_list3,nz); } if (string_char_at(row,1)=="v" && string_char_at(row,2)=="t") { row=string_delete(row,1,string_pos(" ",row)); tx=real(string_copy(row,1,string_pos(" ",row))); row=string_delete(row,1,string_pos(" ",row)); ty=real(string_copy(row,1,string_length(row))); ds_list_add(texture_list1,tx); ds_list_add(texture_list2,ty); } if (string_char_at(row,1)=="f" && string_char_at(row,2)==" ") { row=string_replace_all(row," "," "); row=string_delete(row,1,string_pos(" ",row)); if (string_char_at(row,string_length(row))==" ") row=string_copy(row,0,string_length(row)-1); face_num=string_count(" ",row); face_division=1; temp_faces[0]=0; for (fc=0;fc=1) { nx=flipnormals*ds_list_find_value(normal_list1,floor(real(n_index))); ny=flipnormals*ds_list_find_value(normal_list2,floor(real(n_index))); nz=flipnormals*ds_list_find_value(normal_list3,floor(real(n_index))); } else { nx=0; ny=0; nz=0; } if (floor(real(t_index))!=-1 && ds_list_size(texture_list1)>=1) { tx=ds_list_find_value(texture_list1,floor(real(t_index))); ty=ds_list_find_value(texture_list2,floor(real(t_index))); } else { tx=0; ty=0; } d3d_model_vertex_normal_texture(tm,vx,vy,vz,nx,ny,nz,tx,ty); tsn+=1; if (tsn==999) { tsn=0; d3d_model_primitive_end(tm); d3d_model_primitive_begin(tm,pr_trianglelist); } } d3d_model_primitive_end(tm); return tm; ------------------------------------------------------------------------ Next, you can load a 3D model by placing the following in a script within the Create Event of the object that is to load the OBJ model.... //Load the 3D model example_model = createFromObj('Example.obj',false) ...You would then use the "d3d_model_draw(example_model,0,0,0,spr_example_texture)" like usual or however you plan on showing the 3D model. What the "MOSAIC Light 3D OBJ IMPORTER" script is basically doing is converting an OBJ to a D3D format. The true/false part of the argument is to tell the script whether or not to flip the normals. I would also like to point-out that in Blender, if you created a cube that was 16x16x16 dimensions in size using the standard Blender units, that cube fits perfectly in relation to Game Maker's room editor grid. In other words, a 16x16x16 cube made in Blender will fit within a 640x480 room with d3d enabled 40 times by 30 times, not including stacking. Think of a single Blender unit as a single pixel in Game Maker. It is also worth noting that when it comes to importing an OBJ model, the origin of that model known to Blender does not determine relative positioning as far as Game Maker is concerned; in other words, always keep the 3D model relative to the center of the scene in Blender and the lowest point (such as feet or the bottom of a box) just barely above the floor level in Blender. When exporting your OBJ model in Blender, make sure that: - Forward: Y Forward - Up: Z Up - Scale = 1 If your model is to be animated, the script above will not work, but stationary models will be fine. However, if you are using LateralGM+ Enigma, you can get a model to animate but this has to be done by showing a different OBJ model for each frame and by using its built-in OBJ model support. If you export an OBJ model with animation using Blender, it will automatically generate a single OBJ model for each frame for you, assuming that you have "Animation" checked during the export process.