static void Terrain_cast_ray (LIScrArgs* args) { int grid_x; int grid_z; float fraction; LIMatVector src; LIMatVector dst; LIMatVector point; LIMatVector normal; /* Get the arguments. */ if (!liscr_args_geti_vector (args, 0, &src)) return; if (!liscr_args_geti_vector (args, 1, &dst)) return; if (!liext_terrain_intersect_ray (args->self, &src, &dst, &grid_x, &grid_z, &point, &normal, &fraction)) return; liscr_args_seti_int (args, grid_x); liscr_args_seti_int (args, grid_z); liscr_args_seti_float (args, point.x); liscr_args_seti_float (args, point.y); liscr_args_seti_float (args, point.z); liscr_args_seti_float (args, normal.x); liscr_args_seti_float (args, normal.y); liscr_args_seti_float (args, normal.z); }
static void Terrain_cast_sphere (LIScrArgs* args) { float radius; LIExtTerrain* self; LIMatVector src; LIMatVector dst; LIExtTerrainCollision result; /* Get the arguments. */ self = args->self; if (!liscr_args_geti_vector (args, 0, &src)) return; if (!liscr_args_geti_vector (args, 1, &dst)) return; if (!liscr_args_geti_float (args, 2, &radius)) return; if (radius <= LIMAT_EPSILON) return; /* Convert into grid coordinates. */ src.x /= self->grid_size; src.z /= self->grid_size; dst.x /= self->grid_size; dst.z /= self->grid_size; radius /= self->grid_size; /* Cast the sphere. */ if (!liext_terrain_cast_sphere (self, &src, &dst, radius, &result)) return; liscr_args_seti_float (args, result.fraction); }
static void Widget_set_offset (LIScrArgs* args) { LIMatVector value; if (liscr_args_geti_vector (args, 0, &value)) liwdg_widget_set_offset (args->self, (int) value.x, (int) value.y); }
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 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 Camera_set_target_position (LIScrArgs* args) { LIExtCamera* camera; LIMatTransform transform; camera = args->self; transform = limat_transform_identity (); liext_camera_get_center (camera, &transform); liscr_args_geti_vector (args, 0, &transform.position); liext_camera_set_center (camera, &transform); }
static void Sound_set_listener_position (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_position = value; } }
static void Widget_set_request (LIScrArgs* args) { int internal = 0; int paddings[4]; const char* text; const char* font_name; LIMatVector vector; LIWdgSize size = { -1, -1 }; LIWdgSize size_tmp; LIWdgWidget* widget; widget = args->self; liscr_args_gets_bool (args, "internal", &internal); if (liscr_args_geti_vector (args, 0, &vector)) { size.width = (int) vector.x; size.height = (int) vector.y; } else { if (!liscr_args_geti_int (args, 0, &size.width)) liscr_args_gets_int (args, "width", &size.width); if (!liscr_args_geti_int (args, 1, &size.width)) liscr_args_gets_int (args, "height", &size.height); } /* Calculate from text if given. */ if (liscr_args_gets_string (args, "font", &font_name) && liscr_args_gets_string (args, "text", &text)) { if (liren_render_measure_text (widget->manager->render, font_name, text, size.width, &size_tmp.width, &size_tmp.height)) { if (size.width == -1) size.width = size_tmp.width; if (size.height == -1) size.height = size_tmp.height; } } /* Add paddings if given. */ if (liscr_args_gets_intv (args, "paddings", 4, paddings) == 4) { size.width += paddings[1] + paddings[2]; size.height += paddings[0] + paddings[3]; } /* Set the request. */ if (internal) liwdg_widget_set_request (args->self, 1, size.width, size.height); else liwdg_widget_set_request (args->self, 2, size.width, size.height); }
static void Heightmap_get_height (LIScrArgs* args) { int clamp = 1; float height; LIMatVector vector; if (!liscr_args_geti_vector (args, 0, &vector)) return; liscr_args_geti_bool (args, 1, &clamp); if (liext_heightmap_get_height (args->self, vector.x, vector.z, clamp, &height)) liscr_args_seti_float (args, height); }
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 Camera_calculate_3rd_person_transform (LIScrArgs* args) { float distance; LIMatTransform center; LIMatTransform result; if (!liscr_args_geti_vector (args, 0, ¢er.position)) return; if (!liscr_args_geti_quaternion (args, 1, ¢er.rotation)) return; if (!liscr_args_geti_float (args, 2, &distance)) return; liext_camera_calculate_3rd_person_transform ( args->self, ¢er, distance, &result); liscr_args_seti_vector (args, &result.position); liscr_args_seti_quaternion (args, &result.rotation); }
static void Camera_calculate_smoothed_transform (LIScrArgs* args) { float position_smoothing = 1.0f; float rotation_smoothing = 1.0f; LIMatTransform target; LIMatTransform result; if (!liscr_args_geti_vector (args, 0, &target.position)) return; if (!liscr_args_geti_quaternion (args, 1, &target.rotation)) return; liscr_args_geti_float (args, 2, &position_smoothing); liscr_args_geti_float (args, 3, &rotation_smoothing); liext_camera_calculate_smoothed_transform ( args->self, &target, position_smoothing, rotation_smoothing, &result); liscr_args_seti_vector (args, &result.position); liscr_args_seti_quaternion (args, &result.rotation); }
static void Camera_calculate_3rd_person_clipped_distance (LIScrArgs* args) { int group = 0xFFFF; int mask = 0xFFFF; float distance; float radius; float result; LIMatTransform center; if (!liscr_args_geti_vector (args, 0, ¢er.position)) return; if (!liscr_args_geti_quaternion (args, 1, ¢er.rotation)) return; if (!liscr_args_geti_float (args, 2, &distance)) return; if (!liscr_args_geti_float (args, 3, &radius)) radius = 0.0f; liscr_args_geti_int (args, 4, &group); liscr_args_geti_int (args, 5, &mask); result = liext_camera_calculate_3rd_person_clipped_distance ( args->self, ¢er, distance, radius, group, mask); liscr_args_seti_float (args, result); }
/** 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); }