Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
itdan3344
stb
提交
1d6e55ab
S
stb
项目概览
itdan3344
/
stb
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
stb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1d6e55ab
编写于
4月 16, 2016
作者:
S
Sean Barrett
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
reduce storage for stb_connected_components.h
上级
1392344c
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
168 addition
and
37 deletion
+168
-37
stb_connected_components.h
stb_connected_components.h
+168
-37
未找到文件。
stb_connected_components.h
浏览文件 @
1d6e55ab
...
...
@@ -41,7 +41,6 @@
#define INCLUDE_STB_CONNECTED_COMPONENTS_H
#include <stdlib.h>
#include <assert.h>
typedef
struct
st_stbcc_grid
stbcc_grid
;
...
...
@@ -94,6 +93,9 @@ extern unsigned int stbcc_get_unique_id(stbcc_grid *g, int x, int y);
#ifdef STB_CONNECTED_COMPONENTS_IMPLEMENTATION
#include <assert.h>
#include <string.h> // memset
#if !defined(STBCC_GRID_COUNT_X_LOG2) || !defined(STBCC_GRID_COUNT_Y_LOG2)
#error "You must define STBCC_GRID_COUNT_X_LOG2 and STBCC_GRID_COUNT_Y_LOG2 to define the max grid supported."
#endif
...
...
@@ -140,9 +142,22 @@ extern unsigned int stbcc_get_unique_id(stbcc_grid *g, int x, int y);
typedef
unsigned
short
stbcc__clumpid
;
typedef
unsigned
char
stbcc__verify_max_clumps
[
STBCC__MAX_CLUMPS_PER_CLUSTER
<
(
1
<<
(
8
*
sizeof
(
stbcc__clumpid
)))
?
1
:
-
1
];
#define STBCC__MAX_EXITS_PER_CLUMP (STBCC__CLUSTER_SIZE_X + STBCC__CLUSTER_SIZE_Y) // 64
#define STBCC__MAX_EXITS_PER_CLUSTER (STBCC__CLUSTER_SIZE_X + STBCC__CLUSTER_SIZE_Y) // 64 for 32x32
#define STBCC__MAX_EXITS_PER_CLUMP (STBCC__CLUSTER_SIZE_X + STBCC__CLUSTER_SIZE_Y) // 64 for 32x32
// 2^19 * 2^6 => 2^25 exits => 2^26 => 64MB for 1024x1024
// Logic for above on 4x4 grid:
//
// Many clumps: One clump:
// + + + +
// +X.X. +XX.X+
// .X.X+ .XXX
// +X.X. XXX.
// .X.X+ +X.XX+
// + + + +
//
// 8 exits either way
typedef
unsigned
char
stbcc__verify_max_exits
[
STBCC__MAX_EXITS_PER_CLUMP
<=
256
];
typedef
struct
...
...
@@ -168,15 +183,20 @@ typedef union
typedef
struct
{
stbcc__global_clumpid
global_label
;
unsigned
short
num_adjacent
;
stbcc__relative_clumpid
adjacent_clumps
[
STBCC__MAX_EXITS_PER_CLUMP
];
}
stbcc__clump
;
stbcc__global_clumpid
global_label
;
// 4
unsigned
char
num_adjacent
;
// 1
unsigned
char
max_adjacent
;
// 1
unsigned
char
adjacent_clump_list_index
;
// 1
unsigned
char
on_edge
;
// 1
}
stbcc__clump
;
// 8
#define STBCC__CLUSTER_ADJACENCY_COUNT (STBCC__MAX_EXITS_PER_CLUSTER*4)
typedef
struct
{
unsigned
int
num_clumps
;
stbcc__clump
clump
[
STBCC__MAX_CLUMPS_PER_CLUSTER
];
unsigned
char
rebuild
;
stbcc__clump
clump
[
STBCC__MAX_CLUMPS_PER_CLUSTER
];
// 8 * 2^9 = 4KB
stbcc__relative_clumpid
adjacency_storage
[
STBCC__CLUSTER_ADJACENCY_COUNT
];
// 512 bytes
}
stbcc__cluster
;
struct
st_stbcc_grid
...
...
@@ -184,7 +204,7 @@ struct st_stbcc_grid
int
w
,
h
,
cw
,
ch
;
unsigned
char
map
[
STBCC__GRID_COUNT_Y
][
STBCC__MAP_STRIDE
];
// 1K x 1K => 1K x 128 => 128KB
stbcc__clumpid
clump_for_node
[
STBCC__GRID_COUNT_Y
][
STBCC__GRID_COUNT_X
];
// 1K x 1K x 2 = 2MB
stbcc__cluster
cluster
[
STBCC__CLUSTER_COUNT_Y
][
STBCC__CLUSTER_COUNT_X
];
// 1K x
1K x 0.5 x 64 x 2 = 64
MB
stbcc__cluster
cluster
[
STBCC__CLUSTER_COUNT_Y
][
STBCC__CLUSTER_COUNT_X
];
// 1K x
4.5KB = 9
MB
};
int
stbcc_query_grid_node_connection
(
stbcc_grid
*
g
,
int
x1
,
int
y1
,
int
x2
,
int
y2
)
...
...
@@ -291,13 +311,15 @@ static void stbcc__build_connected_components_for_clumps(stbcc_grid *g)
for
(
k
=
0
;
k
<
(
int
)
cluster
->
num_clumps
;
++
k
)
{
stbcc__clump
*
clump
=
&
cluster
->
clump
[
k
];
stbcc__unpacked_clumpid
m
;
stbcc__relative_clumpid
*
adj
;
m
.
clump_index
=
k
;
m
.
cluster_x
=
i
;
m
.
cluster_y
=
j
;
adj
=
&
cluster
->
adjacency_storage
[
clump
->
adjacent_clump_list_index
];
for
(
h
=
0
;
h
<
clump
->
num_adjacent
;
++
h
)
{
unsigned
int
clump_index
=
clump
->
adjacent_clumps
[
h
].
clump_index
;
unsigned
int
x
=
clump
->
adjacent_clumps
[
h
].
cluster_dx
+
i
;
unsigned
int
y
=
clump
->
adjacent_clumps
[
h
].
cluster_dy
+
j
;
unsigned
int
clump_index
=
adj
[
h
].
clump_index
;
unsigned
int
x
=
adj
[
h
].
cluster_dx
+
i
;
unsigned
int
y
=
adj
[
h
].
cluster_dy
+
j
;
stbcc__clump_union
(
g
,
m
,
x
,
y
,
clump_index
);
}
}
...
...
@@ -318,6 +340,106 @@ static void stbcc__build_connected_components_for_clumps(stbcc_grid *g)
}
}
static
void
stbcc__build_all_connections_for_cluster
(
stbcc_grid
*
g
,
int
cx
,
int
cy
)
{
// in this particular case, we are fully non-incremental. that means we
// can discover the correct sizes for the arrays, but requires we build
// the data into temporary data structures, or just count the sizes, so
// for simplicity we do the latter
stbcc__cluster
*
cluster
=
&
g
->
cluster
[
cy
][
cx
];
unsigned
char
connected
[
STBCC__MAX_CLUMPS_PER_CLUSTER
/
8
];
unsigned
char
num_adj
[
STBCC__MAX_CLUMPS_PER_CLUSTER
]
=
{
0
};
int
x
=
cx
*
STBCC__CLUSTER_SIZE_X
;
int
y
=
cy
*
STBCC__CLUSTER_SIZE_Y
;
int
step_x
,
step_y
=
0
,
i
,
j
,
k
,
n
,
m
,
dx
,
dy
,
total
;
g
->
cluster
[
cy
][
cx
].
rebuild
=
0
;
total
=
0
;
for
(
m
=
0
;
m
<
4
;
++
m
)
{
switch
(
m
)
{
case
0
:
dx
=
1
,
dy
=
0
;
step_x
=
0
,
step_y
=
1
;
i
=
STBCC__CLUSTER_SIZE_X
-
1
;
j
=
0
;
n
=
STBCC__CLUSTER_SIZE_Y
;
break
;
case
1
:
dx
=
-
1
,
dy
=
0
;
i
=
0
;
j
=
0
;
step_x
=
0
;
step_y
=
1
;
n
=
STBCC__CLUSTER_SIZE_Y
;
break
;
case
2
:
dy
=
-
1
,
dx
=
0
;
i
=
0
;
j
=
0
;
step_x
=
1
;
step_y
=
0
;
n
=
STBCC__CLUSTER_SIZE_X
;
break
;
case
3
:
dy
=
1
,
dx
=
0
;
i
=
0
;
j
=
STBCC__CLUSTER_SIZE_Y
-
1
;
step_x
=
1
;
step_y
=
0
;
n
=
STBCC__CLUSTER_SIZE_X
;
break
;
}
if
(
cx
+
dx
<
0
||
cx
+
dx
>=
g
->
cw
||
cy
+
dy
<
0
||
cy
+
dy
>=
g
->
ch
)
continue
;
memset
(
connected
,
0
,
sizeof
(
connected
));
for
(
k
=
0
;
k
<
n
;
++
k
)
{
if
(
STBCC__MAP_OPEN
(
g
,
x
+
i
,
y
+
j
)
&&
STBCC__MAP_OPEN
(
g
,
x
+
i
+
dx
,
y
+
j
+
dy
))
{
stbcc__clumpid
c
=
g
->
clump_for_node
[
y
+
j
+
dy
][
x
+
i
+
dx
];
if
(
0
==
(
connected
[
c
>>
3
]
&
(
1
<<
(
c
&
7
))))
{
connected
[
c
>>
3
]
|=
1
<<
(
c
&
7
);
++
num_adj
[
g
->
clump_for_node
[
y
+
j
][
x
+
i
]];
++
total
;
}
}
i
+=
step_x
;
j
+=
step_y
;
}
}
// decide how to apportion leftover... would be better if we knew WHICH clumps
// were along the edge, but we should compute this at initial time, not above
// to minimize recompoutation
total
=
0
;
for
(
i
=
0
;
i
<
(
int
)
cluster
->
num_clumps
;
++
i
)
{
int
alloc
=
num_adj
[
i
]
*
2
;
// every cluster gets room for 2x current adjacency
assert
(
total
<
256
);
// must fit in byte
cluster
->
clump
[
i
].
adjacent_clump_list_index
=
(
unsigned
char
)
total
;
cluster
->
clump
[
i
].
max_adjacent
=
alloc
;
cluster
->
clump
[
i
].
num_adjacent
=
0
;
total
+=
alloc
;
}
assert
(
total
<=
STBCC__CLUSTER_ADJACENCY_COUNT
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
-
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
0
,
-
1
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
0
,
1
);
// make sure all of the above succeeded.
assert
(
g
->
cluster
[
cy
][
cx
].
rebuild
==
0
);
}
static
void
stbcc__add_connections_to_adjacent_cluster_with_rebuild
(
stbcc_grid
*
g
,
int
cx
,
int
cy
,
int
dx
,
int
dy
)
{
if
(
cx
>=
0
&&
cx
<
g
->
cw
&&
cy
>=
0
&&
cy
<
g
->
ch
)
{
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
dx
,
dy
);
if
(
g
->
cluster
[
cy
][
cx
].
rebuild
)
stbcc__build_all_connections_for_cluster
(
g
,
cx
,
cy
);
}
}
void
stbcc_update_grid
(
stbcc_grid
*
g
,
int
x
,
int
y
,
int
solid
)
{
int
cx
,
cy
;
...
...
@@ -344,16 +466,12 @@ void stbcc_update_grid(stbcc_grid *g, int x, int y, int solid)
STBCC__MAP_BYTE
(
g
,
x
,
y
)
&=
~
STBCC__MAP_BYTE_MASK
(
x
,
y
);
stbcc__build_clumps_for_cluster
(
g
,
cx
,
cy
);
stbcc__build_all_connections_for_cluster
(
g
,
cx
,
cy
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
-
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
0
,
-
1
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
,
0
,
1
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
-
1
,
cy
,
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
+
1
,
cy
,
-
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
-
1
,
0
,
1
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
cx
,
cy
+
1
,
0
,
-
1
);
stbcc__add_connections_to_adjacent_cluster_with_rebuild
(
g
,
cx
-
1
,
cy
,
1
,
0
);
stbcc__add_connections_to_adjacent_cluster_with_rebuild
(
g
,
cx
+
1
,
cy
,
-
1
,
0
);
stbcc__add_connections_to_adjacent_cluster_with_rebuild
(
g
,
cx
,
cy
-
1
,
0
,
1
);
stbcc__add_connections_to_adjacent_cluster_with_rebuild
(
g
,
cx
,
cy
+
1
,
0
,
-
1
);
stbcc__build_connected_components_for_clumps
(
g
);
}
...
...
@@ -389,14 +507,9 @@ void stbcc_init_grid(stbcc_grid *g, unsigned char *map, int w, int h)
for
(
i
=
0
;
i
<
g
->
cw
;
++
i
)
stbcc__build_clumps_for_cluster
(
g
,
i
,
j
);
for
(
j
=
0
;
j
<
g
->
ch
;
++
j
)
{
for
(
i
=
0
;
i
<
g
->
cw
;
++
i
)
{
stbcc__add_connections_to_adjacent_cluster
(
g
,
i
,
j
,
-
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
i
,
j
,
1
,
0
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
i
,
j
,
0
,
-
1
);
stbcc__add_connections_to_adjacent_cluster
(
g
,
i
,
j
,
0
,
1
);
}
}
for
(
j
=
0
;
j
<
g
->
ch
;
++
j
)
for
(
i
=
0
;
i
<
g
->
cw
;
++
i
)
stbcc__build_all_connections_for_cluster
(
g
,
i
,
j
);
stbcc__build_connected_components_for_clumps
(
g
);
...
...
@@ -408,6 +521,7 @@ void stbcc_init_grid(stbcc_grid *g, unsigned char *map, int w, int h)
static
void
stbcc__add_clump_connection
(
stbcc_grid
*
g
,
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
stbcc__cluster
*
cluster
;
stbcc__clump
*
clump
;
int
cx1
=
STBCC__CLUSTER_X_FOR_COORD_X
(
x1
);
...
...
@@ -429,14 +543,22 @@ static void stbcc__add_clump_connection(stbcc_grid *g, int x1, int y1, int x2, i
rc
.
cluster_dx
=
x2
-
x1
;
rc
.
cluster_dy
=
y2
-
y1
;
clump
=
&
g
->
cluster
[
cy1
][
cx1
].
clump
[
c1
];
cluster
=
&
g
->
cluster
[
cy1
][
cx1
];
clump
=
&
cluster
->
clump
[
c1
];
if
(
clump
->
num_adjacent
==
clump
->
max_adjacent
)
g
->
cluster
[
cy1
][
cx1
].
rebuild
=
1
;
else
{
stbcc__relative_clumpid
*
adj
=
&
cluster
->
adjacency_storage
[
clump
->
adjacent_clump_list_index
];
assert
(
clump
->
num_adjacent
<
STBCC__MAX_EXITS_PER_CLUMP
);
clump
->
adjacent_clumps
[
clump
->
num_adjacent
++
]
=
rc
;
adj
[
clump
->
num_adjacent
++
]
=
rc
;
}
}
static
void
stbcc__remove_clump_connection
(
stbcc_grid
*
g
,
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
stbcc__cluster
*
cluster
;
stbcc__clump
*
clump
;
stbcc__relative_clumpid
*
adj
;
int
i
;
int
cx1
=
STBCC__CLUSTER_X_FOR_COORD_X
(
x1
);
...
...
@@ -458,16 +580,18 @@ static void stbcc__remove_clump_connection(stbcc_grid *g, int x1, int y1, int x2
rc
.
cluster_dx
=
x2
-
x1
;
rc
.
cluster_dy
=
y2
-
y1
;
clump
=
&
g
->
cluster
[
cy1
][
cx1
].
clump
[
c1
];
cluster
=
&
g
->
cluster
[
cy1
][
cx1
];
clump
=
&
cluster
->
clump
[
c1
];
adj
=
&
cluster
->
adjacency_storage
[
clump
->
adjacent_clump_list_index
];
for
(
i
=
0
;
i
<
clump
->
num_adjacent
;
++
i
)
if
(
rc
.
clump_index
==
clump
->
adjacent_clumps
[
i
].
clump_index
&&
rc
.
cluster_dx
==
clump
->
adjacent_clumps
[
i
].
cluster_dx
&&
rc
.
cluster_dy
==
clump
->
adjacent_clumps
[
i
].
cluster_dy
)
if
(
rc
.
clump_index
==
adj
[
i
].
clump_index
&&
rc
.
cluster_dx
==
adj
[
i
].
cluster_dx
&&
rc
.
cluster_dy
==
adj
[
i
].
cluster_dy
)
break
;
if
(
i
<
clump
->
num_adjacent
)
clump
->
adjacent_clumps
[
i
]
=
clump
->
adjacent_clumps
[
--
clump
->
num_adjacent
];
adj
[
i
]
=
adj
[
--
clump
->
num_adjacent
];
else
assert
(
0
);
}
...
...
@@ -485,6 +609,9 @@ static void stbcc__add_connections_to_adjacent_cluster(stbcc_grid *g, int cx, in
if
(
cx
+
dx
<
0
||
cx
+
dx
>=
g
->
cw
||
cy
+
dy
<
0
||
cy
+
dy
>=
g
->
ch
)
return
;
if
(
g
->
cluster
[
cy
][
cx
].
rebuild
)
return
;
assert
(
abs
(
dx
)
+
abs
(
dy
)
==
1
);
if
(
dx
==
1
)
{
...
...
@@ -521,6 +648,8 @@ static void stbcc__add_connections_to_adjacent_cluster(stbcc_grid *g, int cx, in
if
(
0
==
(
connected
[
c
>>
3
]
&
(
1
<<
(
c
&
7
))))
{
connected
[
c
>>
3
]
|=
1
<<
(
c
&
7
);
stbcc__add_clump_connection
(
g
,
x
+
i
,
y
+
j
,
x
+
i
+
dx
,
y
+
j
+
dy
);
if
(
g
->
cluster
[
cy
][
cx
].
rebuild
)
break
;
}
}
i
+=
step_x
;
...
...
@@ -669,6 +798,8 @@ static void stbcc__build_clumps_for_cluster(stbcc_grid *g, int cx, int cy)
g
->
clump_for_node
[
y
+
j
][
x
+
i
]
=
cbi
.
label
[
j
][
i
];
// @OPTIMIZE: remove cbi.label entirely
assert
(
g
->
clump_for_node
[
y
+
j
][
x
+
i
]
<=
STBCC__NULL_CLUMPID
);
}
c
->
rebuild
=
1
;
// flag that it has no valid data
}
#endif // STB_CONNECTED_COMPONENTS_IMPLEMENTATION
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录