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 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 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 Animation_set_transform (LIScrArgs* args) { int frame = 0; float scale = 1.0f; const char* node = NULL; LIMatTransform transform; LIMdlAnimation* self; self = args->self; /* Get arguments. */ if (liscr_args_gets_int (args, "frame", &frame)) { frame--; if (frame < 0) return; } if (!liscr_args_gets_string (args, "node", &node)) return; transform = limat_transform_identity (); liscr_args_gets_quaternion (args, "rotation", &transform.rotation); liscr_args_gets_vector (args, "position", &transform.position); liscr_args_gets_float (args, "scale", &scale); transform.rotation = limat_quaternion_normalize (transform.rotation); /* Create the channel and frame. */ if (!limdl_animation_insert_channel (self, node)) return; if (limdl_animation_get_length (self) <= frame) { if (!limdl_animation_set_length (self, frame + 1)) return; } /* Set the node transformation of the frame. */ limdl_animation_set_transform (self, node, frame, scale, &transform); }
static void Camera_picking_ray (LIScrArgs* args) { float fardist = 50.0f; float neardist = 0.0f; LIMatVector cursor; LIMatVector dir; LIMatVector ray0; LIMatVector ray1; LIExtCamera* self = args->self; /* Handle arguments. */ liscr_args_gets_float (args, "far", &fardist); liscr_args_gets_float (args, "near", &neardist); if (!liscr_args_gets_vector (args, "cursor", &cursor)) { cursor.x = self->view.viewport[0] + self->view.viewport[2] / 2.0f; cursor.y = self->view.viewport[1] + self->view.viewport[3] / 2.0f; } else cursor.y = self->view.viewport[3] - cursor.y - 1; /* Calculate ray vector. */ cursor.z = 0.0f; if (!liext_camera_unproject (self, &cursor, &ray0)) return; cursor.z = 1.0f; if (!liext_camera_unproject (self, &cursor, &ray1)) return; dir = limat_vector_subtract (ray1, ray0); dir = limat_vector_normalize (dir); /* Apply near and far distances specified by the user. */ ray1 = limat_vector_add (ray0, limat_vector_multiply (dir, fardist)); ray0 = limat_vector_add (ray0, limat_vector_multiply (dir, neardist)); liscr_args_seti_vector (args, &ray0); liscr_args_seti_vector (args, &ray1); }
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 }
/** 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); }
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); }
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); }