本帖最后由 君悦 于 2021-3-24 19:40 编辑
简单来说就是绘制下面这张图的优化
我绘制的源码前身是领军者1.439版本里的世界地图,下面这个帖子是相关的介绍,不过里面代码较老了
实现以世界行政区划图来显示的大地图。提升执行效率,边界粗细有别
R大版本里绘制的图形载入速率较慢,要想达到我上传图片的精细度可能要2-3分钟的时间, 而我优化后的代码几乎是瞬间绘制完成
1. 载入时间长
原因: 计算量过大. R大代码中以像素点为单位创建mesh_overlay填充图形, 在高精细度下分辨率为216*300=64800. 即有64800个点要绘制.
每个点都要至少调用一次get_closest_center, 陆地上的点还要调用3次get_closest_center. 而get_closest_center通过遍历所有center来计算最近点.
我使用的领军者版本中大约有260个center. 即每次调用都需要260次计算. 以陆地面积占80%来计算, 那么总的计算量就是 64800*260*(3*0.8+0.2)=4.3*10^7次. 这个级别的运算量对骑砍而言是非常吃力了
骑砍里想要达到流畅运算. 10^6这个级别的计算量几乎就是上限了. 而4.3*10^7超出上限10倍还多. 载入时间长也就不难理解了
2. fps低 创建的overlay太多了.渲染吃力 |
先概述一下我的优化方案.
1. 使用线段为单位填充图形.
2. 提前计算图形数据并存储起来, 载入时不再需要计算最近点, 直接读取即可
3. (可选)优化get_closest_center, 加快获取最近center的速度(即最近邻问题)
下面细说
1.使用线段为单位填充图形.
也即把相同色块的点聚集起来, 形成一个矩形, 减少创建的overlay量
例如有5个色块, 并非创建5个overlay填上去, 而是创建一个overlay. 并把长度设为5个像素
红 红 红 红 红 ---> 红-----------
2. 提前计算图形数据并存储起来, 载入时不再需要计算最近点, 直接读取即可
很简单, 就是预计算每个点的最近center, 存到一个数组里面. 需要的时候直接取就好了.
但是要计算的点很多, 计算耗时长. 直接存储也很耗费空间.
我把计算量摊开. 每次只计算k行的数据. 每隔一定的时间间隔计算一次, 即可在玩家感知不到的情况下完成整幅地图的计算.
然后我使用RLE压缩算法(Run Length Encoding)和zigzag压缩算法对数据进行压缩存储. 大大减少的耗费的空间.
对于原版中的64800个点的绘制. 只使用了2000个slot来存储数据.
3. 低纬度下最简单易实现的就是kd树了. 可以把n个点的计算量减少到log(n)级别.
但是由于ms的限制. log(n)前面的系数较大, 而点数不多, 只有200多个. 所以优化并不明显. 计算量大概减少了30%左右.
具体的算法我就不说了. 可以网上查资料, 懂的都能懂, 不能懂的说了也没用
|
源码部分:
我的核心代码使用了四个数组, 都是troop
trp_World_Map
trp_sys_temp_array_0
trp_sys_temp_array_1
trp_sys_temp_array_2
而R大的代码用了另外的五个数组
trp_temp_array_a
trp_temp_array_b
trp_temp_array_c
trp_temp_array_d
trp_temp_array_e
添加对应的troop_id即可
使用示例:
(call_script,"script_Init_World_Map_data","trp_World_Map"),
(try_for_range,":unused",0,1000),#这一步可以放到一个触发器里, 分摊压力
(call_script,"script_Compress_World_Map","trp_World_Map"),
(try_end),
(troop_get_slot,reg0,"trp_World_Map",9),
(display_message,"@total slots:{reg0}"),
- # Compress the values in the [begin,end) range of the source_array
- # into the target array. The compressed data start from traget_begin slot.
- # Value at the "end" slot is not included
- # return reg0: the num of pairs
- # each pair contain two value (length,value)
- # example input array:|1|1|1|1|2|2|2|
- # example output target array:|4|1|3|2|
- # and return value reg0=2 means there are two pairs
- ("RLE_compress",
- [
- (store_script_param,":source_array",1),
- (store_script_param,":begin",2),
- (store_script_param,":end",3),
- (store_script_param,":target",4),
- (store_script_param,":target_begin",5),
- (assign,":cur_target_slot",":target_begin"),
- #init state
- (troop_get_slot,":pre_val",":source_array",":begin"),
- (assign,":pre_slot",":begin"),
- (val_add,":begin",1),
- (try_for_range,":cur_slot",":begin",":end"),
- (troop_get_slot,":cur_val",":source_array",":cur_slot"),
- (neq,":cur_val",":pre_val"),
- (store_sub,":dx",":cur_slot",":pre_slot"),
- (troop_set_slot,":target",":cur_target_slot",":dx"),
- (val_add,":cur_target_slot",1),
- (troop_set_slot,":target",":cur_target_slot",":pre_val"),
- (val_add,":cur_target_slot",1),
- #update state
- (assign,":pre_val",":cur_val"),
- (assign,":pre_slot",":cur_slot"),
- (try_end),
- (store_sub,":dx",":end",":pre_slot"),
- (troop_set_slot,":target",":cur_target_slot",":dx"),
- (val_add,":cur_target_slot",1),
- (troop_set_slot,":target",":cur_target_slot",":pre_val"),
- (val_add,":cur_target_slot",1),
- (store_sub,reg0,":cur_target_slot",":target_begin"),
- (val_div,reg0,2),
- ]),
- # read "num" values starting from the "source_begin" slot in source_array.
- #
- # return reg0: the end slot of target array,
- # which is the next slot to the meaningful slot.
- ("RLE_uncompress",
- [
- (store_script_param,":source_array",1),
- (store_script_param,":source_begin",2),
- (store_script_param,":num",3),
- (store_script_param,":target",4),
- (store_script_param,":target_begin",5),
- (assign,":cur_target_slot",":target_begin"),
- (assign,":cur_source_slot",":source_begin"),
- (try_for_range,":unused_cur_node",0,":num"),
- (troop_get_slot,":dx",":source_array",":cur_source_slot"),
- (val_add,":cur_source_slot",1),
- (troop_get_slot,":val",":source_array",":cur_source_slot"),
- (val_add,":cur_source_slot",1),
- (store_add,":next_target_slot",":cur_target_slot",":dx"),
- (try_for_range,":slot",":cur_target_slot",":next_target_slot"),
- (troop_set_slot,":target",":slot",":val"),
- (try_end),
- (assign,":cur_target_slot",":next_target_slot"),
- (try_end),
- (assign,reg0,":cur_target_slot"),
- ]),
- ("xor",
- [
- (store_script_param,":A",1),
- (store_script_param,":B",2),
- (assign,reg0,":A"),
- (val_or,reg0,":B"),
- (val_and,":A",":B"),
- (val_mul,":A",-1),
- (val_sub,":A",1),
- (val_and,reg0,":A"),
- ]),
- #inner turn long to zigzag value
- ("long_to_zigzag",
- [
- (store_script_param,":long",1),
- (assign,reg0,":long"),
- (val_lshift,reg0,1),
- (val_rshift,":long",63),
- (call_script,"script_xor",reg0,":long"),
- ]),
- #inner turn ziazag value to long
- ("zigzag_to_long",
- [
- (store_script_param,":zipzag",1),
- (assign,reg0,":zipzag"),
- (val_rshift,reg0,1),
- (assign,":t0",1),
- (val_lshift,":t0",63),
- (val_sub,":t0",1),#0111111111
- (val_and,reg0,":t0"),
- (val_and,":zipzag",1),
- (try_begin),
- (eq,":zipzag",1),
- (val_mul,reg0,-1),
- (val_sub,reg0,1),
- (try_end),
- ]),
- # Compress the values in the [begin,end) range of the source_array
- # into the target array. The compressed data start from traget_begin slot.
- # Value at the "end" slot is not included
- # return reg0: the end slot of the target array,
- # which is the next slot to the meaningful slot.
- ("zigzag_compress",
- [
- (store_script_param,":source_array",1),
- (store_script_param,":begin",2),
- (store_script_param,":end",3),
- (store_script_param,":target",4),
- (store_script_param,":target_begin",5),
- (assign,":counter",0),
- (assign,":zip_v",0),
- (assign,":cur_target_slot",":target_begin"),
- (try_for_range,":v_slot",":begin",":end"),
- (troop_get_slot,reg0,":source_array",":v_slot"),
- (call_script,"script_long_to_zigzag",reg0),
- (assign,":zz",reg0),
- (assign,":size",10),
- (try_for_range,":unused",0,":size"),
- (try_begin),
- (assign,":tmp",":zz"),
- (val_and,":tmp",-128),
- (eq,":tmp",0),
- (assign,":slice",":zz"),
- (store_mul,":pos",":counter",8),
- (val_lshift,":slice",":pos"),
- (val_or,":zip_v",":slice"),
-
- (val_add,":counter",1),
- (val_mod,":counter",8),
- (try_begin),
- (eq,":counter",0),
- (troop_set_slot,":target",":cur_target_slot",":zip_v"),
- (assign,":zip_v",0),
- (val_add,":cur_target_slot",1),
- (try_end),
- (assign,":size",0),#break
- (else_try),
- (assign,":slice",":zz"),
- (val_and,":slice",0x7f),
- (val_or,":slice",0x80),
- (store_mul,":pos",":counter",8),
- (val_lshift,":slice",":pos"),
- (val_or,":zip_v",":slice"),
-
- (val_add,":counter",1),
- (val_mod,":counter",8),
- (try_begin),
- (eq,":counter",0),
- (troop_set_slot,":target",":cur_target_slot",":zip_v"),
- (assign,":zip_v",0),
- (val_add,":cur_target_slot",1),
- (try_end),
- (val_rshift,":zz",7),
- (lt,":zz",0),
- (assign,":tmp",1),
- (val_lshift,":tmp",58),
- (val_sub,":tmp",1),
- (val_and,":zz",":tmp"),
- (try_end),
- (try_end),
- (try_end),
- (try_begin),
- (neq,":counter",0),
- (troop_set_slot,":target",":cur_target_slot",":zip_v"),
- (val_add,":cur_target_slot",1),
- (try_end),
- #(store_sub,reg0,":cur_target_slot",":target_begin"),
- (assign,reg0,":cur_target_slot"),
- ]),
- # read "num" values from source_array's "begin" slot.
- # return reg0: the end slot of source array,
- # which is the next slot to the meaningful slot.
- ("zigzag_uncompress",
- [
- (store_script_param,":source_array",1),
- (store_script_param,":begin",2),
- (store_script_param,":num",3),
- (store_script_param,":target",4),
- (store_script_param,":target_begin",5),
- (assign,":counter",0),
- (assign,":cur_source_slot",":begin"),
- (store_add,":target_end",":target_begin",":num"),
- (try_for_range,":cur_target_slot",":target_begin",":target_end"),
- (assign,":offset",0),
- (assign,":ret",0),
- (assign,":size",10),
- (try_for_range,":unused",0,":size"),
- (try_begin),
- (eq,":counter",0),
- (troop_get_slot,":zip_v",":source_array",":cur_source_slot"),
- (val_add,":cur_source_slot",1),
- (try_end),
- #get byte
- (assign,":n",0xff),
- (val_and,":n",":zip_v"),
- (val_rshift,":zip_v",8),
- (val_add,":counter",1),
- (val_mod,":counter",8),
- (try_begin),
- (lt,":n",128),
- (val_lshift,":n",":offset"),
- (val_or,":ret",":n"),
- (call_script,"script_zigzag_to_long",":ret"),
- (troop_set_slot,":target",":cur_target_slot",reg0),
- (assign,":size",0),
- (else_try),
- (val_and,":n",0x7f),
- (val_lshift,":n",":offset"),
- (val_or,":ret",":n"),
- (try_end),
- (val_add,":offset",7),
- (try_end),
- (try_end),
- (assign,reg0,":cur_source_slot"),
- ]),
- # Initialize the state values of the "array" that stores world map data.
- # we discrete the world map into a x_pixels X y_pixels picture
- # and create a mapping from the world map to this picture.
- # We store the 2D map in 1D format.
- # i.e
- # |1|2|3|
- # |4|5|6| was stored in the format as |1|2|3|4|5|6|7|8|9| (before compressed)
- # |7|8|9|
- # We still need to store some state values to descript how this work,
- # so I set aside the first 9 values of the array to store them.
- ("Init_World_Map_data",
- [
- (store_script_param,":array",1),
- (set_fixed_point_multiplier,1000),
- (assign,":map_precision",1),
- (assign, ":min_map_x", -180*1000),
- (assign, ":max_map_x", 180*1000),
- (assign, ":min_map_y", -120*1000),
- (assign, ":max_map_y", 140*1000),
- (store_mul, ":party_move_length", 0.4*1000, ":map_precision"),
- (store_sub, ":x_pixels", ":max_map_x", ":min_map_x"),
- (store_sub, ":y_pixels", ":max_map_y", ":min_map_y"),
- (val_div, ":x_pixels", ":party_move_length"),
- (val_div, ":y_pixels", ":party_move_length"),
- (assign, ":init_map_x", ":min_map_x"), # init map_x
- (assign, ":init_map_y", ":max_map_y"), # init map_y
- #the fixed_point value used in world map.
- (troop_set_slot,":array",0,1000),
- #initial map_x
- (troop_set_slot,":array",1,":init_map_x"),
- #initial map_y
- (troop_set_slot,":array",2,":init_map_y"),
- # plotting scale
- # The length of one pixel on the picture to the
- # actual length on the world map
- (troop_set_slot,":array",3,":party_move_length"),
- # Total x pixels
- (troop_set_slot,":array",4,":x_pixels"),
- # Total y pixels
- (troop_set_slot,":array",5,":y_pixels"),
- # To increase the efficiency of zigzag compression and save space
- # We don't store the closest center directly but the offset from the center_base.
- # For example, if the closest center's id is 120 and the center_base's value is 125,
- # we actually store -5=120-125 instead of 120.
- (store_add,":center_base",centers_begin,centers_end),
- (val_div,":center_base",2),
- (troop_set_slot,":array",6,":center_base"),
- # data start slot. where the data start to store.
- (assign,":data_start_slot",10),
- (troop_set_slot,":array",7,":data_start_slot"),
- # We calculate the data one row at a time.
- # This is the next y-th row value to be calculated.
- (troop_set_slot,":array",8,0),
- # cur data begin slot. Used for loop procedures
- (troop_set_slot,":array",9,":data_start_slot"),
- ]),
- # Each call to this script evaluates one row data.
- # If this script is called again after the evaluation is complete, nothing will be changed.
- # This script won't change fixed_point value.
- ("Compress_World_Map",
- [
- (store_script_param,":array",1),
- # get state
- # see detail description at script_Init_World_Map_data
- (troop_get_slot,":fixed_point",":array",0),
- (troop_get_slot,":init_map_x",":array",1),
- (troop_get_slot,":init_map_y",":array",2),
- (troop_get_slot,":party_move_length",":array",3),
- (troop_get_slot,":x_pixels",":array",4),
- (troop_get_slot,":y_pixels",":array",5),
- (troop_get_slot,":centers_base",":array",6),
- #(troop_get_slot,":data_start_slot",":array",7),# we don't need it here.
- (troop_get_slot,":cur_y",":array",8),
- (troop_get_slot,":cur_data_begin_slot",":array",9),
- (try_begin),
- (neq,":cur_y",":y_pixels"),#not done
- #save previous fixed_point value.
- (assign,":pre_fixed_point",1),
- (convert_to_fixed_point,":pre_fixed_point"),
- (set_fixed_point_multiplier,":fixed_point"),
- (assign,":map_x",":init_map_x"),
- (store_mul,":map_y",":party_move_length",":cur_y"),
- (store_sub,":map_y",":init_map_y",":map_y"),
-
- (position_set_y,pos1,":map_y"),
- #Gets y-th row's closest center of each column and store them in trp_sys_temp_array_0
- (try_for_range,":cur_col",0,":x_pixels"),
- (position_set_x,pos1,":map_x"),
- (party_set_position, "p_temp_party", pos1),
- (party_get_current_terrain, ":current_terrain", "p_temp_party"),
- (try_begin),
- (this_or_next|eq, ":current_terrain", rt_water),
- (eq, ":current_terrain", rt_river),
- (assign,":cur_closest_center",-1),
- (else_try),
- (call_script, "script_get_closest_center", "p_temp_party"),
- (assign,":cur_closest_center",reg0),
- (try_end),
- (val_sub,":cur_closest_center",":centers_base"),
- (troop_set_slot,"trp_sys_temp_array_0",":cur_col",":cur_closest_center"),
- (val_add, ":map_x", ":party_move_length"),
- (try_end),
- # Compress the values in the [0,x_pixels) range of the trp_sys_temp_array_0
- # into the trp_sys_temp_array_1 array. The first value starts at 0.
- (call_script,"script_RLE_compress","trp_sys_temp_array_0",0,":x_pixels","trp_sys_temp_array_1",0),
- (assign,":RLE_pairs_num",reg0),
- # (display_message,"@RLE_pairs_num:{reg0}"), for debug
- # Compressed data format for each row:
- #[num_pairs,zigzag_data...,num_pairs,zigzag_data...]
- (troop_set_slot,":array",":cur_data_begin_slot",":RLE_pairs_num"),
- (val_add,":cur_data_begin_slot",1),
- (store_mul,":end_slot",":RLE_pairs_num",2),
- # Compress the values in the [0,RLE_pairs_num*2) range of trp_sys_temp_array_1
- # into the "array". The first value starts at cur_data_begin_slot
- (call_script,"script_zigzag_compress","trp_sys_temp_array_1",0,":end_slot",":array",":cur_data_begin_slot"),
- # the next slot to store data
- (assign,":cur_data_begin_slot",reg0),
- # update state
- (val_add,":cur_y",1),
- (troop_set_slot,":array",8,":cur_y"),
- (troop_set_slot,":array",9,":cur_data_begin_slot"),
- #restore fixed_point value
- (set_fixed_point_multiplier,":pre_fixed_point"),
- (try_end),
- ]),
复制代码 |
- ("world_map2", 0, mesh_load_window, [
- (ti_on_presentation_load,
- [
- (presentation_set_duration, 999999),
- (set_fixed_point_multiplier, 1000),
- ## initialization part begin
- # presentation obj: begin from top left corner
- (assign, ":init_pos_x", 20), # init x
- (assign, ":init_pos_y", 720), # init y
-
- # color_block_length
- (assign, ":color_block_length", 1),
- (store_mul, ":color_block_size", ":color_block_length", 50),
- (position_set_x, pos2, ":color_block_size"),
- (position_set_y, pos2, ":color_block_size"),
-
- # borderlines length and width
- (assign, ":line_width_1", 1*50), # 1 pixel width
- (assign, ":line_width_2", 2*50), # 2 pixels width
- ## initialization part end
- #(troop_get_slot,":fixed_point","trp_World_Map",0),
- (troop_get_slot,":init_map_x","trp_World_Map",1),
- (troop_get_slot,":init_map_y","trp_World_Map",2),
- (troop_get_slot,":party_move_length","trp_World_Map",3),
- (troop_get_slot,":total_cols","trp_World_Map",4),
- (troop_get_slot,":total_rows","trp_World_Map",5),
- (troop_get_slot,":centers_base","trp_World_Map",6),
- (troop_get_slot,":data_start_slot","trp_World_Map",7),
- # background
- (create_mesh_overlay, reg0, "mesh_map_frame_h"),
- (position_set_x, pos1, 17),
- (position_set_y, pos1, 72),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 3020),
- (position_set_y, pos1, 1000),
- (overlay_set_size, reg0, pos1),
-
- (create_mesh_overlay, reg0, "mesh_map_frame_h"),
- (position_set_x, pos1, 17),
- (position_set_y, pos1, 721),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 3020),
- (position_set_y, pos1, 1000),
- (overlay_set_size, reg0, pos1),
-
- (create_mesh_overlay, reg0, "mesh_map_frame_v"),
- (position_set_x, pos1, 17),
- (position_set_y, pos1, 75),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 1000),
- (position_set_y, pos1, 2160),
- (overlay_set_size, reg0, pos1),
-
- (create_mesh_overlay, reg0, "mesh_map_frame_v"),
- (position_set_x, pos1, 918),
- (position_set_y, pos1, 75),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 1000),
- (position_set_y, pos1, 2160),
- (overlay_set_size, reg0, pos1),
-
- # a large white block
- (create_mesh_overlay, reg0, "mesh_white_plane"),
- (overlay_set_color, reg0, 0xFFFFFF),
- (assign, ":bg_x", ":init_pos_x"),
- (store_add, ":bg_y", ":init_pos_y", ":color_block_length"),
- (position_set_x, pos1, ":bg_x"),
- (position_set_y, pos1, ":bg_y"),
- (overlay_set_position, reg0, pos1),
- (store_mul, ":bg_size_x", ":total_cols", ":color_block_length"),
- (val_mul, ":bg_size_x", 50),
- (store_mul, ":bg_size_y", ":total_rows", ":color_block_length"),
- (val_mul, ":bg_size_y", -50),
- (position_set_x, pos1, ":bg_size_x"),
- (position_set_y, pos1, ":bg_size_y"),
- (overlay_set_size, reg0, pos1),
-
- (assign, ":pos_x", ":init_pos_x"), # assign to cur pos_x
- (assign, ":pos_y", ":init_pos_y"), # assign to cur pos_y
- (assign,":cur_array","trp_sys_temp_array_1"),
- (assign,":pre_array","trp_sys_temp_array_2"),
- #--for debug
- # (assign,":total_rows",2),
- #draw map
- (try_for_range, ":cur_row", 0, ":total_rows"),
- #data_start_slot: The starting position of the data to be decompressed
- (troop_get_slot,":RLE_pairs_num","trp_World_Map",":data_start_slot"),
- (store_mul,":val_num",":RLE_pairs_num",2),
- (val_add,":data_start_slot",1),
- #uncompress data to cur_array
- (call_script,"script_zigzag_uncompress","trp_World_Map",":data_start_slot",":val_num",":cur_array",0),
- (assign,":data_start_slot",reg0),
- #draw overlay
- (try_for_range,":i",0,":RLE_pairs_num"),
- #parser RLE_pair
- (store_mul,":dx_index",":i",2),
- (store_add,":center_index",":dx_index",1),
- (troop_get_slot,":dx",":cur_array",":dx_index"),
- (troop_get_slot,":cur_center",":cur_array",":center_index"),
- (val_add,":cur_center",":centers_base"),
- #Determine the color
- (assign, ":dest_color", 0xFFFFFF), # default
- (try_begin),
- (eq,":cur_center",-1),#water river
- (else_try),
- (store_faction_of_party,":cur_center_faction",":cur_center"),
- (is_between,":cur_center_faction",kingdoms_begin,kingdoms_end),
- (faction_get_color,":dest_color",":cur_center_faction"),
- (try_end),
- (create_mesh_overlay,reg0,"mesh_white_plane"),
- (overlay_set_color,reg0,":dest_color"),
- (position_set_x,pos1,":pos_x"),
- (position_set_y,pos1,":pos_y"),
- (overlay_set_position,reg0,pos1),
- (store_mul,":x_size",":color_block_size",":dx"),#color_block_size:color_block_length*50
- (position_set_x,pos2,":x_size"),
- (position_set_y, pos2, ":color_block_size"),
- (overlay_set_size,reg0,pos2),
- #draw x boundary line
- (try_begin),
- # get previous center
- (val_sub,":center_index",2),
- (gt,":center_index",-1),
- (assign,":draw",1),
- (troop_get_slot,":pre_center",":cur_array",":center_index"),
- (val_add,":pre_center",":centers_base"),
-
- (assign,":x_size",":line_width_1"),
- (try_begin),
- (gt,":pre_center",-1),#not water or river
- (gt,":cur_center",-1),#not water or river
- (store_faction_of_party,":pre_center_faction",":pre_center"),
- (try_begin),
- # national boundary line
- (neq,":pre_center_faction",":cur_center_faction"),
- (assign,":x_size",":line_width_2"),
- (else_try),
- (assign,":cur_bound_center",":cur_center"),
- (try_begin),
- (party_slot_eq,":cur_center",slot_party_type,spt_village),
- (party_get_slot,":cur_bound_center",":cur_center",slot_village_bound_center),
- (try_end),
- (assign,":pre_bound_center",":pre_center"),
- (try_begin),
- (party_slot_eq,":pre_center",slot_party_type,spt_village),
- (party_get_slot,":pre_bound_center",":pre_center",slot_village_bound_center),
- (try_end),
- (eq,":pre_bound_center",":cur_bound_center"),
- (assign,":draw",0),
- (try_end),
- (try_end),
- (eq,":draw",1),
- (create_mesh_overlay,reg0,"mesh_white_plane"),
- (overlay_set_color,reg0,0),
- (overlay_set_position,reg0,pos1),
- (position_set_x,pos2,":x_size"),
- (position_set_y, pos2, ":color_block_size"),
- (overlay_set_size,reg0,pos2),
- (try_end),
- (store_mul,reg0,":dx",":color_block_length"),
- (val_add,":pos_x",reg0),
- (try_end),
- #draw y boundary line
- (try_begin),
- (gt,":cur_row",0),
- (assign,":end",1),#used to control while loop
- (assign,":remain_size",":total_cols"),
- (assign,":dpre",0),
- (assign,":dcur",0),
- (assign,":index_pre",0),
- (assign,":index_cur",0),
- (assign,":pos_x",":init_pos_x"),
- (else_try),
- (assign,":end",-1),
- (try_end),
- # when cur line pixels are different from pre line pixels, we add a boundary line
- # pre line pixels: |1|1|1|1|2|2|2|3|3|3|->|2|2|2|3|3|3|->|3|3|3|->done
- # cur line pixels: |2|2|2|2|2|2|2|2|2|2|->|2|2|2|2|2|2|->|2|2|2|
- #while loop
- (try_for_range,":unused",0,":end"),
- (val_add,":end",1),
- (try_begin),
- (eq,":dpre",0),
- (troop_get_slot,":dpre",":pre_array",":index_pre"),
- (val_add,":index_pre",1),
- (troop_get_slot,":pre_center",":pre_array",":index_pre"),
- (val_add,":pre_center",":centers_base"),
- (val_add,":index_pre",1),
- (try_end),
- (try_begin),
- (eq,":dcur",0),
- (troop_get_slot,":dcur",":cur_array",":index_cur"),
- (val_add,":index_cur",1),
- (troop_get_slot,":cur_center",":cur_array",":index_cur"),
- (val_add,":cur_center",":centers_base"),
- (val_add,":index_cur",1),
- (try_end),
- (assign,":minimum",":dpre"),
- (val_min,":minimum",":dcur"),
- (val_sub,":remain_size",":minimum"),
- (val_sub,":dpre",":minimum"),
- (val_sub,":dcur",":minimum"),
- (try_begin),
- (neq,":cur_center",":pre_center"),
- (assign,":draw",1),
- (assign,":y_size",":line_width_1"),
- (try_begin),
- (gt,":pre_center",-1),#not river or water
- (gt,":cur_center",-1),#not river or water
- (store_faction_of_party,":pre_center_faction",":pre_center"),
- (store_faction_of_party,":cur_center_faction",":cur_center"),
- (try_begin),
- (neq,":pre_center_faction",":cur_center_faction"),
- (assign,":y_size",":line_width_2"),
- (else_try),
- (assign,":cur_bound_center",":cur_center"),
- (try_begin),
- (party_slot_eq,":cur_center",slot_party_type,spt_village),
- (party_get_slot,":cur_bound_center",":cur_center",slot_village_bound_center),
- (try_end),
- (assign,":pre_bound_center",":pre_center"),
- (try_begin),
- (party_slot_eq,":pre_center",slot_party_type,spt_village),
- (party_get_slot,":pre_bound_center",":pre_center",slot_village_bound_center),
- (try_end),
- (eq,":pre_bound_center",":cur_bound_center"),
- (assign,":draw",0),
- (try_end),
- (try_end),
- (eq,":draw",1),
- (create_mesh_overlay,reg0,"mesh_white_plane"),
- (overlay_set_color,reg0,0),
- (position_set_x,pos1,":pos_x"),
- (store_add,":pre_pos_y",":pos_y",":color_block_length"),
- (position_set_y,pos1,":pre_pos_y"),
- (overlay_set_position,reg0,pos1),
- (store_mul,":x_size",":color_block_size",":minimum"),
- (position_set_x,pos2,":x_size"),
- (position_set_y,pos2,":y_size"),
- (overlay_set_size,reg0,pos2),
- (try_end),
- (store_mul,reg0,":minimum",":color_block_length"),
- (val_add,":pos_x",reg0),
- #break condition
- (try_begin),
- (le,":remain_size",0),
- (assign,":end",0),
- (try_end),
- (try_end),
- (assign,":pos_x",":init_pos_x"),
- (val_sub,":pos_y",":color_block_length"),
- #exchange array
- (assign,reg0,":pre_array"),
- (assign,":pre_array",":cur_array"),
- (assign,":cur_array",reg0),
- (try_end),
-
- ## blocks of centers
- (assign, ":slot_no", 0),
- (try_for_range, ":center_no", centers_begin, centers_end),
- (party_is_active, ":center_no"),
- (party_get_position, pos4, ":center_no"),
- (position_get_x, ":center_x", pos4),
- (position_get_y, ":center_y", pos4),
- (val_sub, ":center_x", ":init_map_x"),
- (val_sub, ":center_y", ":init_map_y"),
- (val_mul, ":center_x", ":color_block_length"),
- (val_mul, ":center_y", ":color_block_length"),
- (val_div, ":center_x", ":party_move_length"),
- (val_div, ":center_y", ":party_move_length"),
- (val_add, ":center_x", ":init_pos_x"),
- (val_add, ":center_y", ":init_pos_y"),
- # offset and size
- (try_begin),
- (party_slot_eq, ":center_no", slot_party_type, spt_town),
- (assign, ":block_size", 8),
- (assign, ":center_type", spt_town),
- (else_try),
- (party_slot_eq, ":center_no", slot_party_type, spt_castle),
- (assign, ":block_size", 4),
- (assign, ":center_type", spt_castle),
- (else_try),
- (party_slot_eq, ":center_no", slot_party_type, spt_village),
- (assign, ":block_size", 2),
- (assign, ":center_type", spt_village),
- (try_end),
- (store_div, ":half_block_size", ":block_size", 2),
- (val_sub, ":center_x", ":half_block_size"),
- (val_sub, ":center_y", ":half_block_size"),
- (val_mul, ":block_size", 50),
- # block
- (create_mesh_overlay, reg0, "mesh_white_plane"),
- (overlay_set_color, reg0, 0),
- (position_set_x, pos1, ":center_x"),
- (position_set_y, pos1, ":center_y"),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, ":block_size"),
- (position_set_y, pos1, ":block_size"),
- (overlay_set_size, reg0, pos1),
- # name
- (str_store_party_name, s1, ":center_no"),
- (create_text_overlay, reg1, s1, tf_center_justify),
- (store_add, ":text_x", ":center_x", 0),
- (store_add, ":text_y", ":center_y", 10),
- (position_set_x, pos1, ":text_x"),
- (position_set_y, pos1, ":text_y"),
- (overlay_set_position, reg1, pos1),
- (overlay_set_display, reg1, 0),
- # slots
- (troop_set_slot, "trp_temp_array_a", ":slot_no", reg0), # overlay id
- (troop_set_slot, "trp_temp_array_b", ":slot_no", ":center_type"), # center type
- (troop_set_slot, "trp_temp_array_c", ":slot_no", reg1), # center name
- (val_add, ":slot_no", 1),
- (try_end),
-
- ## blocks of kingdoms
- (create_text_overlay, reg0, "@Factions", tf_vertical_align_center|tf_right_align),
- (position_set_x, pos1, 90),
- (position_set_y, pos1, 43),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 900),
- (position_set_y, pos1, 900),
- (overlay_set_size, reg0, pos1),
-
- (assign, ":slot_no", 0),
- (assign, ":pos_x", 100),
- (assign, ":pos_y", 35),
- (try_for_range, ":cur_kingdom", kingdoms_begin, kingdoms_end),
- (faction_slot_eq, ":cur_kingdom", slot_faction_state, sfs_active),
- # color block
- (create_mesh_overlay, reg0, "mesh_white_plane"),
- (faction_get_color, ":dest_color", ":cur_kingdom"),
- (overlay_set_color, reg0, ":dest_color"),
- (position_set_x, pos1, ":pos_x"),
- (position_set_y, pos1, ":pos_y"),
- (overlay_set_position, reg0, pos1),
- # size: 20*16
- (position_set_x, pos1, 20*50),
- (position_set_y, pos1, 16*50),
- (overlay_set_size, reg0, pos1),
- # kingdom name
- (store_add, ":text_x", ":pos_x", 10),
- (store_add, ":text_y", ":pos_y", 20),
- (str_store_faction_name, s1, ":cur_kingdom"),
- (create_text_overlay, reg1, s1, tf_center_justify),
- (position_set_x, pos1, ":text_x"),
- (position_set_y, pos1, ":text_y"),
- (overlay_set_position, reg1, pos1),
- (position_set_x, pos1, 600),
- (position_set_y, pos1, 600),
- (overlay_set_size, reg1, pos1),
- (overlay_set_display, reg1, 0),
- (troop_set_slot, "trp_temp_array_d", ":slot_no", reg0), # overlay id
- (troop_set_slot, "trp_temp_array_e", ":slot_no", reg1), # faction name
- (val_add, ":pos_x", 30),
- (val_add, ":slot_no", 1),
- (try_end),
-
- ## show centers or not
- # check_boxes
- (position_set_x, pos1, 30),
- # towns
- (create_check_box_overlay, "$g_presentation_obj_admin_panel_1", "mesh_checkbox_off", "mesh_checkbox_on"),
- (position_set_y, pos1, 150),
- (overlay_set_position, "$g_presentation_obj_admin_panel_1", pos1),
- (overlay_set_val, "$g_presentation_obj_admin_panel_1", 1),
- # castles
- (create_check_box_overlay, "$g_presentation_obj_admin_panel_2", "mesh_checkbox_off", "mesh_checkbox_on"),
- (position_set_y, pos1, 120),
- (overlay_set_position, "$g_presentation_obj_admin_panel_2", pos1),
- (overlay_set_val, "$g_presentation_obj_admin_panel_2", 1),
- # villages
- (create_check_box_overlay, "$g_presentation_obj_admin_panel_3", "mesh_checkbox_off", "mesh_checkbox_on"),
- (position_set_y, pos1, 90),
- (overlay_set_position, "$g_presentation_obj_admin_panel_3", pos1),
- (overlay_set_val, "$g_presentation_obj_admin_panel_3", 1),
- # texts
- (position_set_x, pos1, 60),
- (create_text_overlay, reg0, "@Show towns", tf_vertical_align_center),
- (position_set_y, pos1, 160),
- (overlay_set_position, reg0, pos1),
- (create_text_overlay, reg0, "@Show castles", tf_vertical_align_center),
- (position_set_y, pos1, 130),
- (overlay_set_position, reg0, pos1),
- (create_text_overlay, reg0, "@Show villages", tf_vertical_align_center),
- (position_set_y, pos1, 100),
- (overlay_set_position, reg0, pos1),
-
- (create_text_overlay, reg0, "@Tip: move the mouse onto the blocks to show center names or faction names.", tf_vertical_align_center),
- (position_set_x, pos1, 50),
- (position_set_y, pos1, 25),
- (overlay_set_position, reg0, pos1),
- (position_set_x, pos1, 750),
- (position_set_y, pos1, 750),
- (overlay_set_size, reg0, pos1),
-
- # compass
- (create_mesh_overlay, reg0, "mesh_compass"),
- # (display_message,"@total overlays:{reg0}"),
- (position_set_x, pos1, 70),
- (position_set_y, pos1, 670),
- (overlay_set_position, reg0, pos1),
-
- ####### mouse fix pos system #######
- # (call_script, "script_mouse_fix_pos_ready"),
- ####### mouse fix pos system #######
- # Done
- (create_game_button_overlay, "$g_presentation_obj_admin_panel_5", "@Back"),
- (position_set_x, pos1, 900),
- (position_set_y, pos1, 25),
- (overlay_set_position, "$g_presentation_obj_admin_panel_5", pos1),
- ]),
-
- # (ti_on_presentation_run,
- # [
- ## mouse fix pos system #######
- # (call_script, "script_mouse_fix_pos_run"),
- ## mouse fix pos system #######
- # ]),
-
- (ti_on_presentation_mouse_enter_leave,
- [
- (store_trigger_param_1, ":object"),
- (store_trigger_param_2, ":enter_leave"),
-
- (assign, ":num_centers", 0),
- (try_for_range, ":center_no", centers_begin, centers_end),
- (party_is_active, ":center_no"),
- (val_add, ":num_centers", 1),
- (try_end),
- # show center name when mouse on it
- (try_for_range, ":slot_no", 0, ":num_centers"),
- (troop_slot_eq, "trp_temp_array_a", ":slot_no", ":object"),
- (store_sub, ":display_overlay", 1, ":enter_leave"),
- (troop_get_slot, ":cur_overlay", "trp_temp_array_c", ":slot_no"),
- (overlay_set_display, ":cur_overlay", ":display_overlay"),
- (try_end),
-
- (assign, ":num_kingdoms", 0),
- (try_for_range, ":cur_kingdom", kingdoms_begin, kingdoms_end),
- (faction_slot_eq, ":cur_kingdom", slot_faction_state, sfs_active),
- (val_add, ":num_kingdoms", 1),
- (try_end),
- # show faction name when mouse on it
- (try_for_range, ":slot_no", 0, ":num_kingdoms"),
- (troop_slot_eq, "trp_temp_array_d", ":slot_no", ":object"),
- (store_sub, ":display_overlay", 1, ":enter_leave"),
- (troop_get_slot, ":cur_overlay", "trp_temp_array_e", ":slot_no"),
- (overlay_set_display, ":cur_overlay", ":display_overlay"),
- (try_end),
- ]),
-
- (ti_on_presentation_event_state_change,
- [
- (store_trigger_param_1, ":object"),
- (store_trigger_param_2, ":value"),
-
- (assign, ":num_centers", 0),
- (try_for_range, ":center_no", centers_begin, centers_end),
- (party_is_active, ":center_no"),
- (val_add, ":num_centers", 1),
- (try_end),
-
- (try_begin),
- (eq, ":object", "$g_presentation_obj_admin_panel_1"), # show towns
- (try_for_range, ":slot_no", 0, ":num_centers"),
- (troop_slot_eq, "trp_temp_array_b", ":slot_no", spt_town),
- (troop_get_slot, ":cur_overlay", "trp_temp_array_a", ":slot_no"),
- (overlay_set_display, ":cur_overlay", ":value"),
- (try_end),
- (else_try),
- (eq, ":object", "$g_presentation_obj_admin_panel_2"), # show castles
- (try_for_range, ":slot_no", 0, ":num_centers"),
- (troop_slot_eq, "trp_temp_array_b", ":slot_no", spt_castle),
- (troop_get_slot, ":cur_overlay", "trp_temp_array_a", ":slot_no"),
- (overlay_set_display, ":cur_overlay", ":value"),
- (try_end),
- (else_try),
- (eq, ":object", "$g_presentation_obj_admin_panel_3"), # show villages
- (try_for_range, ":slot_no", 0, ":num_centers"),
- (troop_slot_eq, "trp_temp_array_b", ":slot_no", spt_village),
- (troop_get_slot, ":cur_overlay", "trp_temp_array_a", ":slot_no"),
- (overlay_set_display, ":cur_overlay", ":value"),
- (try_end),
- (else_try),
- (eq, ":object", "$g_presentation_obj_admin_panel_5"),
- (presentation_set_duration, 0),
- (try_end),
- ]),
- ]),
复制代码 |
其中需要设置两个常数
KDTreeNodeBufferValueNum=6
KDTreeNodeValueNum=4
用到了额外的两个个专用数组
trp_KDTreeBuffer #构建kd树时使用的临时数组
trp_CenterKDTree #示例中用来来保存kd树结构
使用示例:
构建KD-树
(set_fixed_point_multiplier,1000),
(assign,":count",0),
(try_for_range,":center_no",centers_begin,centers_end),
(troop_set_slot,"trp_CenterKDTree",":count",":center_no"),
(val_add,":count",1),
(try_end),
(call_script,"script_Build_KD_Tree","trp_CenterKDTree",":count","script_GetCoor"),
(display_message,"@KDTree builded"),
(call_script,"script_get_closest_center","p_main_party"),
(str_store_party_name,s0,reg0),
(display_message,"@{s0} {reg0} {reg1} {reg2}"),
KD树构建完成后就可以搜索了
例子:
# script_get_closest_center
# Input: arg1 = party_no
# Output: reg0 = center_no (closest)
("get_closest_center",
[
(store_script_param_1, ":party_no"),
# (assign, ":min_distance", 9999999),
# (assign, reg0, -1),
# (try_for_range, ":center_no", centers_begin, centers_end),
# (store_distance_to_party_from_party, ":party_distance", ":party_no", ":center_no"),
# (lt, ":party_distance", ":min_distance"),
# (assign, ":min_distance", ":party_distance"),
# (assign, reg0, ":center_no"),
# (try_end),
(party_get_position,pos0,":party_no"),
(position_get_x,":point_x",pos0),
(position_get_y,":point_y",pos0),
(call_script,"script_KD_Tree_Nearest_neighbor_Search","trp_CenterKDTree",":point_x",":point_y"),
]),
- ("Get_Positive_Infinity",
- [
- (assign,reg0,1),
- (val_lshift,reg0,63),
- (val_sub,reg0,1),
- ]),
- ("insertion_sort",
- [
- (store_script_param,":array",1),
- (store_script_param,":first",2),
- (store_script_param,":last",3),
- (store_script_param,":cf_cmp_script",4),
- (try_begin),
- (neq,":first",":last"),
- (store_add,":begin",":first",1),
- (try_for_range,":i",":begin",":last"),
- (troop_get_slot,":value",":array",":i"),
- (troop_get_slot,":first_value",":array",":first"),
- (try_begin),
- (call_script,":cf_cmp_script",":value",":first_value"),
- (try_for_range_backwards,":j",":first",":i"),
- (troop_get_slot,":j_value",":array",":j"),
- (val_add,":j",1),
- (troop_set_slot,":array",":j",":j_value"),
- (try_end),
- (troop_set_slot,":array",":first",":value"),
- (else_try),
- (store_sub,":next",":i",1),
- (assign,":end",1),
- (try_for_range,":unused",0,":end"),
- (troop_get_slot,":next_value",":array",":next"),
- (try_begin),
- (call_script,":cf_cmp_script",":value",":next_value"),
- (troop_set_slot,":array",":i",":next_value"),
- (assign,":i",":next"),
- (val_sub,":next",1),
- (else_try),
- (assign,":end",0),
- (try_end),
- (troop_set_slot,":array",":i",":value"),
- (try_end),
- (try_end),
- (try_end),
- (try_end),
- ]),
- ("median_partition",
- [
- (store_script_param,":array",1),
- (store_script_param,":first",2),
- (store_script_param,":last",3),
- (store_script_param,":cf_cmp_script",4),
- #get pivot
- (store_add,":mid",":first",":last"),
- (val_div,":mid",2),
- (troop_get_slot,":first_value",":array",":first"),#25
- (troop_get_slot,":mid_value",":array",":mid"),#999
- (val_sub,":last",1),
- (troop_get_slot,":last_value",":array",":last"),#88
- (val_add,":last",1),
- #choose median
- (try_begin),
- (call_script,":cf_cmp_script",":first_value",":mid_value"),
- (try_begin),
- (call_script,":cf_cmp_script",":mid_value",":last_value"),
- (assign,":pivot",":mid_value"),
- (else_try),
- (call_script,":cf_cmp_script",":first_value",":last_value"),
- (assign,":pivot",":last_value"),
- (else_try),
- (assign,":pivot",":first_value"),
- (try_end),
- (else_try),
- (call_script,":cf_cmp_script",":first_value",":last_value"),
- (assign,":pivot",":first_value"),
- (else_try),
- (call_script,":cf_cmp_script",":mid_value",":last_value"),
- (assign,":pivot",":last_value"),
- (else_try),
- (assign,":pivot",":mid_value"),
- (try_end),
- # (assign,reg0,":pivot"),
- # (assign,reg1,":first_value"),
- # (assign,reg2,":mid_value"),
- # (assign,reg3,":last_value"),
- # (display_message,"@pivot{reg0} f:{reg1} m:{reg2} l:{reg3}"),
- (assign,":end1",1),
- (try_for_range,":unused",0,":end1"),
- (val_add,":end1",1),
- (assign,":end2",1),
- (try_for_range,":unused",0,":end2"),
- (val_add,":end2",1),
- (troop_get_slot,":first_value",":array",":first"),
- (try_begin),
- (call_script,":cf_cmp_script",":first_value",":pivot"),
- (val_add,":first",1),
- (else_try),
- (assign,":end2",0),
- (try_end),
- (try_end),
- (val_sub,":last",1),
- (assign,":end2",1),
- (try_for_range,":unused",0,":end2"),
- (val_add,":end2",1),
- (troop_get_slot,":last_value",":array",":last"),
- (try_begin),
- (call_script,":cf_cmp_script",":pivot",":last_value"),
- (val_sub,":last",1),
- (else_try),
- (assign,":end2",0),
- (try_end),
- (try_end),
- (try_begin),
- (lt,":first",":last"),
- #swap
- (troop_set_slot,":array",":first",":last_value"),
- (troop_set_slot,":array",":last",":first_value"),
- (val_add,":first",1),
- (else_try),
- (assign,":end1",0),
- (assign,reg0,":first"),
- (try_end),
- (try_end),
- ]),
- ("nth_element",
- [
- (store_script_param,":array",1),
- (store_script_param,":first",2),
- (store_script_param,":nth",3),
- (store_script_param,":last",4),
- (store_script_param,":cf_cmp_script",5),
- (assign,":gap",3),
- (assign,":end",1),
- (try_for_range,":unused",0,":end"),
- (val_add,":end",1),
- (store_sub,":dif",":last",":first"),
- (try_begin),
- (gt,":dif",":gap"),
- (call_script,"script_median_partition",":array",":first",":last",":cf_cmp_script"),
- (assign,":cut",reg0),
- (try_begin),
- (le,":cut",":nth"),
- (assign,":first",":cut"),
- (else_try),
- (assign,":last",":cut"),
- (try_end),
- (else_try),
- (assign,":end",0),
- (try_end),
- (try_end),
- (call_script,"script_insertion_sort",":array",":first",":last",":cf_cmp_script"),
- ]),
- ("cf_point_cmp_x",
- [
- (store_script_param,":first",1),
- (store_script_param,":second",2),
- (val_mul,":first",KDTreeNodeBufferValueNum),
- (val_add,":first",1),
- (val_mul,":second",KDTreeNodeBufferValueNum),
- (val_add,":second",1),
- (troop_get_slot,":first_v","trp_KDTreeBuffer",":first"),
- (troop_get_slot,":second_v","trp_KDTreeBuffer",":second"),
- (lt,":first_v",":second_v"),
- ]),
- ("cf_point_cmp_y",
- [
- (store_script_param,":first",1),
- (store_script_param,":second",2),
- (val_mul,":first",KDTreeNodeBufferValueNum),
- (val_add,":first",2),
- (val_mul,":second",KDTreeNodeBufferValueNum),
- (val_add,":second",2),
- (troop_get_slot,":first_v","trp_KDTreeBuffer",":first"),
- (troop_get_slot,":second_v","trp_KDTreeBuffer",":second"),
- (lt,":first_v",":second_v"),
- ]),
- ("Inner_Build_KD_Tree",
- [
- (store_script_param,":array",1),
- (store_script_param,":first",2),
- (store_script_param,":last",3),
- #(store_script_param,":index",4),
- (try_begin),
- (lt,":first",":last"),
- (store_add,":mid",":first",":last"),
- (val_div,":mid",2),
- #ver 2
- (store_sub,":count",":last",":first"),
- (assign,":sx",0),
- (assign,":avgx",0),
- (assign,":sy",0),
- (assign,":avgy",0),
- (try_for_range,":i",":first",":last"),
- (troop_get_slot,":i_id",":array",":i"),
- (store_mul,":i_index",":i_id",KDTreeNodeBufferValueNum),
- (store_add,":x_index",":i_index",1),
- (store_add,":y_index",":i_index",2),
- (troop_get_slot,":x","trp_KDTreeBuffer",":x_index"),
- (troop_get_slot,":y","trp_KDTreeBuffer",":y_index"),
- (val_add,":avgx",":x"),
- (val_add,":avgy",":x"),
- (try_end),
- (val_div,":avgx",":count"),
- (val_div,":avgy",":count"),
- (try_for_range,":i",":first",":last"),
- (troop_get_slot,":i_id",":array",":i"),
- (store_mul,":i_index",":i_id",KDTreeNodeBufferValueNum),
- (store_add,":x_index",":i_index",1),
- (store_add,":y_index",":i_index",2),
- (troop_get_slot,":x","trp_KDTreeBuffer",":x_index"),
- (troop_get_slot,":y","trp_KDTreeBuffer",":y_index"),
- (val_sub,":x",":avgx"),
- (val_sub,":y",":avgy"),
- (val_mul,":x",":x"),
- (val_mul,":y",":y"),
- (val_add,":sx",":x"),
- (val_add,":sy",":y"),
- (try_end),
- # (assign,reg0,":sx"),
- # (assign,reg1,":sy"),
- # (display_message,"@{reg0} {reg1}"),
- (try_begin),
- # (eq,":index",0),
- (ge,":sx",":sy"),
- (assign,":cf_cmp_script","script_cf_point_cmp_x"),
- (assign,":dim",0),
- (else_try),
- (assign,":cf_cmp_script","script_cf_point_cmp_y"),
- (assign,":dim",1),
- (try_end),
- (call_script,"script_nth_element",":array",":first",":mid",":last",":cf_cmp_script"),
- #(val_add,":index",1),
- #(val_mod,":index",2),
- (troop_get_slot,":mid_id",":array",":mid"),
- (store_mul,":left_child_index",":mid_id",KDTreeNodeBufferValueNum),
- (val_add,":left_child_index",3),
- (store_add,":right_child_index",":left_child_index",1),
- (store_add,":dim_index",":right_child_index",1),
- (troop_set_slot,"trp_KDTreeBuffer",":dim_index",":dim"),
- # (call_script,"script_Inner_Build_KD_Tree",":array",":first",":mid",":index"),
- (call_script,"script_Inner_Build_KD_Tree",":array",":first",":mid"),
- (troop_set_slot,"trp_KDTreeBuffer",":left_child_index",reg0),
- (store_add,":mid_plus_one",":mid",1),
- # (call_script,"script_Inner_Build_KD_Tree",":array",":mid_plus_one",":last",":index"),
- (call_script,"script_Inner_Build_KD_Tree",":array",":mid_plus_one",":last"),
- (troop_set_slot,"trp_KDTreeBuffer",":right_child_index",reg0),
- (troop_get_slot,reg0,":array",":mid"),
- (else_try),
- (assign,reg0,-1),
- (try_end),
- ]),
- #reg0: x
- #reg1: y
- ("GetCoor",
- [
- (store_script_param,":id",1),
- (party_get_position,pos0,":id"),
- (position_get_x,reg0,pos0),
- (position_get_y,reg1,pos0),
- ]),
- #reg0: root
- ("Build_KD_Tree",
- [
- (store_script_param,":array",1),
- (store_script_param,":count",2),
- (store_script_param,":CallBackScriptGetCoor",3),
- #Todo System allocate array
- #[id,x,y,left_child,right_child]
- (try_for_range,":i",0,":count"),
- (store_mul,":index",":i",KDTreeNodeBufferValueNum),
- #id
- (troop_get_slot,":point_Id",":array",":i"),
- (troop_set_slot,"trp_KDTreeBuffer",":index",":point_Id"),
- #x
- (val_add,":index",1),
- (call_script,":CallBackScriptGetCoor",":point_Id"),
- (troop_set_slot,"trp_KDTreeBuffer",":index",reg0),
- #y
- (val_add,":index",1),
- (troop_set_slot,"trp_KDTreeBuffer",":index",reg1),
- #left_child
- (val_add,":index",1),
- (troop_set_slot,"trp_KDTreeBuffer",":index",-1),
- #right_child
- (val_add,":index",1),
- (troop_set_slot,"trp_KDTreeBuffer",":index",-1),
- #dim
- (val_add,":index",1),
- (troop_set_slot,"trp_KDTreeBuffer",":index",0),
- (try_end),
- (try_for_range,":i",0,":count"),
- (troop_set_slot,":array",":i",":i"),
- (try_end),
- (call_script,"script_Inner_Build_KD_Tree",":array",0,":count",0),
- (call_script,"script_Construct_Binary_Tree",":array",1,reg0),#root
- (troop_set_slot,":array",0,":count"),
- (assign,":fixed_point",1),
- (convert_to_fixed_point,":fixed_point"),
- (troop_set_slot,":array",1,":fixed_point"),
- #--debug
- # (val_mul,":count",2),
- # (try_for_range,":i",0,":count"),
- # (store_mul,":value_index",":i",KDTreeNodeBufferValueNum),
- # (store_add,":x_index",":value_index",1),
- # (store_add,":y_index",":value_index",2),
- # (store_add,":left_child_index",":value_index",3),
- # (store_add,":right_child_index",":value_index",4),
- # (store_add,":dim_index",":value_index",5),
- # (troop_get_slot,reg0,"trp_KDTreeBuffer",":value_index"),
- # (troop_get_slot,reg1,"trp_KDTreeBuffer",":x_index"),
- # (troop_get_slot,reg2,"trp_KDTreeBuffer",":y_index"),
- # (troop_get_slot,reg3,"trp_KDTreeBuffer",":left_child_index"),
- # (troop_get_slot,reg4,"trp_KDTreeBuffer",":right_child_index"),
- # (troop_get_slot,reg5,"trp_KDTreeBuffer",":dim_index"),
- # (display_message,"@{reg0} {reg1} {reg2} {reg3} {reg4} {reg5}"),
- # (try_end),
- ]),
- ("Construct_Binary_Tree",
- [
- (store_script_param,":array",1),
- (store_script_param,":pos",2),
- (store_script_param,":root",3),
- #get value
- (store_mul,":id_index",":root",KDTreeNodeBufferValueNum),
- (store_add,":x_index",":id_index",1),
- (store_add,":y_index",":id_index",2),
- (store_add,":left_child_index",":id_index",3),
- (store_add,":right_child_index",":id_index",4),
- (store_add,":dim_index",":id_index",5),
- (troop_get_slot,":id","trp_KDTreeBuffer",":id_index"),
- (troop_get_slot,":x","trp_KDTreeBuffer",":x_index"),
- (troop_get_slot,":y","trp_KDTreeBuffer",":y_index"),
- (troop_get_slot,":left_child","trp_KDTreeBuffer",":left_child_index"),
- (troop_get_slot,":right_child","trp_KDTreeBuffer",":right_child_index"),
- (troop_get_slot,":dim","trp_KDTreeBuffer",":dim_index"),
- #set value
- (store_mul,":id_index",":pos",KDTreeNodeValueNum),
- (store_add,":x_index",":id_index",1),
- (store_add,":y_index",":id_index",2),
- (store_add,":dim_index",":id_index",3),
- (troop_set_slot,":array",":id_index",":id"),
- (troop_set_slot,":array",":x_index",":x"),
- (troop_set_slot,":array",":y_index",":y"),
- (troop_set_slot,":array",":dim_index",":dim"),
- (store_mul,":left_child_pos",":pos",2),
- (store_add,":right_child_pos",":left_child_pos",1),
- (try_begin),
- (ge,":left_child",0),
- (call_script,"script_Construct_Binary_Tree",":array",":left_child_pos",":left_child"),
- (else_try),
- (store_mul,":id_index",":left_child_pos",KDTreeNodeValueNum),
- (store_add,":x_index",":id_index",1),
- (store_add,":y_index",":id_index",2),
- # (call_script,"script_Get_Positive_Infinity"),
- (troop_set_slot,":array",":id_index",0x7fffffff),
- (troop_set_slot,":array",":x_index",0x7fffffff),
- (troop_set_slot,":array",":y_index",0x7fffffff),
- (try_end),
- (try_begin),
- (ge,":right_child",0),
- (call_script,"script_Construct_Binary_Tree",":array",":right_child_pos",":right_child"),
- (else_try),
- (store_mul,":id_index",":right_child_pos",KDTreeNodeValueNum),
- (store_add,":x_index",":id_index",1),
- (store_add,":y_index",":id_index",2),
- # (call_script,"script_Get_Positive_Infinity"),
- (troop_set_slot,":array",":id_index",0x7fffffff),
- (troop_set_slot,":array",":x_index",0x7fffffff),
- (troop_set_slot,":array",":y_index",0x7fffffff),
- (try_end),
- ]),
- #Best Point ID: reg0
- #best_dist_square: reg1
- #visited: reg2
- ("KD_Tree_Nearest_neighbor_Search",
- [
- (store_script_param,":KD_Tree",1),
- (store_script_param,":point_x",2),
- (store_script_param,":point_y",3),
- (troop_get_slot,":fixed_point",":KD_Tree",1),
- (val_mul,":point_x",":fixed_point"),
- (val_mul,":point_y",":fixed_point"),
- (convert_from_fixed_point,":point_x"),
- (convert_from_fixed_point,":point_y"),
- (call_script,"script_Get_Positive_Infinity"),#init best_dist to positive infinity
- (assign,reg1,reg0),
- (assign,reg0,-1),
- (assign,reg2,0),
- #(call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",1,":point_x",":point_y",0),
- (call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",1,":point_x",":point_y"),
- #get id
- (val_mul,reg0,KDTreeNodeValueNum),
- (troop_get_slot,reg0,":KD_Tree",reg0),
- #transform best distance
- (val_div,reg1,":fixed_point"),
- (convert_to_fixed_point,reg1),
- (val_div,reg1,":fixed_point"),
- ]),
- #Best Point_index: reg0
- #best_dist: reg1
- #sentinel card: reg2
- ("Inner_KD_Tree_Nearest_Neighbor_Search",
- [
- (store_script_param,":KD_Tree",1),
- (store_script_param,":root",2),
- (store_script_param,":point_x",3),
- (store_script_param,":point_y",4),
- #(store_script_param,":index",5),
- (try_begin),
- #get distance
- (store_mul,":root_index",":root",KDTreeNodeValueNum),
- (store_add,":x_index",":root_index",1),
- (store_add,":y_index",":root_index",2),
- (store_add,":dim_index",":root_index",3),
- (troop_get_slot,":root_value",":KD_Tree",":root_index"),
- (troop_get_slot,":root_x",":KD_Tree",":x_index"),
- (troop_get_slot,":root_y",":KD_Tree",":y_index"),
- (troop_get_slot,":dim",":KD_Tree",":dim_index"),
- (this_or_next|neq,":root_value",0x7fffffff),
- (this_or_next|neq,":root_x",0x7fffffff),
- (neq,":root_y",0x7fffffff),
- (val_add,reg2,1),
- (store_sub,":dx",":root_x",":point_x"),
- (store_sub,":dy",":root_y",":point_y"),
- (store_mul,":dx_square",":dx",":dx"),
- (store_mul,":dy_square",":dy",":dy"),
- (store_add,":distance",":dx_square",":dy_square"),
- (try_begin),
- (this_or_next|eq,reg0,-1),
- (lt,":distance",reg1),
- (assign,reg1,":distance"),
- (assign,reg0,":root"),
- (try_end),
- (neq,reg1,0),
- #calculate di
- (try_begin),
- (eq,":dim",0),
- (assign,":di",":dx"),
- (else_try),
- (assign,":di",":dy"),
- (try_end),
- #update index
- #(val_add,":index",1),
- #(val_mod,":index",2),
- (store_mul,":left_child",":root",2),
- (store_add,":right_child",":left_child",1),
- (try_begin),
- (gt,":di",0),
- (assign,":first",":left_child"),
- (assign,":second",":right_child"),
- (else_try),
- (assign,":first",":right_child"),
- (assign,":second",":left_child"),
- (try_end),
- #(call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",":first",":point_x",":point_y",":index"),
- (call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",":first",":point_x",":point_y"),
- (val_mul,":di",":di"),
- (lt,":di",reg1),
- #(call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",":second",":point_x",":point_y",":index"),
- (call_script,"script_Inner_KD_Tree_Nearest_Neighbor_Search",":KD_Tree",":second",":point_x",":point_y"),
- (try_end),
- ]),
复制代码 |
首先添加对应的代码
执行如下代码绘图并压缩
(call_script,"script_Init_World_Map_data","trp_World_Map"),
(try_for_range,":unused",0,1000),#这一步可以放到一个触发器里, 分摊压力
(call_script,"script_Compress_World_Map","trp_World_Map"),
(try_end),
(troop_get_slot,reg0,"trp_World_Map",9),
(display_message,"@total slots:{reg0}"),
然后就可以看了.
(start_presentation,"prsnt_world_map2"), |
其实还有其他优化方法的空间. 不过以后再说吧
1. 改单行绘制为双行/多行绘制. 进一步减少overlay数量
2. 使用R树求连续最近邻
3. 计算voronoi, 用别的图形填充
2-15 更新: 发现英文写错了, RLE(Run Length Encoding)写成了RTL
3-24 更新: 添加了部分注释, 改了几处变量名 |