static void Camera_new (LIScrArgs* args) { LIExtCamera* self; LIExtCameraModule* module; LIScrData* data; LIRenRender* render; LIRenVideomode mode; /* Allocate self. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_CAMERA); self = liext_camera_new (module); if (self == NULL) return; liext_camera_set_driver (self, LIALG_CAMERA_THIRDPERSON); /* Initialize the viewport. */ render = limai_program_find_component (module->program, "render"); if (render) { liren_render_get_videomode (render, &mode); liext_camera_set_viewport (self, 0, 0, mode.width, mode.height); } /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_CAMERA, liext_camera_free); if (data == NULL) { liext_camera_free (self); return; } liscr_args_seti_stack (args); }
static void Widgets_draw (LIScrArgs* args) { LIExtModule* module; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); liwdg_manager_render (module->widgets); }
static void Sound_get_listener_rotation (LIScrArgs* args) { LIExtModule* module; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); liscr_args_seti_quaternion (args, &module->listener_rotation); }
static void Voxel_fill_region (LIScrArgs* args) { int i; int count; int type = 0; LIExtModule* module; LIMatVector pos; LIMatVector size; LIVoxVoxel tile; LIVoxVoxel* tiles; /* Handle arguments. */ if (!liscr_args_gets_vector (args, "point", &pos) || !liscr_args_gets_vector (args, "size", &size)) return; if (size.x < 1.0f || size.y < 1.0f || size.z < 1.0f) return; liscr_args_gets_int (args, "tile", &type); livox_voxel_init (&tile, type); /* Allocate tiles. */ count = (int) size.x * (int) size.y * (int) size.z; tiles = lisys_calloc (count, sizeof (LIVoxVoxel)); if (tiles == NULL) return; for (i = 0 ; i < count ; i++) tiles[i] = tile; /* Paste tiles to the map. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL); livox_manager_paste_voxels (module->voxels, (int) pos.x, (int) pos.y, (int) pos.z, (int) size.x, (int) size.y, (int) size.z, tiles); lisys_free (tiles); }
static void Ai_solve_path (LIScrArgs* args) { int i; LIAiPath* path; LIExtModule* module; LIMatVector point; LIMatVector start; LIMatVector end; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_AI); if (!liscr_args_gets_vector (args, "start", &start)) return; if (!liscr_args_gets_vector (args, "start", &start) || !liscr_args_gets_vector (args, "target", &end)) return; /* Solve the path. */ path = liai_manager_solve_path (module->ai, &start, &end); if (path == NULL) return; /* Store the path to a table. */ liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); for (i = 0 ; i < liai_path_get_length (path) ; i++) { liai_path_get_point (path, i, &point); liscr_args_seti_vector (args, &point); } liai_path_free (path); }
static void Terrain_new (LIScrArgs* args) { int chunk_size; float grid_size; LIExtTerrain* self; LIExtTerrainModule* module; LIScrData* data; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &chunk_size) || chunk_size < 1) return; if (!liscr_args_geti_float (args, 1, &grid_size) || grid_size <= 0.0f) return; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); /* Allocate the object. */ self = liext_terrain_new (module, chunk_size, grid_size); if (self == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_TERRAIN, liext_terrain_free); if (data == NULL) { liext_terrain_free (self); return; } liscr_args_seti_stack (args); }
static void Heightmap_new (LIScrArgs* args) { int i; int size; float spacing; float scaling; LIExtHeightmap* heightmap; LIExtHeightmapModule* module; LIImgImage* image; LIMatVector position; LIScrData* data; /* Get arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); if (!liscr_args_geti_vector (args, 0, &position)) position = limat_vector_init (0.0f, 0.0f, 0.0f); if (!liscr_args_geti_int (args, 1, &size)) size = 33; else if (size < 0) size = 0; if (!liscr_args_geti_float (args, 2, &spacing)) spacing = 1.0f; else if (spacing <= 0.0f) spacing = 1.0f; if (!liscr_args_geti_float (args, 3, &scaling)) scaling = 1.0f; else if (scaling <= 0.0f) scaling = 1.0f; if (liscr_args_geti_data (args, 4, LIEXT_SCRIPT_IMAGE, &data)) image = liscr_data_get_data (data); else image = NULL; /* Ensure that the size is valid. */ for (i = 32 ; i < 65536 ; i *= 2) { if (size == i + 1) break; } if (size != i + 1) { lisys_error_set (EINVAL, "invalid heightmap size"); lisys_error_report (); return; } /* Allocate the heightmap. */ heightmap = liext_heightmap_new (module, image, &position, size, spacing, scaling); if (heightmap == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, heightmap, LIEXT_SCRIPT_HEIGHTMAP, liext_heightmap_free); if (data == NULL) { liext_heightmap_free (heightmap); return; } liscr_args_seti_stack (args); }
static void Model_get_total_model_count (LIScrArgs* args) { LIMaiProgram* program; program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); liscr_args_seti_int (args, program->models->models->size); }
static void Model_copy (LIScrArgs* args) { int shape_keys = 1; LIMaiProgram* program; LIMdlModel* self; LIScrData* data; /* Get arguments. */ program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); liscr_args_geti_bool (args, 0, &shape_keys); /* Allocate the model. */ self = limdl_model_new_copy (args->self, shape_keys); if (self == NULL) return; /* Allocate the unique ID. */ if (!limdl_manager_add_model (program->models, self)) { limdl_model_free (self); return; } /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LISCR_SCRIPT_MODEL, limdl_manager_free_model); if (data == NULL) { limdl_model_free (self); return; } liscr_args_seti_stack (args); }
static void Widgets_find_widget (LIScrArgs* args) { int x; int y; LIExtModule* module; LIWdgWidget* widget; LIMatVector vector; LIScrData* data; if (!liscr_args_gets_vector (args, "point", &vector) && !liscr_args_geti_vector (args, 0, &vector)) { SDL_GetMouseState (&x, &y); vector = limat_vector_init (x, y, 0.0f); } module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); widget = liwdg_manager_find_widget_by_point (module->widgets, (int) vector.x, (int) vector.y); if (widget == NULL) return; data = liwdg_widget_get_script (widget); if (data == NULL) return; liscr_args_seti_data (args, data); }
static void Sound_get_listener_velocity (LIScrArgs* args) { LIExtModule* module; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); liscr_args_seti_vector (args, &module->listener_velocity); }
static void Model_changed (LIScrArgs* args) { LIMaiProgram* program; /* Invoke callbacks. */ program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); lical_callbacks_call (program->callbacks, "model-changed", lical_marshal_DATA_PTR, args->self); }
static void Sound_set_listener_velocity (LIScrArgs* args) { LIExtModule* module; LIMatVector value; if (liscr_args_geti_vector (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); module->listener_velocity = value; } }
static void Sound_set_listener_rotation (LIScrArgs* args) { LIExtModule* module; LIMatQuaternion value; if (liscr_args_geti_quaternion (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); module->listener_rotation = value; } }
static void Sound_set_music_volume (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND float value; LIExtModule* module; if (liscr_args_geti_float (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); liext_sound_set_music_volume (module, value); } #endif }
static void Model_get_total_memory_used (LIScrArgs* args) { int total; LIMaiProgram* program; LIAlgU32dicIter iter; program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); total = 0; LIALG_U32DIC_FOREACH (iter, program->models->models) total += limdl_model_get_memory (iter.value); liscr_args_seti_int (args, total); }
static void Sound_set_music (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND const char* value; LIExtModule* module; if (liscr_args_geti_string (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); liext_sound_set_music (module, value); } #endif }
static void Sound_get_music_offset (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND LIExtModule* module; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); if (module->music != NULL) liscr_args_seti_float (args, lisnd_source_get_offset (module->music)); else liscr_args_seti_float (args, 0.0f); #else liscr_args_seti_float (args, 0.0f); #endif }
static void Sound_set_music_offset (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND float value; LIExtModule* module; if (liscr_args_geti_float (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); if (module->music != NULL) lisnd_source_set_offset (module->music, value); } #endif }
static void Terrain_build_chunk_model (LIScrArgs* args) { int grid_x; int grid_z; LIExtTerrain* self; LIExtTerrainModule* module; LIMatVector offset; LIMdlModel* model; LIScrData* data; /* Get the arguments. */ self = args->self; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_vector (args, 2, &offset)) offset = limat_vector_init (grid_x * self->grid_size, 0.0f, grid_z * self->grid_size); /* Build the model. */ model = liext_terrain_build_chunk_model (self, grid_x, grid_z, &offset); if (model == NULL) return; /* Copy the model. */ model = limdl_model_new_copy (model, 0); if (model == NULL) return; /* Allocate the unique ID. */ if (!limdl_manager_add_model (module->program->models, model)) { limdl_model_free (model); return; } /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, model, LISCR_SCRIPT_MODEL, limdl_manager_free_model); if (data == NULL) { limdl_model_free (model); return; } liscr_args_seti_stack (args); }
static void Widgets_get_focused_widget (LIScrArgs* args) { int x; int y; LIExtModule* module; LIWdgWidget* widget; LIScrData* data; SDL_GetMouseState (&x, &y); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); widget = liwdg_manager_find_widget_by_point (module->widgets, x, y); if (widget == NULL) return; data = liwdg_widget_get_script (widget); if (data == NULL) return; liscr_args_seti_data (args, data); }
static void Thread_new (LIScrArgs* args) { const char* args_ = ""; const char* file = "main.lua"; const char* code = NULL; LIExtModule* module; /* Read arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_THREAD); if (!liscr_args_geti_string (args, 0, &file)) liscr_args_gets_string (args, "file", &file); if (!liscr_args_geti_string (args, 1, &args_)) liscr_args_gets_string (args, "args", &args_); if (!liscr_args_geti_string (args, 2, &code)) liscr_args_gets_string (args, "code", &code); /* Create the thread to the stack. */ if (liext_thread_inst_new (module->program, args->lua, file, code, args_) != NULL) liscr_args_seti_stack (args); }
static void Animation_load (LIScrArgs* args) { char* file; const char* path; const char* name; LIMdlAnimation* self; LIExtAnimationModule* module; LIScrData* data; /* Get arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_ANIMATION); if (!liscr_args_geti_string (args, 0, &name)) return; /* Create the path. */ file = lisys_string_concat (name, ".lani"); if (file == NULL) return; path = lipth_paths_find_file (module->program->paths, file); lisys_free (file); if (path == NULL) return; /* Allocate the animation. */ self = limdl_animation_new_from_file (path); if (self == NULL) { lisys_error_report (); return; } /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_ANIMATION, limdl_animation_free); if (data == NULL) { limdl_animation_free (self); return; } liscr_args_seti_stack (args); }
static void Widget_new (LIScrArgs* args) { LIExtModule* module; LIScrData* data; LIWdgWidget* self; /* Allocate userdata. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGET); self = liwdg_widget_new (module->widgets); if (self == NULL) return; /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_WIDGET, liwdg_widget_free); if (data == NULL) { liwdg_widget_free (self); return; } liwdg_widget_set_script (self, data); liscr_args_seti_stack (args); }
static void Widgets_add_font_style (LIScrArgs* args) { int size = 16; const char* file; const char* name; LIExtModule* module; /* Arguments. */ if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "name", &name)) return; if (!liscr_args_geti_string (args, 1, &file) && !liscr_args_gets_string (args, "file", &file)) return; if (!liscr_args_geti_int (args, 2, &size)) liscr_args_gets_int (args, "size", &size); /* Load the font. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); if (!liwdg_styles_load_font (module->widgets->styles, name, file, size)) lisys_error_report (); }
static void Model_load (LIScrArgs* args) { int mesh = 1; char* file; const char* name; const char* path; LIMdlModel* tmpmdl; LIMaiProgram* program; program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "file", &name)) return; if (!liscr_args_geti_bool (args, 1, &mesh)) liscr_args_gets_bool (args, "mesh", &mesh); /* Find the absolute path. */ file = lisys_string_concat (name, ".lmdl"); if (file == NULL) return; path = lipth_paths_find_file (program->paths, file); if (path == NULL) { lisys_free (file); return; } lisys_free (file); /* Load the new model data. */ tmpmdl = limdl_model_new_from_file (path, mesh); if (tmpmdl == NULL) return; /* Replace the old model data. */ if (limdl_model_replace (args->self, tmpmdl)) liscr_args_seti_bool (args, 1); limdl_model_free (tmpmdl); }
static void Sound_effect (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND int tmp; int flags = 0; float pitch; float volume; const char* effect; LIEngObject* object; LIExtModule* module; LIMatVector velocity; LIScrData* data; LISndSource* source; if (liscr_args_gets_string (args, "effect", &effect) && liscr_args_gets_data (args, "object", LISCR_SCRIPT_OBJECT, &data)) { if (liscr_args_gets_bool (args, "positional", &tmp) && !tmp) flags |= LIEXT_SOUND_FLAG_NONPOSITIONAL; if (liscr_args_gets_bool (args, "repeating", &tmp) && tmp) flags |= LIEXT_SOUND_FLAG_REPEAT; object = liscr_data_get_data (data); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); source = liext_sound_set_effect (module, object->id, effect, flags); if (source != NULL) { if (liscr_args_gets_float (args, "pitch", &pitch)) lisnd_source_set_pitch (source, pitch); if (liscr_args_gets_float (args, "volume", &volume)) lisnd_source_set_volume (source, volume); if (liscr_args_gets_vector (args, "velocity", &velocity)) lisnd_source_set_velocity (source, &velocity); } } #endif }
static void Voxel_find_blocks (LIScrArgs* args) { int sx; int sy; int sz; int index; int line; int stamp; float radius; LIAlgRange sectors; LIAlgRange blocks; LIAlgRange range; LIAlgRangeIter iter0; LIAlgRangeIter iter1; LIExtModule* module; LIMatVector min; LIMatVector max; LIMatVector point; LIMatVector size; LIVoxBlock* block; LIVoxSector* sector; /* Initialize arguments. */ if (!liscr_args_gets_vector (args, "point", &point)) return; liscr_args_gets_float (args, "radius", &radius); liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL); line = module->voxels->blocks_per_line * module->voxels->sectors->count; /* Calculate sight volume. */ size = limat_vector_init (radius, radius, radius); min = limat_vector_subtract (point, size); max = limat_vector_add (point, size); sectors = lialg_range_new_from_aabb (&min, &max, module->voxels->sectors->width); sectors = lialg_range_clamp (sectors, 0, module->voxels->sectors->count - 1); blocks = lialg_range_new_from_aabb (&min, &max, module->voxels->sectors->width / module->voxels->blocks_per_line); blocks = lialg_range_clamp (blocks, 0, module->voxels->blocks_per_line * module->voxels->sectors->count - 1); /* Loop through visible sectors. */ LIALG_RANGE_FOREACH (iter0, sectors) { /* Get voxel sector. */ sector = lialg_sectors_data_index (module->voxels->sectors, LIALG_SECTORS_CONTENT_VOXEL, iter0.index, 0); if (sector == NULL) continue; /* Calculate visible block range. */ livox_sector_get_offset (sector, &sx, &sy, &sz); sx *= module->voxels->blocks_per_line; sy *= module->voxels->blocks_per_line; sz *= module->voxels->blocks_per_line; range.min = 0; range.max = module->voxels->blocks_per_line; range.minx = LIMAT_MAX (blocks.minx - sx, 0); range.miny = LIMAT_MAX (blocks.miny - sy, 0); range.minz = LIMAT_MAX (blocks.minz - sz, 0); range.maxx = LIMAT_MIN (blocks.maxx - sx, module->voxels->blocks_per_line - 1); range.maxy = LIMAT_MIN (blocks.maxy - sy, module->voxels->blocks_per_line - 1); range.maxz = LIMAT_MIN (blocks.maxz - sz, module->voxels->blocks_per_line - 1); /* Loop through visible blocks. */ LIALG_RANGE_FOREACH (iter1, range) { block = livox_sector_get_block (sector, iter1.x, iter1.y, iter1.z); stamp = livox_block_get_stamp (block); index = (sx + iter1.x) + (sy + iter1.y) * line + (sz + iter1.z) * line * line; liscr_args_setf_float (args, index, stamp); }
static void Voxel_copy_region (LIScrArgs* args) { int i; int length; int sector; int offset[3]; LIArcPacket* packet; LIScrData* data; LIExtModule* module; LIMatVector point; LIMatVector size; LIVoxVoxel* result; /* Get region offset and size. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL); if (liscr_args_gets_int (args, "sector", §or)) { lialg_sectors_index_to_offset (module->program->sectors, sector, offset + 0, offset + 1, offset + 2); point = limat_vector_init (offset[0], offset[1], offset[2]); point = limat_vector_multiply (point, module->voxels->tiles_per_line); size.x = size.y = size.z = module->voxels->tiles_per_line; length = module->voxels->tiles_per_sector; } else if (liscr_args_gets_vector (args, "point", &point) && liscr_args_gets_vector (args, "size", &size)) { if (point.x < 0.0f || point.y < 0.0f || point.z < 0.0f || size.x < 1.0f || size.y < 1.0f || size.z < 1.0f) return; length = (int) size.x * (int) size.y * (int) size.z; } else return; /* Read voxel data. */ result = lisys_calloc (length, sizeof (LIVoxVoxel)); if (result == NULL) return; livox_manager_copy_voxels (module->voxels, (int) point.x, (int) point.y, (int) point.z, (int) size.x, (int) size.y, (int) size.z, result); /* Create a packet writer. */ packet = liarc_packet_new_writable (0); if (packet == NULL) { lisys_free (result); return; } /* Write the dimensions. */ if (!liarc_writer_append_uint32 (packet->writer, (int) size.x) || !liarc_writer_append_uint32 (packet->writer, (int) size.y) || !liarc_writer_append_uint32 (packet->writer, (int) size.z)) { lisys_free (result); return; } /* Write voxel data. */ for (i = 0 ; i < length ; i++) { if (!livox_voxel_write (result + i, packet->writer)) { lisys_free (result); return; } } lisys_free (result); /* Return data. */ data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data == NULL) { liarc_packet_free (packet); return; } liscr_args_seti_stack (args); }
/** Script callback Los.heightmap_generate This function converts the image data to Voxels: <li>First image contains height information in color values</li> <li>Second image contains material information in color values</li> <li>Position is the lower inferior voxel of the mapped area</li> <li>Size is the volume of the mapped area. Base size must fit with image size</li> <li>Materials is an array of mat ID used to associate voxel types</li> \param LIScrArgs* args */ static void Heightmap_heightmap_generate (LIScrArgs* args) { LIExtModule* module; LIVoxManager* voxels; LIVoxVoxel* tmp; const char* map_file; const char* tiles_file; LIMatVector posv; LIMatVector sizev; int materials[MAX_TEXTURES]; void* map_data; void* tiles_data; int min[3]; int max[3]; int size[3]; int x,y,z, y2, i, value; printf("Starting heightmap generation\n"); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); voxels = limai_program_find_component (module->program, "voxels"); if (voxels == NULL) return; if (!liscr_args_geti_string (args, 0, &map_file) && liscr_args_gets_string (args, "map", &map_file)) return; if (!liscr_args_geti_string (args, 1, &tiles_file)) liscr_args_gets_string (args, "tiles", &tiles_file); if (!liscr_args_geti_vector (args, 2, &posv)) liscr_args_gets_vector (args, "pos", &posv); if (!liscr_args_geti_vector (args, 3, &sizev)) liscr_args_gets_vector (args, "size", &sizev); if (!liscr_args_geti_intv (args, 4, MAX_TEXTURES, materials)) liscr_args_gets_intv (args, "materials", MAX_TEXTURES, materials); if (liext_heightmap_generate(module, map_file, &map_data) != 0) { return; } if (liext_heightmap_generate(module, tiles_file, &tiles_data) != 0) { liext_heightmap_cleanup(module, &map_data); return; } /* Calculate the size of the area. */ size[0] = sizev.x; size[1] = sizev.y; size[2] = sizev.z; min[0] = posv.x; min[1] = posv.y; min[2] = posv.z; max[0] = (int)posv.x + size[0]; max[1] = (int)posv.y + size[1]; max[2] = (int)posv.z + size[2]; printf("Coords: %d %d %d / %d %d %d / %d %d %d\n", min[0], min[1], min[2], max[0], max[1], max[2], size[0], size[1], size[2]); /* Batch copy terrain data. */ /* Reading all tiles at once is faster than operating on individual tiles since there are fewer sector lookups. */ tmp = lisys_calloc (size[0] * size[1] * size[2], sizeof (LIVoxVoxel)); if (tmp == NULL) { liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); return; } livox_manager_copy_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); /* Apply heightmap to the copied tiles. */ i = 0; for (z = min[2] ; z < max[2] ; z++) for (y = min[1] ; y < max[1] ; y++) for (x = min[0] ; x < max[0] ; x++) { //TODO: better resolution y2 = 255 - liext_heightmap_find(module, x, z, map_data); printf("gen y: %d\n", y2); if (y2 != -1 && y <= y2) { value = liext_heightmap_find(module, x, z, tiles_data); if (value < 0 || value >= MAX_TEXTURES) { value = 0; } livox_voxel_init (tmp + i, 15 /* materials[value] */); printf("voxel: %d %d\n", i, value); } i++; } /* Batch write the copied tiles. */ livox_manager_paste_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); lisys_free (tmp); printf("Area has been successfully loaded from heightmap\n"); liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); }