Now layout build works fine
This commit is contained in:
@@ -33,7 +33,7 @@ entries=[ {
|
||||
"order": 4,
|
||||
"type": "layout"
|
||||
}, {
|
||||
"children": [ 18, 19 ],
|
||||
"children": [ 18, 19, 20 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 4,
|
||||
"name": "zone_0",
|
||||
@@ -41,7 +41,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 20, 21, 22 ],
|
||||
"children": [ 21, 22, 23 ],
|
||||
"commands": [ [ 4, [ ] ] ],
|
||||
"index": 5,
|
||||
"name": "zone_1",
|
||||
@@ -49,7 +49,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 23, 24, 25, 26 ],
|
||||
"children": [ 24, 25, 26, 27 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 6,
|
||||
"name": "zone_1",
|
||||
@@ -57,7 +57,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 27, 28, 29 ],
|
||||
"children": [ 28, 29, 30 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 7,
|
||||
"name": "zone_0",
|
||||
@@ -65,14 +65,14 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 30, 31 ],
|
||||
"children": [ 31, 32 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 8,
|
||||
"name": "unit_0",
|
||||
"order": 3,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ 32, 33 ],
|
||||
"children": [ 33, 34 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 9,
|
||||
"name": "zone_0",
|
||||
@@ -80,35 +80,35 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 34, 35 ],
|
||||
"children": [ 35, 36 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 10,
|
||||
"name": "unit_0",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ 36, 37 ],
|
||||
"children": [ 37, 38 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 11,
|
||||
"name": "unit_1",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ 38, 39 ],
|
||||
"children": [ 39, 40 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 12,
|
||||
"name": "unit_2",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ 40, 41 ],
|
||||
"children": [ 41, 42 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 13,
|
||||
"name": "unit_3",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ 42, 43 ],
|
||||
"children": [ 43, 44 ],
|
||||
"commands": [ ],
|
||||
"index": 14,
|
||||
"name": "zone_0",
|
||||
@@ -116,7 +116,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 44, 45 ],
|
||||
"children": [ 45, 46 ],
|
||||
"commands": [ ],
|
||||
"index": 15,
|
||||
"name": "zone_1",
|
||||
@@ -124,7 +124,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 46, 47, 48 ],
|
||||
"children": [ 47, 48, 49 ],
|
||||
"commands": [ ],
|
||||
"index": 16,
|
||||
"name": "zone_2",
|
||||
@@ -132,7 +132,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 49, 50, 51, 52, 53 ],
|
||||
"children": [ 50, 51, 52, 53, 54 ],
|
||||
"commands": [ ],
|
||||
"index": 17,
|
||||
"name": "zone_3",
|
||||
@@ -161,8 +161,18 @@ entries=[ {
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"commands": [ ],
|
||||
"index": 20,
|
||||
"name": "office_0",
|
||||
"order": 3,
|
||||
"room_area": 16.0,
|
||||
"room_type": 309,
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 21,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -172,7 +182,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ], [ 3, [ ] ] ],
|
||||
"index": 21,
|
||||
"index": 22,
|
||||
"name": "bathroom_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -182,7 +192,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 22,
|
||||
"index": 23,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -192,7 +202,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 23,
|
||||
"index": 24,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 144.0,
|
||||
@@ -202,7 +212,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 24,
|
||||
"index": 25,
|
||||
"name": "kitchen_0",
|
||||
"order": 1,
|
||||
"room_area": 64.0,
|
||||
@@ -212,7 +222,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 25,
|
||||
"index": 26,
|
||||
"name": "storage_room_0",
|
||||
"order": 2,
|
||||
"room_area": 16.0,
|
||||
@@ -222,7 +232,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 26,
|
||||
"index": 27,
|
||||
"name": "enterance_0",
|
||||
"order": 3,
|
||||
"room_area": 16.0,
|
||||
@@ -232,7 +242,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 27,
|
||||
"index": 28,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -242,7 +252,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 28,
|
||||
"index": 29,
|
||||
"name": "bathroom_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -252,7 +262,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 29,
|
||||
"index": 30,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -260,17 +270,17 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 54, 55, 56 ],
|
||||
"children": [ 55, 56, 57 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 30,
|
||||
"index": 31,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 57, 58 ],
|
||||
"children": [ 58, 59 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 31,
|
||||
"index": 32,
|
||||
"name": "zone_1",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
@@ -278,7 +288,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 32,
|
||||
"index": 33,
|
||||
"name": "enterance_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -286,9 +296,9 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 59 ],
|
||||
"children": [ 60 ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 33,
|
||||
"index": 34,
|
||||
"name": "stair_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -296,65 +306,65 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 60, 61, 62 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 34,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 63, 64 ],
|
||||
"children": [ 61, 62, 63 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 35,
|
||||
"name": "zone_1",
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 65 ],
|
||||
"children": [ 64, 65 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 36,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 66, 67 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 37,
|
||||
"name": "zone_1",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 68 ],
|
||||
"children": [ 66 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 38,
|
||||
"index": 37,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 67, 68 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 38,
|
||||
"name": "zone_1",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 69 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 39,
|
||||
"name": "zone_1",
|
||||
"order": 1,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 70 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 40,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 70 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 40,
|
||||
"name": "zone_1",
|
||||
"order": 1,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 71 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 41,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 72 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 42,
|
||||
"name": "zone_1",
|
||||
"order": 1,
|
||||
"type": "zone",
|
||||
@@ -362,7 +372,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 42,
|
||||
"index": 43,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -372,27 +382,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 43,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
"room_type": 202,
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 44,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
"room_type": 200,
|
||||
"type": "room",
|
||||
"window": false
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 45,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -402,7 +392,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 46,
|
||||
"index": 45,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -412,7 +402,27 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 46,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
"room_type": 202,
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 47,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
"room_type": 200,
|
||||
"type": "room",
|
||||
"window": false
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 48,
|
||||
"name": "bathroom_0",
|
||||
"order": 2,
|
||||
"room_area": 16.0,
|
||||
@@ -422,7 +432,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 48,
|
||||
"index": 49,
|
||||
"name": "bathroom_1",
|
||||
"order": 3,
|
||||
"room_area": 144.0,
|
||||
@@ -432,7 +442,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 49,
|
||||
"index": 50,
|
||||
"name": "living_room_0",
|
||||
"order": 1,
|
||||
"room_area": 144.0,
|
||||
@@ -442,7 +452,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 50,
|
||||
"index": 51,
|
||||
"name": "kitchen_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -452,7 +462,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 51,
|
||||
"index": 52,
|
||||
"name": "dining_room_0",
|
||||
"order": 3,
|
||||
"room_area": 144.0,
|
||||
@@ -462,7 +472,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 52,
|
||||
"index": 53,
|
||||
"name": "enterance_0",
|
||||
"order": 4,
|
||||
"room_area": 16.0,
|
||||
@@ -472,7 +482,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 53,
|
||||
"index": 54,
|
||||
"name": "enterance_1",
|
||||
"order": 5,
|
||||
"room_area": 16.0,
|
||||
@@ -482,7 +492,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 54,
|
||||
"index": 55,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -492,7 +502,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 55,
|
||||
"index": 56,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -502,7 +512,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 56,
|
||||
"index": 57,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 36.0,
|
||||
@@ -512,7 +522,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 57,
|
||||
"index": 58,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 36.0,
|
||||
@@ -522,7 +532,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 58,
|
||||
"index": 59,
|
||||
"name": "kitchen_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -530,17 +540,17 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 72, 73 ],
|
||||
"children": [ 73, 74 ],
|
||||
"commands": [ ],
|
||||
"floor_index": 1,
|
||||
"index": 59,
|
||||
"index": 60,
|
||||
"name": "floor_0",
|
||||
"order": 0,
|
||||
"type": "floor"
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 60,
|
||||
"index": 61,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -550,7 +560,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 61,
|
||||
"index": 62,
|
||||
"name": "bathroom_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -560,7 +570,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 62,
|
||||
"index": 63,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -570,7 +580,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 63,
|
||||
"index": 64,
|
||||
"name": "kitchen_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -580,7 +590,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 64,
|
||||
"index": 65,
|
||||
"name": "living_room_0",
|
||||
"order": 1,
|
||||
"room_area": 144.0,
|
||||
@@ -590,7 +600,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 65,
|
||||
"index": 66,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -600,7 +610,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 66,
|
||||
"index": 67,
|
||||
"name": "kitchen_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -610,7 +620,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 67,
|
||||
"index": 68,
|
||||
"name": "living_room_0",
|
||||
"order": 1,
|
||||
"room_area": 64.0,
|
||||
@@ -620,7 +630,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 68,
|
||||
"index": 69,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -630,7 +640,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 69,
|
||||
"index": 70,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -640,7 +650,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 70,
|
||||
"index": 71,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -650,7 +660,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 71,
|
||||
"index": 72,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -658,24 +668,24 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 74 ],
|
||||
"children": [ 75 ],
|
||||
"commands": [ ],
|
||||
"index": 72,
|
||||
"index": 73,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 75, 76 ],
|
||||
"children": [ 76, 77 ],
|
||||
"commands": [ ],
|
||||
"index": 73,
|
||||
"index": 74,
|
||||
"name": "unit_0",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 74,
|
||||
"index": 75,
|
||||
"name": "storage_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -683,17 +693,17 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 77 ],
|
||||
"children": [ 78 ],
|
||||
"commands": [ ],
|
||||
"index": 75,
|
||||
"index": 76,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 78 ],
|
||||
"children": [ 79 ],
|
||||
"commands": [ ],
|
||||
"index": 76,
|
||||
"index": 77,
|
||||
"name": "zone_1",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
@@ -701,7 +711,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 77,
|
||||
"index": 78,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -711,7 +721,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 78,
|
||||
"index": 79,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
|
||||
Submodule src/flecs updated: e3219d774d...3ae6926f78
Submodule src/godot updated: f75abbb3ec...36a01852a7
Submodule src/meshoptimizer updated: bab69978d8...20787cc054
@@ -2,6 +2,8 @@
|
||||
#include "base_data.h"
|
||||
#include "world_editor.h"
|
||||
#include "editor_event.h"
|
||||
#include "graph_module.h"
|
||||
#include "growth_module.h"
|
||||
#include "building_layout_graph.h"
|
||||
|
||||
// TODO: allocate zones in completed units and grow them.
|
||||
@@ -17,7 +19,8 @@ BuildingLayoutGraph::BuildingLayoutGraph()
|
||||
flecs::log::set_level(255);
|
||||
get_layout_grid_base();
|
||||
get_layout_grid_base();
|
||||
ecs.import <BuildingLayoutGraph::graph_module>();
|
||||
ecs.import <graph_module>();
|
||||
ecs.import <growth_module>();
|
||||
Error err = config.load("res://astream/building_layout.conf");
|
||||
assert(err == OK);
|
||||
public_rooms = config.get_value("rooms", "public", Array());
|
||||
|
||||
@@ -45,26 +45,4 @@ public:
|
||||
void create_interior_tilemap(const String &layout_name);
|
||||
int get_layout_count() const;
|
||||
int get_children_count(flecs::entity base_e) const;
|
||||
struct graph_module {
|
||||
flecs::entity GraphSolve;
|
||||
|
||||
flecs::entity get_layout_grid_base();
|
||||
flecs::entity get_layout_base();
|
||||
bool have_cell(flecs::entity floor_e, int id);
|
||||
void grow_cell(flecs::entity seed_e, int id);
|
||||
void queue_grow_cell(flecs::entity seed_e, int id);
|
||||
void growth_module(flecs::world &ecs,
|
||||
const String &module_name);
|
||||
void room_growth_module(flecs::world &ecs,
|
||||
const String &module_name);
|
||||
void zones_graph_module(flecs::world &ecs,
|
||||
const String &module_name);
|
||||
void create_floor_components(
|
||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||
const WorldEditor::components::buildings_layout_grid_size
|
||||
&size);
|
||||
bool check_region(flecs::entity floor_e, int index,
|
||||
const Rect2i &rect) const;
|
||||
graph_module(flecs::world &ecs);
|
||||
};
|
||||
};
|
||||
@@ -899,15 +899,14 @@ void BuildingLayoutGraphUI::draw_2d_grid_view(Control *draw)
|
||||
Math::randf(),
|
||||
Math::randf(),
|
||||
1.0f);
|
||||
draw->draw_rect(
|
||||
Rect2(dx + 0.1f * dsize,
|
||||
dy + 0.1f * dsize,
|
||||
0.8f * dsize,
|
||||
0.8f * dsize),
|
||||
colors[String(
|
||||
re.path())],
|
||||
true);
|
||||
}
|
||||
draw->draw_rect(
|
||||
Rect2(dx + 0.3f * dsize,
|
||||
dy + 0.3f * dsize,
|
||||
0.6f * dsize,
|
||||
0.6f * dsize),
|
||||
colors[String(re.path())],
|
||||
true);
|
||||
mcount++;
|
||||
});
|
||||
print_line(
|
||||
@@ -916,6 +915,8 @@ void BuildingLayoutGraphUI::draw_2d_grid_view(Control *draw)
|
||||
", " + String::num(dy) + ") " +
|
||||
String::num(dsize) + " " +
|
||||
(colors[cell.type].operator String()));
|
||||
if (mcount)
|
||||
print_line("draw_cell: is a room");
|
||||
});
|
||||
}
|
||||
pos++;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,235 +1,19 @@
|
||||
#ifndef GRAPH_MODULE_H_
|
||||
#define GRAPH_MODULE_H_
|
||||
#include <core/math/vector2.h>
|
||||
#include "grid_misc.h"
|
||||
#include "grow_job.h"
|
||||
struct RegionRect2i {
|
||||
Point2i position;
|
||||
Size2i size;
|
||||
struct graph_module {
|
||||
flecs::entity GraphSolve;
|
||||
|
||||
const Point2i &get_position() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
void set_position(const Point2i &p_position)
|
||||
{
|
||||
position = p_position;
|
||||
}
|
||||
const Size2i &get_size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
void set_size(const Size2i &p_size)
|
||||
{
|
||||
size = p_size;
|
||||
}
|
||||
|
||||
int get_area() const
|
||||
{
|
||||
return size.width * size.height;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2i get_center() const
|
||||
{
|
||||
return position + (size / 2);
|
||||
}
|
||||
|
||||
inline bool intersects(const RegionRect2i &p_rect) const
|
||||
{
|
||||
if (position.x > (p_rect.position.x + p_rect.size.width - 1)) {
|
||||
return false;
|
||||
}
|
||||
if ((position.x + size.width - 1) < p_rect.position.x) {
|
||||
return false;
|
||||
}
|
||||
if (position.y > (p_rect.position.y + p_rect.size.height - 1)) {
|
||||
return false;
|
||||
}
|
||||
if ((position.y + size.height - 1) < p_rect.position.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool encloses(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return (p_rect.position.x >= position.x) &&
|
||||
(p_rect.position.y >= position.y) &&
|
||||
((p_rect.position.x + p_rect.size.x) <=
|
||||
(position.x + size.x)) &&
|
||||
((p_rect.position.y + p_rect.size.y) <=
|
||||
(position.y + size.y));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool has_no_area() const
|
||||
{
|
||||
return (size.x <= 0 || size.y <= 0);
|
||||
}
|
||||
inline RegionRect2i clip(const RegionRect2i &p_rect) const
|
||||
{ /// return a clipped rect
|
||||
|
||||
RegionRect2i new_rect = p_rect;
|
||||
|
||||
if (!intersects(new_rect)) {
|
||||
return RegionRect2i();
|
||||
}
|
||||
|
||||
new_rect.position.x = MAX(p_rect.position.x, position.x);
|
||||
new_rect.position.y = MAX(p_rect.position.y, position.y);
|
||||
|
||||
Point2 p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2 end = position + size;
|
||||
|
||||
new_rect.size.x =
|
||||
(int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
|
||||
new_rect.size.y =
|
||||
(int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
inline RegionRect2i merge(const RegionRect2i &p_rect) const
|
||||
{ ///< return a merged rect
|
||||
|
||||
RegionRect2i new_rect;
|
||||
|
||||
new_rect.position.x = MIN(p_rect.position.x, position.x);
|
||||
new_rect.position.y = MIN(p_rect.position.y, position.y);
|
||||
|
||||
new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x,
|
||||
position.x + size.x);
|
||||
new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y,
|
||||
position.y + size.y);
|
||||
|
||||
new_rect.size =
|
||||
new_rect.size - new_rect.position; //make relative again
|
||||
|
||||
return new_rect;
|
||||
};
|
||||
bool has_point(const Point2 &p_point) const
|
||||
{
|
||||
if (p_point.x < position.x) {
|
||||
return false;
|
||||
}
|
||||
if (p_point.y < position.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_point.x >= (position.x + size.x)) {
|
||||
return false;
|
||||
}
|
||||
if (p_point.y >= (position.y + size.y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return position == p_rect.position && size == p_rect.size;
|
||||
}
|
||||
bool operator!=(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return position != p_rect.position || size != p_rect.size;
|
||||
}
|
||||
|
||||
RegionRect2i grow(int p_by) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g.position.x -= p_by;
|
||||
g.position.y -= p_by;
|
||||
g.size.width += p_by * 2;
|
||||
g.size.height += p_by * 2;
|
||||
return g;
|
||||
}
|
||||
|
||||
inline RegionRect2i grow_margin(Margin p_margin, int p_amount) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g = g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0,
|
||||
(MARGIN_TOP == p_margin) ? p_amount : 0,
|
||||
(MARGIN_RIGHT == p_margin) ? p_amount : 0,
|
||||
(MARGIN_BOTTOM == p_margin) ? p_amount :
|
||||
0);
|
||||
return g;
|
||||
}
|
||||
|
||||
inline RegionRect2i grow_individual(int p_left, int p_top, int p_right,
|
||||
int p_bottom) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g.position.x -= p_left;
|
||||
g.position.y -= p_top;
|
||||
g.size.width += p_left + p_right;
|
||||
g.size.height += p_top + p_bottom;
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RegionRect2i expand(const Vector2i &p_vector) const
|
||||
{
|
||||
RegionRect2i r = *this;
|
||||
r.expand_to(p_vector);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void expand_to(const Point2i &p_vector)
|
||||
{
|
||||
Point2i begin = position;
|
||||
Point2i end = position + size;
|
||||
|
||||
if (p_vector.x < begin.x) {
|
||||
begin.x = p_vector.x;
|
||||
}
|
||||
if (p_vector.y < begin.y) {
|
||||
begin.y = p_vector.y;
|
||||
}
|
||||
|
||||
if (p_vector.x > end.x) {
|
||||
end.x = p_vector.x;
|
||||
}
|
||||
if (p_vector.y > end.y) {
|
||||
end.y = p_vector.y;
|
||||
}
|
||||
|
||||
position = begin;
|
||||
size = end - begin;
|
||||
}
|
||||
|
||||
operator String() const
|
||||
{
|
||||
return String(position) + ", " + String(size);
|
||||
}
|
||||
|
||||
operator Rect2() const
|
||||
{
|
||||
return Rect2(position, size);
|
||||
}
|
||||
RegionRect2i(const Rect2 &p_r2)
|
||||
: position(p_r2.position)
|
||||
, size(p_r2.size)
|
||||
{
|
||||
}
|
||||
RegionRect2i(const Rect2i &p_r2)
|
||||
: position(p_r2.position)
|
||||
, size(p_r2.size)
|
||||
{
|
||||
}
|
||||
RegionRect2i()
|
||||
{
|
||||
}
|
||||
RegionRect2i(int p_x, int p_y, int p_width, int p_height)
|
||||
: position(Point2(p_x, p_y))
|
||||
, size(Size2(p_width, p_height))
|
||||
{
|
||||
}
|
||||
RegionRect2i(const Point2 &p_pos, const Size2 &p_size)
|
||||
: position(p_pos)
|
||||
, size(p_size)
|
||||
{
|
||||
}
|
||||
bool have_cell(flecs::entity floor_e, int id);
|
||||
void queue_grow_cell(flecs::entity seed_e, int id);
|
||||
void zones_graph_module(flecs::world &ecs, const String &module_name);
|
||||
void create_floor_components(
|
||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size);
|
||||
bool check_region(flecs::entity floor_e, int index,
|
||||
const Rect2i &rect) const;
|
||||
graph_module(flecs::world &ecs);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -48,303 +48,4 @@ struct grid_calc {
|
||||
{
|
||||
assert(grid_size > 0);
|
||||
}
|
||||
};
|
||||
void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
||||
const String &module_name)
|
||||
{
|
||||
ecs.component<growth_regions>();
|
||||
ecs.component<region_tree>();
|
||||
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(flecs::OnUpdate);
|
||||
GraphFilter.disable();
|
||||
flecs::entity GraphGridPrepare = ecs.entity("GraphGridPrepare")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(GraphSolve);
|
||||
|
||||
#if 0
|
||||
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
|
||||
"CreateGrid")
|
||||
.kind(GraphSolve)
|
||||
.write<WorldEditor::components::buildings_layout_grid>()
|
||||
.each([this](flecs::iter &it, size_t count,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_size &size) {
|
||||
struct grid_misc grid;
|
||||
flecs::entity graph_e = it.entity(count);
|
||||
graph_e.world().defer_suspend();
|
||||
flecs::log::warn("creating grid for: %s",
|
||||
graph_e.path().c_str());
|
||||
flecs::entity grid_base_e = get_layout_grid_base();
|
||||
flecs::entity grid_e =
|
||||
grid_base_e.lookup(graph_e.name());
|
||||
assert(grid_e.is_valid());
|
||||
flecs::log::warn("creating grid for: %s: %s",
|
||||
graph_e.path().c_str(),
|
||||
grid_e.path().c_str());
|
||||
/* starting at grid center */
|
||||
const List<Pair<int, flecs::entity_t> >::Element *me =
|
||||
size.floors.front();
|
||||
while (me) {
|
||||
flecs::query<const WorldEditor::components::
|
||||
buildings_layout_area>
|
||||
q = graph_e.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_area>()
|
||||
.with(flecs::ChildOf,
|
||||
me->get().second)
|
||||
.scope_open()
|
||||
.with<WorldEditor::components::
|
||||
buildings_layout_zone>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::
|
||||
buildings_layout_unit>()
|
||||
.scope_close()
|
||||
.build();
|
||||
q.each([size,
|
||||
&grid](flecs::entity ce,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_area
|
||||
&area) {
|
||||
flecs::log::warn(
|
||||
"generating positions for: %s",
|
||||
ce.path().c_str());
|
||||
grid.filter_candidates(ce, area.area,
|
||||
size);
|
||||
});
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(me->get().second);
|
||||
flecs::entity grid_floor_e =
|
||||
grid.get_grid_floor(grid_e,
|
||||
base_floor_e);
|
||||
create_floor_components(grid_floor_e,
|
||||
base_floor_e, size);
|
||||
grid.place_regions(grid_floor_e);
|
||||
|
||||
me = me->next();
|
||||
}
|
||||
graph_e.world().defer_resume();
|
||||
});
|
||||
#endif
|
||||
ecs.system("AssembleSkeletonEnd")
|
||||
.kind(GraphSolve)
|
||||
.run([module_name](flecs::iter &it) {
|
||||
print_line("Assembling skeleton done...");
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphSolveZones")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.disable();
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphFilter")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.enable();
|
||||
EditorEvent::get_singleton()->event.emit(
|
||||
"update_layout_view", varray());
|
||||
// assert(false);
|
||||
});
|
||||
#if 0
|
||||
|
||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||
growth_regions>("GrowFloorRectRegions")
|
||||
.kind(0)
|
||||
.each([this](flecs::entity floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor
|
||||
&fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grid;
|
||||
grid.grow_region_rects(this, floor_e, fl, g);
|
||||
grid.place_region_cells(this, floor_e, fl, g);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
||||
"GrowFloorRegions")
|
||||
.kind(0)
|
||||
.each([this](flecs::entity floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor
|
||||
&fl) {
|
||||
/* TODO: limit growth per region too */
|
||||
struct grid_calc grid(fl.grid_size);
|
||||
if (fl.size_left <= 0)
|
||||
return;
|
||||
flecs::query<const WorldEditor::components::
|
||||
buildings_layout_grid_cell>
|
||||
q = floor_e.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.with(flecs::ChildOf, floor_e)
|
||||
.without<WorldEditor::components::
|
||||
final_cell>()
|
||||
.build();
|
||||
q.each([this, &floor_e, &fl,
|
||||
&grid](flecs::entity et,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell &cell) {
|
||||
int index = cell.index;
|
||||
assert(et.is_valid());
|
||||
int i;
|
||||
LocalVector<int> candidates;
|
||||
candidates.resize(8);
|
||||
grid.get_cadidates(cell.index,
|
||||
candidates.ptr());
|
||||
int extended = 0;
|
||||
for (i = 0; i < (int)candidates.size(); i++) {
|
||||
if (have_cell(floor_e, candidates[i]))
|
||||
continue;
|
||||
queue_grow_cell(et, candidates[i]);
|
||||
extended++;
|
||||
}
|
||||
if (extended == 0)
|
||||
et.add<WorldEditor::components::
|
||||
final_cell>();
|
||||
print_line("size: " + itos(grid.grid_size) +
|
||||
" index: " + itos(index));
|
||||
});
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||
"GrowRegions")
|
||||
.kind(0)
|
||||
.without<WorldEditor::components::final_cell>()
|
||||
.read<WorldEditor::components::buildings_layout_grid_size>()
|
||||
.write<WorldEditor::components::buildings_layout_grid_cell>()
|
||||
.write<WorldEditor::components::buildings_layout_grid_floor>()
|
||||
.write<WorldEditor::components::buildings_layout_grid_queue>()
|
||||
.each([this](flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell &cell) {
|
||||
e.world().defer_suspend();
|
||||
int index = cell.index;
|
||||
assert(e.is_valid());
|
||||
flecs::entity floor_e = e.parent();
|
||||
assert(floor_e.is_valid());
|
||||
|
||||
flecs::entity grid_e = floor_e.parent();
|
||||
assert(grid_e.is_valid());
|
||||
String layout_name(grid_e.name());
|
||||
flecs::entity base_e = get_layout_base();
|
||||
flecs::entity layout_e =
|
||||
base_e.lookup(layout_name.ascii().ptr());
|
||||
assert(layout_e.is_valid());
|
||||
struct grid_calc grid(layout_e);
|
||||
int i;
|
||||
LocalVector<int> candidates;
|
||||
candidates.resize(8);
|
||||
grid.get_cadidates(cell.index, candidates.ptr());
|
||||
int extended = 0;
|
||||
for (i = 0; i < (int)candidates.size(); i++) {
|
||||
if (have_cell(floor_e, candidates[i]))
|
||||
continue;
|
||||
queue_grow_cell(e, candidates[i]);
|
||||
extended++;
|
||||
}
|
||||
if (extended == 0)
|
||||
e.add<WorldEditor::components::final_cell>();
|
||||
print_line("size: " + itos(grid.grid_size) +
|
||||
" index: " + itos(index));
|
||||
e.world().defer_resume();
|
||||
});
|
||||
#endif
|
||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||
WorldEditor::components::buildings_layout_grid_queue>(
|
||||
"GrowCommitQueue")
|
||||
.kind(0)
|
||||
.each([this](flecs::entity e,
|
||||
WorldEditor::components::buildings_layout_grid_floor
|
||||
&fl,
|
||||
WorldEditor::components::buildings_layout_grid_queue
|
||||
&queue) {
|
||||
List<Pair<flecs::entity_t, int> >::Element *me =
|
||||
queue.queue.front();
|
||||
while (me) {
|
||||
flecs::entity seed_e =
|
||||
e.world().entity(me->get().first);
|
||||
int id = me->get().second;
|
||||
if (!fl.cells.has(id)) {
|
||||
grow_cell(seed_e, id);
|
||||
fl.cells.insert(id);
|
||||
}
|
||||
me = me->next();
|
||||
}
|
||||
queue.queue.clear();
|
||||
e.remove<WorldEditor::components::
|
||||
buildings_layout_grid_queue>();
|
||||
});
|
||||
ecs.system("RunGrow")
|
||||
.immediate()
|
||||
.write<WorldEditor::components::buildings_layout_grid_floor>()
|
||||
.write<WorldEditor::components::buildings_layout_grid_size>()
|
||||
.write<growth_regions>()
|
||||
.kind(GraphFilter)
|
||||
.run([module_name, this](flecs::iter &it) {
|
||||
flecs::world &&ecs = it.world();
|
||||
it.world().defer_suspend();
|
||||
struct queries queries(ecs);
|
||||
flecs::log::dbg("Creating regions grow...");
|
||||
queries.get_qp().each(
|
||||
[this, &queries,
|
||||
module_name](flecs::iter &it2, size_t count,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_size
|
||||
&size) {
|
||||
struct grid_misc grid;
|
||||
// grid.subregions_init(it2.world());
|
||||
flecs::entity graph_e =
|
||||
it2.entity(count);
|
||||
flecs::log::warn(
|
||||
"creating grid for: %s",
|
||||
graph_e.path().c_str());
|
||||
flecs::entity grid_base_e =
|
||||
get_layout_grid_base();
|
||||
flecs::entity grid_e =
|
||||
grid_base_e.lookup(
|
||||
graph_e.name());
|
||||
assert(grid_e.is_valid());
|
||||
flecs::log::warn(
|
||||
"creating grid for: %s: %s",
|
||||
graph_e.path().c_str(),
|
||||
grid_e.path().c_str());
|
||||
/* starting at grid center */
|
||||
queries.build_subregions(grid_e, grid,
|
||||
size);
|
||||
struct grow_job_queue job_queue(
|
||||
grid_e, queries, size,
|
||||
module_name);
|
||||
job_queue.iterate();
|
||||
// assert(false);
|
||||
});
|
||||
#if 0
|
||||
assert(false);
|
||||
flecs::log::dbg("Running grow...");
|
||||
qr.each([this](flecs::entity grid_floor_e,
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grd;
|
||||
if (g.complete)
|
||||
return;
|
||||
grd.grow_region_rects(this, grid_floor_e, fl,
|
||||
g);
|
||||
grd.place_region_cells(this, grid_floor_e, fl,
|
||||
g);
|
||||
});
|
||||
#endif
|
||||
it.world()
|
||||
.system(it.world().lookup(
|
||||
(module_name + "::GrowCommitQueue")
|
||||
.ascii()
|
||||
.ptr()))
|
||||
.run();
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphFilter")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.disable();
|
||||
it.world().defer_resume();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,456 +0,0 @@
|
||||
#include "base_data.h"
|
||||
#include "world_editor.h"
|
||||
#include "building_layout_graph.h"
|
||||
#include "grid_misc.h"
|
||||
#include "graph_module.h"
|
||||
|
||||
void BuildingLayoutGraph::graph_module::room_growth_module(
|
||||
flecs::world &ecs, const String &module_name)
|
||||
{
|
||||
flecs::entity GraphFilter =
|
||||
ecs.lookup((module_name + "::GraphFilter").ascii().ptr());
|
||||
assert(GraphFilter.is_valid());
|
||||
flecs::entity GraphGrowUnitAreas = ecs.entity("GraphGrowUnitAreas")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(flecs::OnUpdate);
|
||||
GraphGrowUnitAreas.disable();
|
||||
flecs::entity GraphMarkData = ecs.entity("GraphMarkData")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(flecs::OnUpdate);
|
||||
GraphMarkData.disable();
|
||||
flecs::entity GraphProcessRooms = ecs.entity("GraphProcessRooms")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(flecs::OnUpdate);
|
||||
GraphProcessRooms.disable();
|
||||
ecs.system<const WorldEditor::components::buildings_layout_unit>(
|
||||
"AllocateUnitGrow")
|
||||
.kind(GraphGrowUnitAreas)
|
||||
.each([](flecs::entity ec,
|
||||
const WorldEditor::components::buildings_layout_unit
|
||||
&unit) {
|
||||
ec.world()
|
||||
.query_builder<const WorldEditor::components::
|
||||
buildings_layout_zone>()
|
||||
.build()
|
||||
.each([](flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_zone &zone) {
|
||||
// assert(false);
|
||||
});
|
||||
});
|
||||
|
||||
ecs.system("CheckGrow").kind(GraphFilter).run([module_name](flecs::iter &it) {
|
||||
int failed_zones = 0, total_zones = 0;
|
||||
it.world()
|
||||
.query_builder<const WorldEditor::components::
|
||||
buildings_layout_zone>()
|
||||
.build()
|
||||
.each([&failed_zones, &total_zones](
|
||||
flecs::entity ec,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_zone &zone) {
|
||||
int count = 0;
|
||||
ec.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.with<WorldEditor::components::belongs>(
|
||||
ec)
|
||||
.build()
|
||||
.each([&count](
|
||||
flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
count++;
|
||||
});
|
||||
if (count == 0)
|
||||
failed_zones++;
|
||||
total_zones++;
|
||||
});
|
||||
if (failed_zones > 0)
|
||||
flecs::log::err("failed to allocate zones: %d/%d",
|
||||
failed_zones, total_zones);
|
||||
flecs::query<const WorldEditor::components::
|
||||
buildings_layout_grid_floor>
|
||||
q = it.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
.build();
|
||||
int count_left = 0;
|
||||
int count_run = 0;
|
||||
q.each([&count_left,
|
||||
&count_run](flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_floor &fl) {
|
||||
count_run++;
|
||||
count_left += MAX(0, fl.size_left);
|
||||
});
|
||||
// assert(false);
|
||||
if (count_run > 0 && count_left <= 0 && failed_zones == 0) {
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphFilter")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.disable();
|
||||
print_line("Grow done");
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphMarkData")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.enable();
|
||||
print_line("Mark started...");
|
||||
} else if (count_run > 0 && count_left <= 0 &&
|
||||
failed_zones > 0) {
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphFilter")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.disable();
|
||||
print_line("Grow done");
|
||||
it.world()
|
||||
.lookup((module_name + "::GraphGrowUnitAreas")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.enable();
|
||||
print_line("Grow unit started...");
|
||||
}
|
||||
});
|
||||
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||
"MarkExternalWall")
|
||||
.kind(GraphMarkData)
|
||||
.without<WorldEditor::components::outside_wall>()
|
||||
.read<WorldEditor::components::buildings_layout_grid_floor>()
|
||||
.write<WorldEditor::components::outside_wall>()
|
||||
.write<WorldEditor::components::final_cell>()
|
||||
.each([](flecs::entity e,
|
||||
const WorldEditor::components::buildings_layout_grid_cell
|
||||
&cell) {
|
||||
int grid_size =
|
||||
e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
int i;
|
||||
Vector2i position(cell.index % grid_size,
|
||||
cell.index / grid_size);
|
||||
Vector2 west(position.x - 1, position.y);
|
||||
Vector2 north(position.x, position.y - 1);
|
||||
Vector2 east(position.x + 1, position.y);
|
||||
Vector2 south(position.x, position.y + 1);
|
||||
int west_id = west.x + grid_size * west.y;
|
||||
int north_id = north.x + grid_size * north.y;
|
||||
int east_id = east.x + grid_size * east.y;
|
||||
int south_id = south.x + grid_size * south.y;
|
||||
std::vector<int> neighbors = { west_id, north_id,
|
||||
east_id, south_id };
|
||||
bool outside = false;
|
||||
bool border = false;
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
if (!e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->cells.has(id)) {
|
||||
outside = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
String neighbor_name = "cell_" + itos(id);
|
||||
flecs::entity neighbor_e = e.parent().lookup(
|
||||
neighbor_name.ascii().ptr());
|
||||
if (!neighbor_e.is_valid())
|
||||
continue;
|
||||
const WorldEditor::components::buildings_layout_grid_cell
|
||||
*neighbor_cell = neighbor_e.get<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_cell>();
|
||||
if (cell.type != neighbor_cell->type) {
|
||||
border = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outside)
|
||||
e.add<WorldEditor::components::outside_wall>();
|
||||
else
|
||||
e.add<WorldEditor::components::final_cell>();
|
||||
if (border)
|
||||
e.add<WorldEditor::components::border>();
|
||||
print_line("outside: " + itos(outside));
|
||||
print_line("position: " + (position.operator String()));
|
||||
print_line("grid size: " + itos(grid_size));
|
||||
print_line("tile index: " + itos(cell.index));
|
||||
});
|
||||
ecs.system("CheckMark")
|
||||
.kind(GraphMarkData)
|
||||
.run([module_name](flecs::iter &it) {
|
||||
int tile_count = 0, inside_count = 0, wall_count = 0;
|
||||
it.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.build()
|
||||
.each([&tile_count, &inside_count, &wall_count](
|
||||
flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
tile_count++;
|
||||
if (e.has<WorldEditor::components::
|
||||
outside_wall>())
|
||||
wall_count++;
|
||||
if (e.has<WorldEditor::components::
|
||||
final_cell>())
|
||||
inside_count++;
|
||||
});
|
||||
if (tile_count > 0 && wall_count > 0 &&
|
||||
inside_count > 0 &&
|
||||
tile_count == wall_count + inside_count) {
|
||||
it.world()
|
||||
.lookup((module_name +
|
||||
"::GraphMarkData")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.disable();
|
||||
it.world()
|
||||
.lookup((module_name +
|
||||
"::GraphProcessRooms")
|
||||
.ascii()
|
||||
.ptr())
|
||||
.enable();
|
||||
}
|
||||
});
|
||||
struct prio_queue {
|
||||
HashMap<int, flecs::entity> entities;
|
||||
Set<int> tile_selection[4];
|
||||
Vector<int> tile_selection_array[4];
|
||||
struct make_random r;
|
||||
bool dirty;
|
||||
prio_queue()
|
||||
: r(make_random(100))
|
||||
, dirty(true)
|
||||
{
|
||||
}
|
||||
void add_tile(int prio, int id, flecs::entity ec)
|
||||
{
|
||||
if (!tile_selection[prio].has(id))
|
||||
tile_selection[prio].insert(id);
|
||||
if (!entities.has(id))
|
||||
entities[id] = ec;
|
||||
dirty = true;
|
||||
}
|
||||
void update()
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 4; i++) {
|
||||
tile_selection_array[i].resize(
|
||||
tile_selection[i].size());
|
||||
j = 0;
|
||||
Set<int>::Element *m =
|
||||
tile_selection[i].front();
|
||||
while (m) {
|
||||
tile_selection_array[i].write[j++] =
|
||||
m->get();
|
||||
m = m->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
void dump()
|
||||
{
|
||||
if (dirty) {
|
||||
update();
|
||||
dirty = false;
|
||||
}
|
||||
print_line("0: " +
|
||||
itos(tile_selection_array[0].size()));
|
||||
print_line("1: " +
|
||||
itos(tile_selection_array[1].size()));
|
||||
print_line("2: " +
|
||||
itos(tile_selection_array[2].size()));
|
||||
}
|
||||
int get_random_tile(int prio)
|
||||
{
|
||||
assert(tile_selection[prio].size() > 0);
|
||||
int sel = r.get() % tile_selection[prio].size();
|
||||
int id = tile_selection_array[prio][sel];
|
||||
assert(entities.has(id));
|
||||
tile_selection_array[prio].erase(id);
|
||||
tile_selection[prio].erase(id);
|
||||
return id;
|
||||
}
|
||||
void delete_neighbors(int id)
|
||||
{
|
||||
int i, j;
|
||||
flecs::entity selected_e = entities[id];
|
||||
int grid_size =
|
||||
selected_e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
Vector2i base(id % grid_size, id / grid_size);
|
||||
for (i = -1; i < 2; i++)
|
||||
for (j = -1; j < 2; j++) {
|
||||
if (i == 0 && j == 0)
|
||||
continue;
|
||||
Vector2i neighbor =
|
||||
base + Vector2i(i, j);
|
||||
int neighbor_id =
|
||||
neighbor.x +
|
||||
grid_size * neighbor.y;
|
||||
tile_selection_array[0].erase(
|
||||
neighbor_id);
|
||||
tile_selection[0].erase(neighbor_id);
|
||||
if (!tile_selection[3].has(
|
||||
neighbor_id)) {
|
||||
tile_selection_array[3]
|
||||
.push_back(neighbor_id);
|
||||
tile_selection[3].insert(
|
||||
neighbor_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
int take_tile()
|
||||
{
|
||||
if (dirty) {
|
||||
update();
|
||||
dirty = false;
|
||||
}
|
||||
if (tile_selection[0].size() > 0) {
|
||||
int id = get_random_tile(0);
|
||||
delete_neighbors(id);
|
||||
return id;
|
||||
} else {
|
||||
int prio;
|
||||
flecs::log::warn(
|
||||
"out of normal tiles, using outside wall and zone borders");
|
||||
for (prio = 1; prio < 4; prio++) {
|
||||
if (tile_selection[prio].size() > 0) {
|
||||
int id = get_random_tile(prio);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
flecs::log::err("failed to allocate room initial tile");
|
||||
return -1;
|
||||
}
|
||||
flecs::entity get_entity(int id)
|
||||
{
|
||||
assert(entities.has(id));
|
||||
return entities[id];
|
||||
}
|
||||
int get_total_size()
|
||||
{
|
||||
int ret = 0, i;
|
||||
for (i = 0; i < 4; i++)
|
||||
ret += tile_selection[i].size();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
ecs.system<const WorldEditor::components::buildings_layout_zone,
|
||||
const WorldEditor::components::buildings_layout_floor_index>(
|
||||
"ProcessFloor0Rooms")
|
||||
.kind(GraphProcessRooms)
|
||||
.read<WorldEditor::components::belongs>()
|
||||
.read<WorldEditor::components::outside_wall>()
|
||||
.read<WorldEditor::components::border>()
|
||||
.each([](flecs::entity e,
|
||||
const WorldEditor::components::buildings_layout_zone
|
||||
&zone,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_floor_index &idx) {
|
||||
if (idx.index != 0)
|
||||
return;
|
||||
// make_random r(1001);
|
||||
struct prio_queue prio;
|
||||
e.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.with<WorldEditor::components::belongs>(e)
|
||||
.without<WorldEditor::components::outside_wall>()
|
||||
.without<WorldEditor::components::border>()
|
||||
.build()
|
||||
.each([&prio](flecs::entity ec,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
prio.add_tile(0, cell.index, ec);
|
||||
});
|
||||
e.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.with<WorldEditor::components::belongs>(e)
|
||||
.without<WorldEditor::components::outside_wall>()
|
||||
.with<WorldEditor::components::border>()
|
||||
.build()
|
||||
.each([&prio](flecs::entity ec,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
prio.add_tile(1, cell.index, ec);
|
||||
});
|
||||
e.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.with<WorldEditor::components::belongs>(e)
|
||||
.with<WorldEditor::components::outside_wall>()
|
||||
.build()
|
||||
.each([&prio](flecs::entity ec,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
prio.add_tile(2, cell.index, ec);
|
||||
});
|
||||
prio.update();
|
||||
prio.dump();
|
||||
if (prio.get_total_size() == 0) {
|
||||
flecs::log::err(
|
||||
"no tiles allocated for zone: %s",
|
||||
e.path().c_str());
|
||||
return;
|
||||
}
|
||||
int count = 0, assigned_count = 0;
|
||||
e.world()
|
||||
.query_builder<const WorldEditor::components::
|
||||
buildings_layout_room>()
|
||||
.with(flecs::ChildOf, e)
|
||||
.build()
|
||||
.each([&prio, &count, &assigned_count](
|
||||
flecs::entity ec,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_room
|
||||
&room) {
|
||||
int id = prio.take_tile();
|
||||
if (id >= 0) {
|
||||
flecs::entity selected_e =
|
||||
prio.get_entity(id);
|
||||
int mcount = 0;
|
||||
selected_e.each<
|
||||
WorldEditor::components::
|
||||
belongs_room>(
|
||||
[&mcount](flecs::entity
|
||||
e) {
|
||||
mcount++;
|
||||
});
|
||||
assert(mcount == 0);
|
||||
selected_e.add<
|
||||
WorldEditor::components::
|
||||
belongs_room>(
|
||||
ec);
|
||||
assigned_count++;
|
||||
}
|
||||
count++;
|
||||
});
|
||||
if (assigned_count < count)
|
||||
flecs::log::err(
|
||||
"not all rooms were assigned: %d < %d",
|
||||
assigned_count, count);
|
||||
});
|
||||
}
|
||||
713
src/modules/stream/ui/grid_misc.cpp
Normal file
713
src/modules/stream/ui/grid_misc.cpp
Normal file
@@ -0,0 +1,713 @@
|
||||
#include <vector>
|
||||
#include <core/math/vector2.h>
|
||||
#include <core/math/rect2.h>
|
||||
#include "world_editor.h"
|
||||
#include "graph_module.h"
|
||||
#include "growth_regions.h"
|
||||
#include "grid_misc.h"
|
||||
|
||||
void grid_misc::get_dim_candidates(const Vector2i &base, int dim,
|
||||
Vector2i *candidates)
|
||||
{
|
||||
int i;
|
||||
std::vector<Vector2i> candidates_data = {
|
||||
/* clang-format off */
|
||||
{ base.x + dim, base.y },
|
||||
{ base.x, base.y + dim },
|
||||
{ base.x - dim, base.y },
|
||||
{ base.x, base.y - dim },
|
||||
{ base.x + dim, base.y },
|
||||
{ base.x, base.y + dim },
|
||||
{ base.x - dim, base.y },
|
||||
{ base.x, base.y - dim },
|
||||
/* clang-format on */
|
||||
};
|
||||
for (i = 0; i < (int)candidates_data.size(); i++)
|
||||
candidates[i] = candidates_data[i];
|
||||
}
|
||||
|
||||
int grid_misc::get_floor_index(flecs::entity e) const
|
||||
{
|
||||
return e.get<WorldEditor::components::buildings_layout_floor_index>()
|
||||
->index;
|
||||
}
|
||||
|
||||
flecs::entity grid_misc::get_grid_floor(flecs::entity grid_e,
|
||||
flecs::entity graph_floor_e) const
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(graph_floor_e.is_valid());
|
||||
int floor_index = get_floor_index(graph_floor_e);
|
||||
String floor_name = "floor_" + itos(floor_index);
|
||||
// flecs::log::dbg("floor: %s", floor_name.ascii().ptr());
|
||||
flecs::entity floor_e = grid_e.lookup(floor_name.ascii().ptr());
|
||||
assert(floor_e.is_valid());
|
||||
return floor_e;
|
||||
}
|
||||
|
||||
bool grid_misc::check_duplicates() const
|
||||
{
|
||||
int i, j;
|
||||
bool result = true;
|
||||
for (i = 0; i < (int)positions.size(); i++)
|
||||
for (j = 0; j < (int)positions.size(); j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
if (positions[i].second == positions[j].second) {
|
||||
flecs::log::err("duplicate positions");
|
||||
result = false;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void grid_misc::place_regions(flecs::entity grid_floor_e)
|
||||
{
|
||||
int i;
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
// flecs::log::dbg("###=== %s", grid_floor_e.path().c_str());
|
||||
flecs::entity grid_e = grid_floor_e.parent();
|
||||
assert(grid_e.is_valid());
|
||||
growth_regions::region parent_reg;
|
||||
parent_reg.can_grow = false;
|
||||
parent_reg.complete = true;
|
||||
parent_reg.rect.position = Vector2i();
|
||||
parent_reg.rect.size = Vector2i(grid_size, grid_size);
|
||||
parent_reg.can_grow_square = false;
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
int parent_index = g->parent_regions.size();
|
||||
g->parent_regions.push_back(parent_reg);
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
int cell_id = positions[i].second.x +
|
||||
grid_size * positions[i].second.y;
|
||||
flecs::entity region_e =
|
||||
grid_e.world().entity(positions[i].first);
|
||||
assert(region_e.is_valid());
|
||||
Rect2i check;
|
||||
check.position = positions[i].second;
|
||||
check.size = Vector2i(1, 1);
|
||||
// flecs::log::dbg("%s ->region: %s cell_id %d",
|
||||
// grid_floor_e.path().c_str(),
|
||||
// region_e.path().c_str(), cell_id);
|
||||
assert(g->check_region(-1, check));
|
||||
flecs::entity cell_e =
|
||||
g->create_cell(grid_floor_e, region_e, cell_id);
|
||||
assert(cell_e.is_valid());
|
||||
flecs::log::warn("grid cell: %s", cell_e.path().c_str());
|
||||
float area = get_entity_area(region_e);
|
||||
// flecs::log::dbg("region: %s: parent: %s",
|
||||
// region_e.path().c_str(),
|
||||
// region_e.parent().path().c_str());
|
||||
g->create_region(grid_floor_e, cell_e, region_e.parent(),
|
||||
region_e, positions[i].second, area,
|
||||
parent_index);
|
||||
flecs::log::warn("grid cell: %s", cell_e.path().c_str());
|
||||
}
|
||||
// flecs::log::dbg("###=== %s done", grid_floor_e.path().c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
void grid_misc::place_regions_common(flecs::entity parent_e,
|
||||
flecs::entity grid_floor_e,
|
||||
int parent_index)
|
||||
{
|
||||
int i;
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
// flecs::log::dbg("###=== %s", grid_floor_e.path().c_str());
|
||||
flecs::entity grid_e = grid_floor_e.parent();
|
||||
assert(grid_e.is_valid());
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
assert(g->parent_regions[parent_index].rect.has_point(
|
||||
positions[i].second));
|
||||
int cell_id = positions[i].second.x +
|
||||
grid_size * positions[i].second.y;
|
||||
flecs::entity region_e =
|
||||
grid_e.world().entity(positions[i].first);
|
||||
assert(region_e.is_valid());
|
||||
RegionRect2i check;
|
||||
check.position = positions[i].second;
|
||||
check.size = Vector2i(1, 1);
|
||||
// flecs::log::dbg("%s ->region: %s cell_id %d",
|
||||
// grid_floor_e.path().c_str(),
|
||||
// region_e.path().c_str(), cell_id);
|
||||
assert(g->check_region(-1, check));
|
||||
flecs::entity cell_e = g->update_cell(grid_floor_e, parent_e,
|
||||
region_e, cell_id);
|
||||
if (cell_e.is_valid()) {
|
||||
float area = get_entity_area(region_e);
|
||||
// flecs::log::dbg(
|
||||
// "region: %s: parent: %s",
|
||||
// region_e.path().c_str(),
|
||||
// region_e.parent().path().c_str());
|
||||
g->create_region(grid_floor_e, cell_e, parent_e,
|
||||
region_e, positions[i].second, area,
|
||||
parent_index);
|
||||
// flecs::log::warn("grid cell: %s",
|
||||
// cell_e.path().c_str());
|
||||
} else {
|
||||
flecs::log::err("unable to create region");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
// flecs::log::dbg("###=== %s done", grid_floor_e.path().c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool grid_misc::process_candidates(flecs::entity ce, const Vector2i &base,
|
||||
float area, flecs::entity_t base_et, int dim,
|
||||
const RegionRect2i &clip, bool tight)
|
||||
{
|
||||
int j;
|
||||
assert(dim > 1);
|
||||
int base_radius = get_base_radius(ce.world(), base_et);
|
||||
base_radius = MAX(1, base_radius);
|
||||
int local_radius = (int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||
4; /* grid conversion */
|
||||
local_radius = MAX(1, local_radius);
|
||||
// int dim = base_radius + local_radius;
|
||||
// dim = MAX(4, dim);
|
||||
Vector2i candidates[8];
|
||||
assert(clip.has_point(base));
|
||||
get_dim_candidates(base, dim, &candidates[0]);
|
||||
for (j = 0; j < (int)(sizeof(candidates) / sizeof(candidates[0]));
|
||||
j++) {
|
||||
print_line("base: " + itos(base.x) + ", " + itos(base.y));
|
||||
print_line("possible candidate: " + itos(candidates[j].x) +
|
||||
", " + itos(candidates[j].y));
|
||||
if (!clip.has_point(candidates[j])) {
|
||||
print_line("clipped by grid field");
|
||||
print_line(clip.operator String());
|
||||
continue;
|
||||
}
|
||||
if (!clip.has_point(candidates[j])) {
|
||||
flecs::log::dbg("clipped by clip rect");
|
||||
continue;
|
||||
}
|
||||
if (!check_candidates_tolerance(candidates[j])) {
|
||||
print_line("too close to existing positions");
|
||||
continue;
|
||||
}
|
||||
if (!check_candidate(candidates[j])) {
|
||||
// print_line(
|
||||
// "too close to existing positions (rect)");
|
||||
continue;
|
||||
}
|
||||
// print_line("valid candidate: " + itos(candidates[j].x) +
|
||||
// ", " + itos(candidates[j].y));
|
||||
// flecs::log::dbg(
|
||||
// "accepting candidate: %s",
|
||||
// (candidates[j].operator String()).ascii().ptr());
|
||||
if (!tight)
|
||||
accept_candidate(ce, candidates[j], area);
|
||||
else
|
||||
accept_candidate2(ce, candidates[j]);
|
||||
}
|
||||
if (accepted.size() == 0) {
|
||||
Vector2i current = base;
|
||||
Set<Vector2i> generated;
|
||||
int candidate_count = 0;
|
||||
int max_count = 1000;
|
||||
for (j = 0; j < positions.size(); j++) {
|
||||
assert(clip.has_point(positions[j].second));
|
||||
generated.insert(positions[j].second);
|
||||
}
|
||||
for (j = 0;
|
||||
j < (int)(sizeof(candidates) / sizeof(candidates[0]));
|
||||
j++) {
|
||||
do {
|
||||
candidates[j] = clip.position +
|
||||
Vector2i(r.get() % clip.size.x,
|
||||
r.get() % clip.size.y);
|
||||
max_count--;
|
||||
if (max_count < 0)
|
||||
break;
|
||||
} while (generated.has(candidates[j]) ||
|
||||
!clip.has_point(candidates[j]));
|
||||
if (max_count >= 0) {
|
||||
assert(!generated.has(candidates[j]));
|
||||
generated.insert(candidates[j]);
|
||||
flecs::log::dbg(
|
||||
"candidate: %d: %s -> %s", j,
|
||||
(clip.operator String()).ascii().ptr(),
|
||||
(candidates[j].operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
candidate_count++;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < candidate_count; j++) {
|
||||
print_line("!!base: " + itos(base.x) + ", " +
|
||||
itos(base.y));
|
||||
print_line("!!possible candidate: " +
|
||||
itos(candidates[j].x) + ", " +
|
||||
itos(candidates[j].y));
|
||||
if (!clip.has_point(candidates[j])) {
|
||||
print_line("!!clipped by grid field");
|
||||
print_line(clip.operator String());
|
||||
continue;
|
||||
}
|
||||
if (!clip.has_point(candidates[j])) {
|
||||
flecs::log::dbg("!!clipped by clip rect");
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (!check_candidate(candidates[j])) {
|
||||
print_line(
|
||||
"!!too close to existing positions (rect)");
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
// print_line("valid candidate: " + itos(candidates[j].x) +
|
||||
// ", " + itos(candidates[j].y));
|
||||
// flecs::log::dbg(
|
||||
// "accepting candidate: %s",
|
||||
// (candidates[j].operator String()).ascii().ptr());
|
||||
if (!tight)
|
||||
accept_candidate(ce, candidates[j], area);
|
||||
else
|
||||
accept_candidate2(ce, candidates[j]);
|
||||
assert(clip.has_point(candidates[j]));
|
||||
}
|
||||
if (accepted.size() == 0)
|
||||
flecs::log::err("all candidates were rejected");
|
||||
}
|
||||
if (accepted.size() > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void grid_misc::filter_candidates(flecs::entity ce, float area,
|
||||
const RegionRect2i &clip_rect)
|
||||
{
|
||||
if (positions.empty()) {
|
||||
/* starting at grid center */
|
||||
Vector2i start_pos(clip_rect.position.x + clip_rect.size.x / 2,
|
||||
clip_rect.position.y + clip_rect.size.y / 2);
|
||||
positions.push_back(
|
||||
Pair<flecs::entity_t, Vector2i>(ce.id(), start_pos));
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
int which = which_position();
|
||||
const Vector2i &base = positions[which].second;
|
||||
flecs::entity_t base_et = positions[which].first;
|
||||
int base_radius = get_base_radius(ce.world(), base_et);
|
||||
base_radius = MAX(1, base_radius);
|
||||
int local_radius = (int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||
4; /* grid conversion */
|
||||
local_radius = MAX(1, local_radius);
|
||||
/* minimum distance between region positions */
|
||||
int dim = base_radius + local_radius;
|
||||
dim = MAX(2, dim);
|
||||
int md = 1;
|
||||
int clip_size = MIN(clip_rect.size.x, clip_rect.size.y);
|
||||
assert(dim > 1);
|
||||
|
||||
if (clip_size > 30)
|
||||
md = 8;
|
||||
else if (clip_size > 20)
|
||||
md = 6;
|
||||
else if (clip_size > 15)
|
||||
md = 4;
|
||||
else if (clip_size > 10)
|
||||
md = 2;
|
||||
if (clip_size < 6)
|
||||
md = 0;
|
||||
Rect2i clip(clip_rect.position.x + md,
|
||||
clip_rect.position.y + md,
|
||||
clip_rect.size.x - md * 2,
|
||||
clip_rect.size.y - md * 2);
|
||||
#if 0
|
||||
Rect2i dim_rect_min(base.x - dim, base.y - dim, dim,
|
||||
dim),
|
||||
dim_rect_max(base.x, base.y, dim, dim);
|
||||
dim_rect_min = clip.clip(dim_rect_min);
|
||||
dim_rect_max = clip.clip(dim_rect_max);
|
||||
int dim_min =
|
||||
MAX(dim_rect_min.size.x, dim_rect_min.size.y);
|
||||
int dim_max =
|
||||
MAX(dim_rect_max.size.x, dim_rect_max.size.y);
|
||||
int avg_dim = (dim_min + dim_max) / 2;
|
||||
dim = MIN(dim, avg_dim - 1);
|
||||
#endif
|
||||
// flecs::log::dbg("dim=%d", dim);
|
||||
assert(dim > 1);
|
||||
assert(clip.has_point(base));
|
||||
// flecs::log::warn(
|
||||
// "filter_candidates: %d %d / %s / %s",
|
||||
// clip_size, dim,
|
||||
// (base.operator String()).ascii().ptr(),
|
||||
// (clip.operator String()).ascii().ptr());
|
||||
// flecs::log::warn("clip: %s base: %s dim: %d",
|
||||
// (clip.operator String()).ascii().ptr(),
|
||||
// (base.operator String()).ascii().ptr(),
|
||||
// dim);
|
||||
if (!(clip.has_point(base + Vector2i(dim, dim)) ||
|
||||
clip.has_point(base + Vector2i(dim, 0)) ||
|
||||
clip.has_point(base + Vector2i(0, dim)) ||
|
||||
clip.has_point(base + Vector2i(-dim, -dim)) ||
|
||||
clip.has_point(base + Vector2i(-dim, 0)) ||
|
||||
clip.has_point(base + Vector2i(0, -dim))))
|
||||
dim = MIN(2, dim);
|
||||
assert(clip.has_point(base));
|
||||
assert(clip.has_point(base + Vector2i(dim, dim)) ||
|
||||
clip.has_point(base + Vector2i(dim, 0)) ||
|
||||
clip.has_point(base + Vector2i(0, dim)) ||
|
||||
clip.has_point(base + Vector2i(-dim, -dim)) ||
|
||||
clip.has_point(base + Vector2i(-dim, 0)) ||
|
||||
clip.has_point(base + Vector2i(0, -dim)));
|
||||
if (dim < 4)
|
||||
process_candidates(ce, base, area, base_et, dim, clip,
|
||||
true);
|
||||
else
|
||||
process_candidates(ce, base, area, base_et, dim, clip,
|
||||
false);
|
||||
if (accepted.size() > 0) {
|
||||
assert(accepted.size() > 0);
|
||||
const Vector2i &selected = accepted[which_selected()];
|
||||
assert(check_candidates_tolerance(selected));
|
||||
Pair<flecs::entity_t, Vector2i> m(ce.id(), selected);
|
||||
check_candidate(selected);
|
||||
assert(clip_rect.encloses(
|
||||
Rect2i(m.second, Vector2i(1, 1))));
|
||||
positions.push_back(m);
|
||||
flecs::log::warn("add position: %d, %d", selected.x,
|
||||
selected.y);
|
||||
accepted.clear();
|
||||
break;
|
||||
} else {
|
||||
assert(positions.size() > 0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void grid_misc::place_region_cells(
|
||||
flecs::entity grid_floor_e,
|
||||
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < g.regions.size(); i++) {
|
||||
int x, y;
|
||||
RegionRect2i rect = g.regions[i].rect;
|
||||
for (x = rect.position.x; x <= rect.position.x + rect.size.x;
|
||||
x++)
|
||||
for (y = rect.position.y;
|
||||
y <= rect.position.y + rect.size.y; y++) {
|
||||
int id = x + fl.grid_size * y;
|
||||
if (!fl.cells.has(id)) {
|
||||
flecs::entity seed_e =
|
||||
grid_floor_e.world().entity(
|
||||
g.regions[i].seed_et);
|
||||
assert(seed_e.is_valid());
|
||||
assert(seed_e.parent().is_valid());
|
||||
assert(seed_e.parent().id() ==
|
||||
grid_floor_e.id());
|
||||
queue_grow_cell(seed_e, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void grid_misc::queue_grow_cell(flecs::entity seed_e, int id)
|
||||
{
|
||||
assert(seed_e.is_valid());
|
||||
flecs::entity floor_e = seed_e.parent();
|
||||
if (!floor_e.is_valid())
|
||||
flecs::log::err("the parent of %s is not grid floor",
|
||||
seed_e.path().c_str());
|
||||
assert(floor_e.is_valid());
|
||||
if (!floor_e.has<WorldEditor::components::buildings_layout_grid_floor>())
|
||||
flecs::log::err("the parent of %s is not grid floor %s",
|
||||
seed_e.path().c_str(), floor_e.path().c_str());
|
||||
assert(floor_e.has<
|
||||
WorldEditor::components::buildings_layout_grid_floor>());
|
||||
Pair<flecs::entity_t, int> m(seed_e.id(), id);
|
||||
if (!floor_e.has<
|
||||
WorldEditor::components::buildings_layout_grid_queue>()) {
|
||||
List<Pair<flecs::entity_t, int> > queue;
|
||||
queue.push_back(m);
|
||||
floor_e.set<WorldEditor::components::buildings_layout_grid_queue>(
|
||||
{ queue });
|
||||
} else {
|
||||
floor_e.get_mut<WorldEditor::components::
|
||||
buildings_layout_grid_queue>()
|
||||
->queue.push_back(m);
|
||||
floor_e.modified<
|
||||
WorldEditor::components::buildings_layout_grid_queue>();
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void grid_misc::print_can_grow(int state, growth_regions &g, int index,
|
||||
const char *what)
|
||||
{
|
||||
const growth_regions::region ®ion = g.regions[index];
|
||||
bool can = false;
|
||||
if (!strcmp(what, "square"))
|
||||
can = region.can_grow_square;
|
||||
else if (!strcmp(what, "rect"))
|
||||
can = region.can_grow;
|
||||
|
||||
if (can)
|
||||
flecs::log::dbg(
|
||||
"state: %d: index %d: region can still grow %s %d",
|
||||
state, index, what, region.remains_area);
|
||||
else
|
||||
flecs::log::dbg("state: %d: index %d: region can't grow %s %d",
|
||||
state, index, what, region.remains_area);
|
||||
if (region.can_grow_region())
|
||||
flecs::log::dbg("state %d: index %d: region can still continue",
|
||||
state, index);
|
||||
}
|
||||
|
||||
bool grid_misc::grow_state0(growth_regions &g, int index,
|
||||
const RegionRect2i &clip)
|
||||
{
|
||||
bool ok = true, ret = false;
|
||||
RegionRect2i mrect;
|
||||
growth_regions::region ®ion = g.regions.write[index];
|
||||
mrect = region.rect;
|
||||
assert(g.check_region(index, mrect));
|
||||
|
||||
mrect = mrect.grow(1);
|
||||
ok = clip.encloses(mrect);
|
||||
// if (!ok)
|
||||
// flecs::log::dbg("state: %d: index %d: out of clip area",
|
||||
// 0, index);
|
||||
if (ok) {
|
||||
ok = g.check_region(index, mrect);
|
||||
// if (!ok)
|
||||
// flecs::log::dbg(
|
||||
// "state: %d: index %d: check_region failed",
|
||||
// 0, index);
|
||||
}
|
||||
if (ok) {
|
||||
ret = region.update_region_size(mrect);
|
||||
// if (!ret)
|
||||
// flecs::log::dbg(
|
||||
// "state: %d: index %d: update_region_size failed",
|
||||
// 0, index);
|
||||
}
|
||||
print_can_grow(0, g, index, "square");
|
||||
// if (!ret)
|
||||
// flecs::log::dbg("state %d could not grow region %d: %d",
|
||||
// 0, index, region.remains_area);
|
||||
// else
|
||||
// flecs::log::dbg("state %d could grow region %d: %d", 0,
|
||||
// index, region.remains_area);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool grid_misc::grow_state1(growth_regions &g, int index,
|
||||
const RegionRect2i &clip)
|
||||
{
|
||||
int d;
|
||||
bool ret = false;
|
||||
RegionRect2i mrect;
|
||||
growth_regions::region ®ion = g.regions.write[index];
|
||||
int count = 0;
|
||||
for (d = 0; d < 4; d++) {
|
||||
bool ok;
|
||||
mrect = region.rect;
|
||||
assert(g.check_region(index, mrect));
|
||||
switch (d) {
|
||||
case 0:
|
||||
mrect.position.y -= 1;
|
||||
mrect.size.y += 1;
|
||||
break;
|
||||
case 1:
|
||||
mrect.size.y += 1;
|
||||
break;
|
||||
case 2:
|
||||
mrect.position.x -= 1;
|
||||
mrect.size.x += 1;
|
||||
break;
|
||||
case 3:
|
||||
mrect.size.x += 1;
|
||||
break;
|
||||
}
|
||||
ok = g.parent_regions[region.parent_region].rect.encloses(
|
||||
mrect);
|
||||
if (ok)
|
||||
ok = clip.encloses(mrect);
|
||||
if (ok) {
|
||||
ok = false;
|
||||
if (mrect.size.y > 0 && mrect.size.x > 0) {
|
||||
float aspect = (float)mrect.size.x /
|
||||
(float)mrect.size.y;
|
||||
ok = (aspect > 0.2f && aspect < 5.0f);
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
ok = g.check_region(index, mrect);
|
||||
if (ok) {
|
||||
bool result = region.update_region_size(mrect);
|
||||
if (result)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
ret = true;
|
||||
// flecs::log::dbg(
|
||||
// "state %d could grow region %d: %d - %d out of %d times",
|
||||
// 0, index, region.remains_area, count, 4);
|
||||
}
|
||||
print_can_grow(1, g, index, "rect");
|
||||
// if (!ret)
|
||||
// flecs::log::dbg(
|
||||
// "state %d could not grow region rect %d: %d", 0,
|
||||
// index, region.remains_area);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void grid_misc::grow_region_rects(
|
||||
flecs::entity floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g)
|
||||
{
|
||||
int i;
|
||||
bool grown = true;
|
||||
int state = 0;
|
||||
if (g.complete)
|
||||
return;
|
||||
Rect2i clip(0, 0, fl.grid_size, fl.grid_size);
|
||||
state = 0;
|
||||
// flecs::log::dbg("growing square");
|
||||
while (grown) {
|
||||
grown = false;
|
||||
int count = 0;
|
||||
for (i = 0; i < g.regions.size(); i++) {
|
||||
growth_regions::region ®ion = g.regions.write[i];
|
||||
RegionRect2i mrect = region.rect;
|
||||
// flecs::log::dbg("grow_region_rects: region %d",
|
||||
// i);
|
||||
if (!region.can_grow_region()) {
|
||||
// flecs::log::dbg(
|
||||
// "grow_region_rects: skip %d",
|
||||
// i);
|
||||
continue;
|
||||
}
|
||||
mrect = region.rect;
|
||||
bool result = false;
|
||||
result = grow_state0(g, i, clip);
|
||||
if (result)
|
||||
count++;
|
||||
}
|
||||
if (count > 0) {
|
||||
grown = true;
|
||||
// flecs::log::dbg("grown squares %d times of %d",
|
||||
// count, g.regions.size());
|
||||
}
|
||||
// if (!grown)
|
||||
// flecs::log::dbg(
|
||||
// "grow_region_rects: could not grow more squares");
|
||||
}
|
||||
state = 1;
|
||||
grown = true;
|
||||
// flecs::log::dbg("growing rect");
|
||||
while (grown) {
|
||||
grown = false;
|
||||
int count = 0;
|
||||
for (i = 0; i < g.regions.size(); i++) {
|
||||
growth_regions::region ®ion = g.regions.write[i];
|
||||
RegionRect2i mrect = region.rect;
|
||||
// flecs::log::dbg("grow_region_rects: region %d",
|
||||
// i);
|
||||
if (!region.can_grow_region()) {
|
||||
// flecs::log::dbg(
|
||||
// "grow_region_rects: skip %d",
|
||||
// i);
|
||||
continue;
|
||||
}
|
||||
mrect = region.rect;
|
||||
bool result = false;
|
||||
result = grow_state1(g, i, clip);
|
||||
if (result)
|
||||
count++;
|
||||
// if (!result)
|
||||
// flecs::log::dbg(
|
||||
// "state %d could not grow region %d",
|
||||
// state, i);
|
||||
// else
|
||||
// flecs::log::dbg(
|
||||
// "state %d could grow region %d: %d",
|
||||
// state, i, region.remains_area);
|
||||
}
|
||||
if (count > 0) {
|
||||
grown = true;
|
||||
// flecs::log::dbg("grown rects %d times of %d",
|
||||
// count, g.regions.size());
|
||||
}
|
||||
// if (!grown)
|
||||
// flecs::log::dbg(
|
||||
// "grow_region_rects: could not grow any more rects");
|
||||
}
|
||||
flecs::log::dbg("grow_region_rects: complete");
|
||||
g.complete = true;
|
||||
flecs::log::dbg("grow_region_rects: %s: done", floor_e.path().c_str());
|
||||
}
|
||||
|
||||
void grid_misc::subregions_init(flecs::world w)
|
||||
{
|
||||
flecs::query<const WorldEditor::components::buildings_layout_area> qprep =
|
||||
w.query_builder<
|
||||
const WorldEditor::components::buildings_layout_area>()
|
||||
.scope_open()
|
||||
.with<WorldEditor::components::buildings_layout_zone>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::buildings_layout_unit>()
|
||||
.scope_close()
|
||||
.build();
|
||||
qprep.each([this](flecs::entity ce,
|
||||
const WorldEditor::components::buildings_layout_area
|
||||
&area) {
|
||||
all_items.push_back({ ce, ce.parent().id() });
|
||||
});
|
||||
}
|
||||
|
||||
void grid_misc::get_subregions(flecs::entity parent,
|
||||
List<Pair<flecs::entity, float> > *subregions)
|
||||
{
|
||||
flecs::query<const WorldEditor::components::buildings_layout_area> qprep =
|
||||
parent.world()
|
||||
.query_builder<const WorldEditor::components::
|
||||
buildings_layout_area>()
|
||||
.with(flecs::ChildOf, parent)
|
||||
.scope_open()
|
||||
.with<WorldEditor::components::buildings_layout_zone>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::buildings_layout_unit>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::buildings_layout_room>()
|
||||
.scope_close()
|
||||
.build();
|
||||
qprep.each([&subregions](
|
||||
flecs::entity ce,
|
||||
const WorldEditor::components::buildings_layout_area
|
||||
&area) {
|
||||
subregions->push_back({ ce, area.area });
|
||||
});
|
||||
}
|
||||
#endif
|
||||
196
src/modules/stream/ui/grid_misc.h
Normal file
196
src/modules/stream/ui/grid_misc.h
Normal file
@@ -0,0 +1,196 @@
|
||||
#ifndef GRID_MISC_H
|
||||
#define GRID_MISC_H
|
||||
#include <core/vector.h>
|
||||
#include <core/pair.h>
|
||||
#include "world_editor.h"
|
||||
struct RegionRect2i;
|
||||
struct growth_regions;
|
||||
struct make_random {
|
||||
int seed;
|
||||
int next;
|
||||
make_random(int seed)
|
||||
: seed(seed)
|
||||
, next(seed)
|
||||
{
|
||||
}
|
||||
int get()
|
||||
{
|
||||
next = next * 1103515245 + 12345;
|
||||
return (int)((unsigned)next >> 16) % 32768;
|
||||
}
|
||||
};
|
||||
struct grid_misc {
|
||||
Vector<Pair<flecs::entity_t, Vector2i> > positions;
|
||||
Vector<Vector2i> accepted;
|
||||
struct make_random r;
|
||||
grid_misc()
|
||||
: r(100)
|
||||
{
|
||||
}
|
||||
void get_dim_candidates(const Vector2i &base, int dim,
|
||||
Vector2i *candidates);
|
||||
int get_floor_index(flecs::entity e) const;
|
||||
flecs::entity get_grid_floor(flecs::entity grid_e,
|
||||
flecs::entity graph_floor_e) const;
|
||||
bool check_duplicates() const;
|
||||
void place_regions(flecs::entity grid_floor_e);
|
||||
void place_regions_common(flecs::entity parent_e,
|
||||
flecs::entity grid_floor_e, int parent_index);
|
||||
float get_entity_area(flecs::entity e) const
|
||||
{
|
||||
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||
->area;
|
||||
}
|
||||
float get_entity_area(flecs::world &&ecs, flecs::entity_t et) const
|
||||
{
|
||||
flecs::entity e = ecs.entity(et);
|
||||
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||
->area;
|
||||
}
|
||||
float get_entity_area(flecs::world &ecs, flecs::entity_t et) const
|
||||
{
|
||||
flecs::entity e = ecs.entity(et);
|
||||
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||
->area;
|
||||
}
|
||||
int get_base_radius(flecs::world &&ecs, flecs::entity_t et) const
|
||||
{
|
||||
float base_area = get_entity_area(ecs, et);
|
||||
int base_radius = (int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||
4; /* grid conversion */
|
||||
return base_radius;
|
||||
}
|
||||
int get_base_radius(flecs::world &ecs, flecs::entity_t et) const
|
||||
{
|
||||
float base_area = get_entity_area(ecs, et);
|
||||
int base_radius = (int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||
4; /* grid conversion */
|
||||
return base_radius;
|
||||
}
|
||||
int distance_squared(const Vector2i &p1, const Vector2i &p2) const
|
||||
{
|
||||
int lx = p2.x - p1.x;
|
||||
int ly = p2.y - p1.y;
|
||||
return lx * lx + ly * ly;
|
||||
}
|
||||
bool check_candidates_tolerance(const Vector2i check)
|
||||
{
|
||||
int i;
|
||||
bool ret = true;
|
||||
for (i = 0; i < (int)positions.size(); i++)
|
||||
if (distance_squared(check, positions[i].second) < 1) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool check_candidate(const Vector2i &candidate)
|
||||
{
|
||||
int m;
|
||||
bool bad = false;
|
||||
for (m = 0; m < (int)positions.size(); m++)
|
||||
if (positions[m].second == candidate) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
return !bad;
|
||||
}
|
||||
bool accept_candidate(flecs::entity ce, const Vector2i &candidate,
|
||||
float area)
|
||||
{
|
||||
int k;
|
||||
int local_radius = (int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||
4; /* grid conversion */
|
||||
local_radius = MAX(1, local_radius);
|
||||
bool ok = false;
|
||||
for (k = 0; k < (int)positions.size(); k++) {
|
||||
assert(k < (int)positions.size());
|
||||
flecs::entity_t pbase_et = positions[k].first;
|
||||
float parea = get_entity_area(ce.world(), pbase_et);
|
||||
int pdim = (int)((Math::sqrt(parea) * 1.5f) / 2.0f) /
|
||||
4; /* radius converted to grid 4x4*/
|
||||
int radius = pdim + local_radius;
|
||||
int radius_sq = radius * radius;
|
||||
if (distance_squared(positions[k].second, candidate) <
|
||||
radius_sq) {
|
||||
// flecs::log::dbg(
|
||||
// "too close to positions %d < %d",
|
||||
// distance_squared(positions[k].second,
|
||||
// candidate),
|
||||
// radius_sq);
|
||||
continue;
|
||||
}
|
||||
assert(check_candidates_tolerance(candidate));
|
||||
accepted.push_back(candidate);
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
bool accept_candidate2(flecs::entity ce, const Vector2i &candidate)
|
||||
{
|
||||
int k;
|
||||
bool ok = false;
|
||||
for (k = 0; k < (int)positions.size(); k++) {
|
||||
assert(k < (int)positions.size());
|
||||
flecs::entity_t pbase_et = positions[k].first;
|
||||
int radius_sq = 4;
|
||||
if (distance_squared(positions[k].second, candidate) <
|
||||
radius_sq) {
|
||||
// flecs::log::dbg(
|
||||
// "too close to positions %d < %d",
|
||||
// distance_squared(positions[k].second,
|
||||
// candidate),
|
||||
// radius_sq);
|
||||
continue;
|
||||
}
|
||||
assert(check_candidates_tolerance(candidate));
|
||||
accepted.push_back(candidate);
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
bool process_candidates(flecs::entity ce, const Vector2i &base,
|
||||
float area, flecs::entity_t base_et, int dim,
|
||||
const RegionRect2i &clip, bool tight);
|
||||
void filter_candidates(flecs::entity ce, float area,
|
||||
const RegionRect2i &clip_rect);
|
||||
int which_position()
|
||||
{
|
||||
int which;
|
||||
if (positions.size() == 0)
|
||||
return -1;
|
||||
which = r.get() % positions.size();
|
||||
assert(which < (int)positions.size());
|
||||
return which;
|
||||
}
|
||||
int which_selected()
|
||||
{
|
||||
int which;
|
||||
if (accepted.size() == 0)
|
||||
return -1;
|
||||
which = r.get() % accepted.size();
|
||||
assert(which < (int)accepted.size());
|
||||
return which;
|
||||
}
|
||||
void place_region_cells(
|
||||
flecs::entity grid_floor_e,
|
||||
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g);
|
||||
void queue_grow_cell(flecs::entity seed_e, int id);
|
||||
void print_can_grow(int state, growth_regions &g, int index,
|
||||
const char *what);
|
||||
bool grow_state0(growth_regions &g, int index,
|
||||
const RegionRect2i &clip);
|
||||
bool grow_state1(growth_regions &g, int index,
|
||||
const RegionRect2i &clip);
|
||||
void grow_region_rects(
|
||||
flecs::entity floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g);
|
||||
Vector<Pair<flecs::entity, flecs::entity_t> > all_items;
|
||||
void subregions_init(flecs::world w);
|
||||
void get_subregions(flecs::entity parent,
|
||||
List<Pair<flecs::entity, float> > *subregions);
|
||||
};
|
||||
|
||||
#endif
|
||||
735
src/modules/stream/ui/grow_job.cpp
Normal file
735
src/modules/stream/ui/grow_job.cpp
Normal file
@@ -0,0 +1,735 @@
|
||||
#include "base_data.h"
|
||||
#include "world_editor.h"
|
||||
#include "grid_misc.h"
|
||||
#include "graph_module.h"
|
||||
#include "queries.h"
|
||||
#include "region_tree.h"
|
||||
#include "grow_job.h"
|
||||
|
||||
static inline int get_floor_index(flecs::entity e)
|
||||
{
|
||||
return e.get<WorldEditor::components::buildings_layout_floor_index>()
|
||||
->index;
|
||||
}
|
||||
|
||||
static inline flecs::entity get_grid_floor(flecs::entity grid_e,
|
||||
flecs::entity graph_floor_e)
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(graph_floor_e.is_valid());
|
||||
int floor_index = get_floor_index(graph_floor_e);
|
||||
String floor_name = "floor_" + itos(floor_index);
|
||||
// flecs::log::dbg("floor: %s", floor_name.ascii().ptr());
|
||||
flecs::entity floor_e = grid_e.lookup(floor_name.ascii().ptr());
|
||||
assert(floor_e.is_valid());
|
||||
return floor_e;
|
||||
}
|
||||
|
||||
grow_job_queue::grow_job_queue(
|
||||
flecs::entity grid_e, struct subregions &subregions,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size,
|
||||
const String &module_name)
|
||||
: grid_e(grid_e)
|
||||
, grid_size(size.grid_size)
|
||||
, subregions(subregions)
|
||||
, module_name(module_name)
|
||||
{
|
||||
const List<Pair<int, flecs::entity_t> >::Element *me;
|
||||
List<Pair<flecs::entity_t, flecs::entity_t> > job_create_queue;
|
||||
me = size.floors.front();
|
||||
while (me) {
|
||||
// graph entity
|
||||
job_create_queue.push_back(
|
||||
{ me->get().second, me->get().second });
|
||||
flecs::entity_t base_floor_et =
|
||||
job_create_queue.front()->get().second;
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(base_floor_et);
|
||||
flecs::entity grid_floor_e =
|
||||
get_grid_floor(grid_e, base_floor_e);
|
||||
grid_floor_e.get_mut<growth_regions>()->job_list =
|
||||
List<grow_job>();
|
||||
me = me->next();
|
||||
}
|
||||
while (!job_create_queue.empty()) {
|
||||
// graph entity
|
||||
flecs::entity_t et = job_create_queue.front()->get().first;
|
||||
// parent graph entity
|
||||
flecs::entity_t base_floor_et =
|
||||
job_create_queue.front()->get().second;
|
||||
job_create_queue.pop_front();
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(base_floor_et);
|
||||
flecs::log::dbg("job_queue: base_floor: %s",
|
||||
base_floor_e.path().c_str());
|
||||
flecs::entity grid_floor_e =
|
||||
get_grid_floor(grid_e, base_floor_e);
|
||||
flecs::log::dbg("job_queue: grid_floor: %s",
|
||||
grid_floor_e.path().c_str());
|
||||
assert(!subregions.sub_subregions.empty());
|
||||
if (subregions.sub_subregions.has(et) &&
|
||||
!subregions.sub_subregions[et].empty()) {
|
||||
flecs::log::dbg(
|
||||
"subregions for: %s",
|
||||
grid_e.world().entity(et).path().c_str());
|
||||
struct grow_job job;
|
||||
if (grid_floor_e.get<growth_regions>()->job_list.empty())
|
||||
job.job_type = grow_job::INITIAL;
|
||||
else
|
||||
job.job_type = grow_job::COMMON;
|
||||
job.parent_id = et;
|
||||
job.base_floor_id = base_floor_et;
|
||||
job.grid_floor_id = grid_floor_e.id();
|
||||
job.subregions =
|
||||
subregions.sub_subregions[job.parent_id];
|
||||
grid_floor_e.get_mut<growth_regions>()
|
||||
->job_list.push_back(job);
|
||||
List<Pair<flecs::entity, float> >::Element *se =
|
||||
job.subregions.front();
|
||||
while (se) {
|
||||
job_create_queue.push_back(
|
||||
{ se->get().first.id(),
|
||||
base_floor_et });
|
||||
se = se->next();
|
||||
}
|
||||
grid_floor_e.modified<growth_regions>();
|
||||
} else
|
||||
flecs::log::dbg(
|
||||
"no subregions for: %s",
|
||||
grid_e.world().entity(et).path().c_str());
|
||||
}
|
||||
}
|
||||
void grow_job_queue::job_initial(struct grow_job *job)
|
||||
{
|
||||
int i, j;
|
||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
||||
flecs::log::dbg("create: grid_floor: %s", grid_floor_e.path().c_str());
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
RegionRect2i clip_rect(1, 1, grid_size - 2, grid_size - 2);
|
||||
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
||||
List<struct region> initial_regions;
|
||||
#if 0
|
||||
assert(g->regions.size() == 0);
|
||||
#endif
|
||||
if (subregions.size() == 0) {
|
||||
flecs::log::err("nothing to do");
|
||||
return;
|
||||
}
|
||||
grid_floor_e.set<region_tree>(
|
||||
{ { job->base_floor_id, job->base_floor_id, job->base_floor_id,
|
||||
clip_rect.grow(-1), grid_size * grid_size, false, false,
|
||||
true },
|
||||
Vector<struct region_tree *>(),
|
||||
nullptr });
|
||||
struct region_tree *rtree = grid_floor_e.get_mut<region_tree>();
|
||||
create_region_list(rtree, subregions, initial_regions);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get_mut<region_tree>()->split(grid_floor_e,
|
||||
initial_regions);
|
||||
assert(rtree->check(grid_floor_e));
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get<region_tree>()->dump(grid_floor_e);
|
||||
grid_floor_e.get_mut<region_tree>()->grow(grid_floor_e);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get<region_tree>()->dump(grid_floor_e);
|
||||
// grid_floor_e.get<region_tree>()->place(grid_floor_e);
|
||||
List<RegionRect2i> rects;
|
||||
List<RegionRect2i>::Element *e, *e1;
|
||||
grid_floor_e.get<region_tree>()->get_rects(&rects);
|
||||
e = rects.front();
|
||||
bool ok = true;
|
||||
while (e) {
|
||||
e1 = rects.front();
|
||||
while (e1) {
|
||||
if (e->get() == e1->get()) {
|
||||
e1 = e1->next();
|
||||
continue;
|
||||
}
|
||||
if (e->get().intersects(e1->get()))
|
||||
ok = false;
|
||||
if (e->get().encloses(e1->get()))
|
||||
ok = false;
|
||||
if (e1->get().intersects(e->get()))
|
||||
ok = false;
|
||||
if (e1->get().encloses(e->get()))
|
||||
ok = false;
|
||||
if (!ok)
|
||||
break;
|
||||
e1 = e1->next();
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
|
||||
#if 0
|
||||
while (fe) {
|
||||
flecs::entity ce = fe->get().first;
|
||||
float area = fe->get().second;
|
||||
flecs::log::warn("generating positions for: %s",
|
||||
ce.path().c_str());
|
||||
job->grid.filter_candidates(ce, area, clip_rect);
|
||||
fe = fe->next();
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
job->grid.place_regions(grid_floor_e);
|
||||
|
||||
flecs::log::dbg("Running grow...");
|
||||
queries.get_qr().each(
|
||||
[this](flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grd;
|
||||
if (g.complete)
|
||||
return;
|
||||
grd.grow_region_rects(grid_floor_e, fl, g);
|
||||
grd.place_region_cells(grid_floor_e, fl, g);
|
||||
});
|
||||
queries.get_qr().each(
|
||||
[](flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
int i;
|
||||
for (i = 0; i < (int)g.regions.size(); i++)
|
||||
g.regions.write[i].complete = true;
|
||||
g.complete = true;
|
||||
});
|
||||
grid_e.world()
|
||||
.system(grid_e.world().lookup(
|
||||
(module_name + "::GrowCommitQueue").ascii().ptr()))
|
||||
.run();
|
||||
queries.get_mark_cells().each([](flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
int grid_size =
|
||||
e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
int i;
|
||||
Vector2i position(cell.index % grid_size,
|
||||
cell.index / grid_size);
|
||||
Vector2 west(position.x - 1, position.y);
|
||||
Vector2 north(position.x, position.y - 1);
|
||||
Vector2 east(position.x + 1, position.y);
|
||||
Vector2 south(position.x, position.y + 1);
|
||||
int west_id = west.x + grid_size * west.y;
|
||||
int north_id = north.x + grid_size * north.y;
|
||||
int east_id = east.x + grid_size * east.y;
|
||||
int south_id = south.x + grid_size * south.y;
|
||||
std::vector<int> neighbors = { west_id, north_id, east_id,
|
||||
south_id };
|
||||
bool outside = false;
|
||||
bool border = false;
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
if (!e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->cells.has(id)) {
|
||||
outside = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
String neighbor_name = "cell_" + itos(id);
|
||||
flecs::entity neighbor_e =
|
||||
e.parent().lookup(neighbor_name.ascii().ptr());
|
||||
if (!neighbor_e.is_valid())
|
||||
continue;
|
||||
const WorldEditor::components::buildings_layout_grid_cell
|
||||
*neighbor_cell = neighbor_e.get<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_cell>();
|
||||
if (cell.type != neighbor_cell->type) {
|
||||
border = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outside)
|
||||
e.add<WorldEditor::components::outside_wall>();
|
||||
else
|
||||
e.add<WorldEditor::components::final_cell>();
|
||||
if (border)
|
||||
e.add<WorldEditor::components::border>();
|
||||
print_line("outside: " + itos(outside));
|
||||
print_line("position: " + (position.operator String()));
|
||||
print_line("grid size: " + itos(grid_size));
|
||||
print_line("tile index: " + itos(cell.index));
|
||||
});
|
||||
flecs::log::dbg("initial: region count: %d", g->regions.size());
|
||||
assert(g->regions.size() > 0);
|
||||
#endif
|
||||
assert(rtree->check(grid_floor_e));
|
||||
}
|
||||
void grow_job_queue::job_common(struct grow_job *job)
|
||||
{
|
||||
int i, j;
|
||||
make_random r(172);
|
||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
||||
flecs::log::dbg("create: grid_floor: %s", grid_floor_e.path().c_str());
|
||||
flecs::entity parent_e = grid_e.world().entity(job->parent_id);
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
subregions.front();
|
||||
|
||||
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>(),
|
||||
*rtree;
|
||||
List<struct region> region_list;
|
||||
base_rtree->dump(grid_floor_e);
|
||||
flecs::log::warn("search for: %s %lx", parent_e.path().c_str(),
|
||||
job->parent_id);
|
||||
rtree = base_rtree->find(job->parent_id);
|
||||
if (!rtree) {
|
||||
g->job_list.push_back(*job);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
parent_e.path().c_str(), g->job_list.size());
|
||||
return;
|
||||
}
|
||||
create_region_list(rtree, subregions, region_list);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->split(grid_floor_e, region_list);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
grid_floor_e.modified<region_tree>();
|
||||
rtree->dump(grid_floor_e);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->grow(grid_floor_e);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->dump(grid_floor_e);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
|
||||
#if 0
|
||||
flecs::log::dbg("common: region count: %d", g->regions.size());
|
||||
assert(g->regions.size() > 0);
|
||||
bool restart = false, found = false;
|
||||
RegionRect2i clip_rect(0, 0, grid_size, grid_size);
|
||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
||||
flecs::log::dbg("region %d: %s", i,
|
||||
grid_e.world()
|
||||
.entity(g->regions[i].region_et)
|
||||
.path()
|
||||
.c_str());
|
||||
}
|
||||
int region_index = -1;
|
||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
||||
if (g->regions[i].region_et == job->parent_id) {
|
||||
flecs::log::warn("parent is in regions %d", i);
|
||||
region_index = i;
|
||||
if (!g->regions[i].complete) {
|
||||
g->job_list.push_back(*job);
|
||||
restart = true;
|
||||
flecs::log::err(
|
||||
"parent is in regions %d incomplete",
|
||||
i);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
grid_e.world()
|
||||
.entity(job->parent_id)
|
||||
.path()
|
||||
.c_str(),
|
||||
g->job_list.size());
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// no parent region yet
|
||||
g->job_list.push_back(*job);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
parent_e.path().c_str(), g->job_list.size());
|
||||
restart = true;
|
||||
}
|
||||
if (restart)
|
||||
return;
|
||||
#endif
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"before: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
// growth_regions::region parent_region = g->regions[region_index];
|
||||
// const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
// subregions.front();
|
||||
List<Pair<flecs::entity, float> > region_list = subregions;
|
||||
g->split_region(grid_floor_e, region_index, region_list);
|
||||
#endif
|
||||
// g->regions.remove(region_index);
|
||||
// clip_rect = parent_region.rect;
|
||||
// int parent_region_index = g->parent_regions.size();
|
||||
// g->parent_regions.push_back(parent_region);
|
||||
/*
|
||||
while (fe) {
|
||||
flecs::entity ce = fe->get().first;
|
||||
float area = fe->get().second;
|
||||
flecs::log::warn("generating positions for: %s",
|
||||
ce.path().c_str());
|
||||
job->grid.filter_candidates(ce, area, clip_rect);
|
||||
fe = fe->next();
|
||||
}
|
||||
job->grid.place_regions_common(parent_e, grid_floor_e,
|
||||
parent_region_index);
|
||||
*/
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"after: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
flecs::log::dbg("Running grow...");
|
||||
g->grow_regions(grid_floor_e);
|
||||
#endif
|
||||
#if 0
|
||||
// FIXME: fix this
|
||||
queries.get_qr().each(
|
||||
[this, parent_e](
|
||||
flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
if (g.complete)
|
||||
return;
|
||||
g.grow_regions(grid_floor_e);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"after2: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
#endif
|
||||
#if 0
|
||||
queries.get_qr().each(
|
||||
[this, parent_e](
|
||||
flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grd;
|
||||
// if (g.complete)
|
||||
// return;
|
||||
//grd.grow_region_rects(grid_floor_e, fl, g);
|
||||
grd.update_region_cells(grid_floor_e, parent_e, fl, g);
|
||||
assert(false);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
update_region_cells(grid_floor_e);
|
||||
for (i = 0; i < (int)g->regions.size(); i++)
|
||||
g->regions.write[i].complete = true;
|
||||
g->complete = true;
|
||||
#endif
|
||||
commit_common_queue();
|
||||
// assert(false);
|
||||
}
|
||||
void grow_job_queue::commit_common_queue()
|
||||
{
|
||||
grid_e.world()
|
||||
.query_builder<
|
||||
WorldEditor::components::buildings_layout_grid_floor,
|
||||
WorldEditor::components::buildings_layout_grid_queue>()
|
||||
.each([this](flecs::entity e,
|
||||
WorldEditor::components::buildings_layout_grid_floor
|
||||
&fl,
|
||||
WorldEditor::components::buildings_layout_grid_queue
|
||||
&queue) {
|
||||
List<Pair<flecs::entity_t, int> >::Element *me =
|
||||
queue.queue.front();
|
||||
while (me) {
|
||||
flecs::entity seed_e =
|
||||
e.world().entity(me->get().first);
|
||||
int id = me->get().second;
|
||||
if (!fl.cells.has(id)) {
|
||||
flecs::log::err("bad cell %d", id);
|
||||
assert(false);
|
||||
}
|
||||
// fl.cells.insert(id);
|
||||
flecs::entity floor_e = seed_e.parent();
|
||||
String c_name = "cell_" + itos(id);
|
||||
flecs::entity c_e =
|
||||
floor_e.lookup(c_name.ascii().ptr());
|
||||
if (c_e.is_valid() &&
|
||||
c_e.has<WorldEditor::components::
|
||||
buildings_layout_grid_cell>()) {
|
||||
// flecs::log::dbg("cell: %s: %s",
|
||||
// e.path().c_str(),
|
||||
// c_e.path().c_str());
|
||||
String type =
|
||||
seed_e.get<WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
->type;
|
||||
c_e.set<WorldEditor::components::
|
||||
buildings_layout_grid_cell>(
|
||||
{ type, id });
|
||||
seed_e.each<
|
||||
WorldEditor::components::belongs>(
|
||||
[&c_e](flecs::entity second) {
|
||||
c_e.add<WorldEditor::components::
|
||||
belongs>(
|
||||
second);
|
||||
});
|
||||
seed_e.each<WorldEditor::components::
|
||||
belongs_room>(
|
||||
[&c_e](flecs::entity second) {
|
||||
c_e.add<WorldEditor::components::
|
||||
belongs_room>(
|
||||
second);
|
||||
});
|
||||
floor_e.modified<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_floor>();
|
||||
} else {
|
||||
flecs::log::err("bad cell %s",
|
||||
c_name.ascii().ptr());
|
||||
assert(false);
|
||||
}
|
||||
me = me->next();
|
||||
}
|
||||
queue.queue.clear();
|
||||
e.remove<WorldEditor::components::
|
||||
buildings_layout_grid_queue>();
|
||||
});
|
||||
}
|
||||
void grow_job_queue::create_region_list(
|
||||
region_tree *rtree, const List<Pair<flecs::entity, float> > &subregions,
|
||||
List<struct region> ®ion_list)
|
||||
{
|
||||
int i, j;
|
||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
subregions.front();
|
||||
bool restart = false, found = false;
|
||||
make_random r(172);
|
||||
RegionRect2i clip_rect = rtree->region.rect;
|
||||
Vector2i current_position = clip_rect.get_center();
|
||||
Vector2i velocity;
|
||||
|
||||
Vector<flecs::entity> regions;
|
||||
LocalVector<Vector2i> positions;
|
||||
Vector<int> distances;
|
||||
LocalVector<float> areas;
|
||||
// Drunk walk implementation
|
||||
int speed = MAX(1, grid_size * grid_size / 2 / subregions.size());
|
||||
int bad_count = 0;
|
||||
while (fe) {
|
||||
Vector<Vector2i> position_candidates;
|
||||
if (positions.empty()) {
|
||||
int target_distance =
|
||||
(int)(Math::sqrt(fe->get().second) * 0.7f) + 1;
|
||||
positions.push_back(current_position);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
fe = fe->next();
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
int which = r.get() % 12;
|
||||
switch (which) {
|
||||
case 1:
|
||||
velocity = { 0, 1 };
|
||||
break;
|
||||
case 3:
|
||||
velocity = { 1, 0 };
|
||||
break;
|
||||
case 5:
|
||||
velocity = { 0, -1 };
|
||||
break;
|
||||
case 7:
|
||||
velocity = { -1, 0 };
|
||||
break;
|
||||
}
|
||||
if (clip_rect.has_point(current_position + velocity)) {
|
||||
position_candidates.push_back(current_position +
|
||||
velocity);
|
||||
current_position += velocity;
|
||||
}
|
||||
}
|
||||
int target_distance =
|
||||
(int)(Math::sqrt(fe->get().second) * 0.7f) + 1;
|
||||
assert(fe);
|
||||
if (bad_count > 100)
|
||||
target_distance = 1;
|
||||
bool any_match = false;
|
||||
for (i = 0; i < position_candidates.size(); i++) {
|
||||
bool bad = false;
|
||||
assert(fe);
|
||||
for (j = 0; j < (int)positions.size(); j++) {
|
||||
Vector2i l =
|
||||
position_candidates[i] - positions[j];
|
||||
int distance =
|
||||
l.x * l.x + l.y * l.y - distances[j];
|
||||
if (distance < target_distance) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(fe);
|
||||
if (!bad) {
|
||||
assert(fe);
|
||||
positions.push_back(position_candidates[i]);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
any_match = true;
|
||||
bad_count = 0;
|
||||
if (fe) {
|
||||
fe = fe->next();
|
||||
if (fe)
|
||||
target_distance =
|
||||
(int)(Math::sqrt(
|
||||
fe->get()
|
||||
.second) *
|
||||
0.7f) +
|
||||
1;
|
||||
}
|
||||
}
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
if (!any_match) {
|
||||
flecs::log::err(
|
||||
"No match found: %s: %s",
|
||||
(clip_rect.operator String()).ascii().ptr(),
|
||||
(current_position.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
bad_count++;
|
||||
}
|
||||
if (bad_count >= 100) {
|
||||
position_candidates.clear();
|
||||
int x, y;
|
||||
for (x = clip_rect.position.x;
|
||||
x < clip_rect.position.x + clip_rect.size.x; x++)
|
||||
for (y = clip_rect.position.y;
|
||||
y <
|
||||
clip_rect.position.y + clip_rect.size.y;
|
||||
y++) {
|
||||
position_candidates.push_back(
|
||||
Vector2i(x, y));
|
||||
}
|
||||
bad_count = 0;
|
||||
for (i = 0; i < position_candidates.size(); i++) {
|
||||
bool bad = false;
|
||||
assert(fe);
|
||||
for (j = 0; j < (int)positions.size(); j++) {
|
||||
Vector2i l = position_candidates[i] -
|
||||
positions[j];
|
||||
int distance = l.x * l.x + l.y * l.y -
|
||||
distances[j];
|
||||
if (distance > 0) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(fe);
|
||||
if (!bad) {
|
||||
assert(fe);
|
||||
positions.push_back(
|
||||
position_candidates[i]);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
any_match = true;
|
||||
bad_count = 0;
|
||||
if (fe)
|
||||
fe = fe->next();
|
||||
}
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(bad_count < 2000);
|
||||
}
|
||||
flecs::log::dbg("grid_size %d", grid_size);
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
struct region region;
|
||||
flecs::log::dbg("region: %s", regions[i].path().c_str());
|
||||
flecs::log::dbg("position: %d, %d", positions[i].x,
|
||||
positions[i].y);
|
||||
region.complete = false;
|
||||
region.can_grow = true;
|
||||
region.can_grow_square = true;
|
||||
region.parent = rtree->region.region_et;
|
||||
region.rect = RegionRect2i(positions[i], Vector2i(1, 1));
|
||||
region.region_et = regions[i].id();
|
||||
region.remains_area = MAX(1, (areas[i] / 16));
|
||||
/* setting seed uninitialized */
|
||||
region_list.push_back(region);
|
||||
}
|
||||
}
|
||||
void grow_job_queue::iterate()
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(this);
|
||||
flecs::query<growth_regions> q =
|
||||
grid_e.world().query_builder<growth_regions>().build();
|
||||
q.each([this](flecs::entity e, growth_regions &g) {
|
||||
flecs::log::warn("pre floor: %s", e.path().c_str());
|
||||
});
|
||||
q.each([this](flecs::entity e, growth_regions &g) {
|
||||
flecs::log::warn("floor: %s", e.path().c_str());
|
||||
flecs::log::warn("job count: %d", g.job_list.size());
|
||||
while (!g.job_list.empty()) {
|
||||
List<struct grow_job>::Element *job_e =
|
||||
g.job_list.front();
|
||||
assert(job_e);
|
||||
flecs::entity base_floor_e = grid_e.world().entity(
|
||||
job_e->get().base_floor_id);
|
||||
assert(base_floor_e.is_valid());
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(
|
||||
job_e->get().grid_floor_id);
|
||||
assert(grid_floor_e.is_valid());
|
||||
flecs::log::dbg("inerate: create: base_floor: %s",
|
||||
base_floor_e.path().c_str());
|
||||
flecs::log::dbg("iterate: create: grid_floor: %s",
|
||||
grid_floor_e.path().c_str());
|
||||
switch (job_e->get().job_type) {
|
||||
case grow_job::INITIAL:
|
||||
flecs::log::dbg("initial");
|
||||
job_initial(&job_e->get());
|
||||
{
|
||||
const region_tree *rtree =
|
||||
e.get<region_tree>();
|
||||
assert(!rtree ||
|
||||
(rtree &&
|
||||
rtree->check(grid_floor_e)));
|
||||
}
|
||||
break;
|
||||
case grow_job::COMMON:
|
||||
flecs::log::dbg("common");
|
||||
job_common(&job_e->get());
|
||||
{
|
||||
const region_tree *rtree =
|
||||
e.get<region_tree>();
|
||||
assert(!rtree ||
|
||||
(rtree &&
|
||||
rtree->check(grid_floor_e)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
g.job_list.pop_front();
|
||||
// if (common_count > 0)
|
||||
// break;
|
||||
}
|
||||
g.job_list.clear();
|
||||
flecs::query<region_tree> qm =
|
||||
grid_e.world().query_builder<region_tree>().build();
|
||||
qm.each([this](flecs::entity em, region_tree &rt) {
|
||||
assert(rt.check(em));
|
||||
});
|
||||
qm.each([this](flecs::entity em, region_tree &rt) {
|
||||
rt.place(em);
|
||||
});
|
||||
flecs::log::dbg(
|
||||
"processed jobs (created region initial positions): %d",
|
||||
g.job_list.size());
|
||||
});
|
||||
}
|
||||
31
src/modules/stream/ui/grow_job.h
Normal file
31
src/modules/stream/ui/grow_job.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef GROW_JOB_H
|
||||
#define GROW_JOB_H
|
||||
struct grow_job {
|
||||
enum { INITIAL, COMMON };
|
||||
int job_type;
|
||||
flecs::entity_t parent_id;
|
||||
flecs::entity_t base_floor_id;
|
||||
flecs::entity_t grid_floor_id;
|
||||
List<Pair<flecs::entity, float> > subregions;
|
||||
struct grid_misc grid;
|
||||
};
|
||||
|
||||
struct grow_job_queue {
|
||||
flecs::entity grid_e;
|
||||
int grid_size;
|
||||
struct subregions &subregions;
|
||||
const String &module_name;
|
||||
grow_job_queue(
|
||||
flecs::entity grid_e, struct subregions &subregions,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size,
|
||||
const String &module_name);
|
||||
void iterate();
|
||||
void job_initial(struct grow_job *job);
|
||||
void job_common(struct grow_job *job);
|
||||
void commit_common_queue();
|
||||
void
|
||||
create_region_list(struct region_tree *rtree,
|
||||
const List<Pair<flecs::entity, float> > &subregions,
|
||||
List<struct region> ®ion_list);
|
||||
};
|
||||
#endif
|
||||
242
src/modules/stream/ui/growth_module.cpp
Normal file
242
src/modules/stream/ui/growth_module.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
#include "growth_regions.h"
|
||||
#include "region_tree.h"
|
||||
#include "editor_event.h"
|
||||
#include "queries.h"
|
||||
#include "growth_module.h"
|
||||
|
||||
growth_module::growth_module(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<growth_module>();
|
||||
ecs.component<growth_regions>();
|
||||
ecs.component<region_tree>();
|
||||
const String &module_name = "::growth_module";
|
||||
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(flecs::OnUpdate);
|
||||
flecs::entity GraphSolve = ecs.lookup("::graph_module::GraphSolve");
|
||||
assert(GraphSolve.is_valid());
|
||||
GraphFilter.disable();
|
||||
#if 0
|
||||
flecs::entity GraphGridPrepare = ecs.entity("GraphGridPrepare")
|
||||
.add(flecs::Phase)
|
||||
.depends_on(GraphSolve);
|
||||
#endif
|
||||
|
||||
ecs.system("RunGrow")
|
||||
.immediate()
|
||||
.write<WorldEditor::components::buildings_layout_grid_floor>()
|
||||
.write<WorldEditor::components::buildings_layout_grid_size>()
|
||||
.write<growth_regions>()
|
||||
.kind(GraphSolve)
|
||||
.run([module_name, this, GraphFilter](flecs::iter &it) {
|
||||
flecs::world &&ecs_ = it.world();
|
||||
it.world().defer_suspend();
|
||||
flecs::log::dbg("Assembling skeleton done...");
|
||||
flecs::entity GraphSolveZones = it.world().lookup(
|
||||
"::graph_module::GraphSolveZones");
|
||||
assert(GraphSolveZones.is_valid());
|
||||
GraphSolveZones.disable();
|
||||
assert(GraphFilter.is_valid());
|
||||
GraphFilter.enable();
|
||||
EditorEvent::get_singleton()->event.emit(
|
||||
"update_layout_view", varray());
|
||||
// assert(false);
|
||||
struct subregions subregions(ecs_);
|
||||
struct queries queries(ecs_);
|
||||
flecs::log::dbg("Creating regions grow...");
|
||||
queries.get_qp().each(
|
||||
[this, &subregions, &queries,
|
||||
module_name](flecs::iter &it2, size_t count,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_size
|
||||
&size) {
|
||||
struct grid_misc grid;
|
||||
// grid.subregions_init(it2.world());
|
||||
flecs::entity graph_e =
|
||||
it2.entity(count);
|
||||
flecs::log::warn(
|
||||
"creating grid for: %s",
|
||||
graph_e.path().c_str());
|
||||
flecs::entity grid_base_e =
|
||||
queries.get_layout_grid_base();
|
||||
flecs::entity grid_e =
|
||||
grid_base_e.lookup(
|
||||
graph_e.name());
|
||||
assert(grid_e.is_valid());
|
||||
flecs::log::warn(
|
||||
"creating grid for: %s: %s",
|
||||
graph_e.path().c_str(),
|
||||
grid_e.path().c_str());
|
||||
/* starting at grid center */
|
||||
subregions.build_subregions(grid_e,
|
||||
grid, size);
|
||||
struct grow_job_queue job_queue(
|
||||
grid_e, subregions, size,
|
||||
module_name);
|
||||
job_queue.iterate();
|
||||
});
|
||||
commit_growth_queue(it.world());
|
||||
queries.get_mark_cells().each([](flecs::entity e,
|
||||
const WorldEditor::
|
||||
components::buildings_layout_grid_cell
|
||||
&cell) {
|
||||
int grid_size =
|
||||
e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
int i;
|
||||
Vector2i position(cell.index % grid_size,
|
||||
cell.index / grid_size);
|
||||
Vector2 west(position.x - 1, position.y);
|
||||
Vector2 north(position.x, position.y - 1);
|
||||
Vector2 east(position.x + 1, position.y);
|
||||
Vector2 south(position.x, position.y + 1);
|
||||
int west_id = west.x + grid_size * west.y;
|
||||
int north_id = north.x + grid_size * north.y;
|
||||
int east_id = east.x + grid_size * east.y;
|
||||
int south_id = south.x + grid_size * south.y;
|
||||
std::vector<int> neighbors = {
|
||||
west_id, north_id, east_id, south_id
|
||||
};
|
||||
bool outside = false;
|
||||
#if 0
|
||||
bool border = false;
|
||||
#endif
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
String neighbor_cell =
|
||||
"cell_" + itos(id);
|
||||
flecs::entity neighbor_e =
|
||||
e.parent().lookup(
|
||||
neighbor_cell.ascii()
|
||||
.ptr());
|
||||
if (!neighbor_e.is_valid()) {
|
||||
outside = true;
|
||||
break;
|
||||
}
|
||||
if (!e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->cells.has(id)) {
|
||||
outside = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
flecs::log::dbg("outside: %d", outside);
|
||||
#if 0
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
String neighbor_name = "cell_" + itos(id);
|
||||
flecs::entity neighbor_e =
|
||||
e.parent().lookup(neighbor_name.ascii().ptr());
|
||||
if (!neighbor_e.is_valid())
|
||||
continue;
|
||||
const WorldEditor::components::buildings_layout_grid_cell
|
||||
*neighbor_cell = neighbor_e.get<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_cell>();
|
||||
if (cell.type != neighbor_cell->type) {
|
||||
border = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (outside) {
|
||||
e.add<WorldEditor::components::
|
||||
outside_wall>();
|
||||
flecs::log::dbg("outside wall cell %s",
|
||||
e.path().c_str());
|
||||
} else
|
||||
e.add<WorldEditor::components::
|
||||
final_cell>();
|
||||
#if 0
|
||||
if (border)
|
||||
e.add<WorldEditor::components::border>();
|
||||
#endif
|
||||
print_line("outside: " + itos(outside));
|
||||
print_line("position: " +
|
||||
(position.operator String()));
|
||||
print_line("grid size: " + itos(grid_size));
|
||||
print_line("tile index: " + itos(cell.index));
|
||||
});
|
||||
it.world()
|
||||
.lookup("::growth_module::GraphFilter")
|
||||
.disable();
|
||||
it.world().defer_resume();
|
||||
});
|
||||
}
|
||||
|
||||
void growth_module::grow_cell(flecs::entity seed_e, int id)
|
||||
{
|
||||
flecs::entity floor_e = seed_e.parent();
|
||||
String c_name = "cell_" + itos(id);
|
||||
flecs::entity c_e = floor_e.lookup(c_name.ascii().ptr());
|
||||
if (!c_e.is_valid()) {
|
||||
c_e = seed_e.world()
|
||||
.entity(c_name.ascii().ptr())
|
||||
.child_of(floor_e);
|
||||
assert(c_e.is_valid());
|
||||
String type = seed_e.get<WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
->type;
|
||||
c_e.set<WorldEditor::components::buildings_layout_grid_cell>(
|
||||
{ type, id });
|
||||
seed_e.each<WorldEditor::components::belongs>(
|
||||
[&c_e](flecs::entity second) {
|
||||
c_e.add<WorldEditor::components::belongs>(
|
||||
second);
|
||||
});
|
||||
int mcount = 0;
|
||||
seed_e.each<WorldEditor::components::belongs_room>(
|
||||
[&c_e, &mcount](flecs::entity second) {
|
||||
assert(mcount == 0);
|
||||
c_e.add<WorldEditor::components::belongs_room>(
|
||||
second);
|
||||
mcount++;
|
||||
});
|
||||
floor_e.get_mut<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->size_left--;
|
||||
floor_e.get_mut<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->cells.insert(id);
|
||||
floor_e.modified<
|
||||
WorldEditor::components::buildings_layout_grid_floor>();
|
||||
}
|
||||
}
|
||||
|
||||
void growth_module::commit_growth_queue(flecs::world &&ecs)
|
||||
{
|
||||
flecs::query<WorldEditor::components::buildings_layout_grid_floor,
|
||||
WorldEditor::components::buildings_layout_grid_queue>
|
||||
grow_commit_queue =
|
||||
ecs.query_builder<WorldEditor::components::
|
||||
buildings_layout_grid_floor,
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_queue>()
|
||||
.build();
|
||||
grow_commit_queue.each(
|
||||
[this](flecs::entity e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
WorldEditor::components::buildings_layout_grid_queue
|
||||
&queue) {
|
||||
List<Pair<flecs::entity_t, int> >::Element *me =
|
||||
queue.queue.front();
|
||||
while (me) {
|
||||
flecs::entity seed_e =
|
||||
e.world().entity(me->get().first);
|
||||
int id = me->get().second;
|
||||
if (!fl.cells.has(id)) {
|
||||
grow_cell(seed_e, id);
|
||||
fl.cells.insert(id);
|
||||
}
|
||||
me = me->next();
|
||||
}
|
||||
queue.queue.clear();
|
||||
e.remove<WorldEditor::components::
|
||||
buildings_layout_grid_queue>();
|
||||
});
|
||||
}
|
||||
12
src/modules/stream/ui/growth_module.h
Normal file
12
src/modules/stream/ui/growth_module.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* ~/godot-projects/streaming_world/src/modules/stream/ui/growth_module.h */
|
||||
#ifndef GROWTH_MODULE_H_
|
||||
#define GROWTH_MODULE_H_
|
||||
#include "base_data.h"
|
||||
|
||||
struct growth_module {
|
||||
void grow_cell(flecs::entity seed_e, int id);
|
||||
void commit_growth_queue(flecs::world &&world);
|
||||
growth_module(flecs::world &ecs);
|
||||
};
|
||||
|
||||
#endif // GROWTH_MODULE_H_
|
||||
213
src/modules/stream/ui/growth_regions.cpp
Normal file
213
src/modules/stream/ui/growth_regions.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "growth_regions.h"
|
||||
|
||||
#if 0
|
||||
|
||||
static void print_can_grow(int state, growth_regions &g, int index,
|
||||
const char *what)
|
||||
{
|
||||
const growth_regions::region ®ion = g.regions[index];
|
||||
bool can = false;
|
||||
if (!strcmp(what, "square"))
|
||||
can = region.can_grow_square;
|
||||
else if (!strcmp(what, "rect"))
|
||||
can = region.can_grow;
|
||||
|
||||
if (can)
|
||||
flecs::log::dbg(
|
||||
"state: %d: index %d: region can still grow %s %d",
|
||||
state, index, what, region.remains_area);
|
||||
else
|
||||
flecs::log::dbg("state: %d: index %d: region can't grow %s %d",
|
||||
state, index, what, region.remains_area);
|
||||
if (region.can_grow_region())
|
||||
flecs::log::dbg("state %d: index %d: region can still continue",
|
||||
state, index);
|
||||
}
|
||||
|
||||
bool growth_regions::grow_state0(int index, const RegionRect2i &clip)
|
||||
{
|
||||
bool ok = true, ret = false;
|
||||
RegionRect2i mrect;
|
||||
growth_regions::region ®ion = regions.write[index];
|
||||
mrect = region.rect;
|
||||
assert(check_region(index, mrect));
|
||||
|
||||
mrect = mrect.grow(1);
|
||||
ok = clip.encloses(mrect);
|
||||
// if (!ok)
|
||||
// flecs::log::dbg("state: %d: index %d: out of clip area",
|
||||
// 0, index);
|
||||
if (ok) {
|
||||
ok = check_region(index, mrect);
|
||||
// if (!ok)
|
||||
// flecs::log::dbg(
|
||||
// "state: %d: index %d: check_region failed",
|
||||
// 0, index);
|
||||
}
|
||||
if (ok) {
|
||||
ret = region.update_region_size(mrect);
|
||||
// if (!ret)
|
||||
// flecs::log::dbg(
|
||||
// "state: %d: index %d: update_region_size failed",
|
||||
// 0, index);
|
||||
}
|
||||
print_can_grow(0, *this, index, "square");
|
||||
// if (!ret)
|
||||
// flecs::log::dbg("state %d could not grow region %d: %d",
|
||||
// 0, index, region.remains_area);
|
||||
// else
|
||||
// flecs::log::dbg("state %d could grow region %d: %d", 0,
|
||||
// index, region.remains_area);
|
||||
return ret;
|
||||
}
|
||||
bool growth_regions::grow_state1(int index, const RegionRect2i &clip)
|
||||
{
|
||||
int d;
|
||||
bool ret = false;
|
||||
RegionRect2i mrect;
|
||||
growth_regions::region ®ion = regions.write[index];
|
||||
int count = 0;
|
||||
for (d = 0; d < 4; d++) {
|
||||
bool ok;
|
||||
mrect = region.rect;
|
||||
assert(check_region(index, mrect));
|
||||
switch (d) {
|
||||
case 0:
|
||||
mrect.position.y -= 1;
|
||||
mrect.size.y += 1;
|
||||
break;
|
||||
case 1:
|
||||
mrect.size.y += 1;
|
||||
break;
|
||||
case 2:
|
||||
mrect.position.x -= 1;
|
||||
mrect.size.x += 1;
|
||||
break;
|
||||
case 3:
|
||||
mrect.size.x += 1;
|
||||
break;
|
||||
}
|
||||
ok = parent_regions[region.parent_region].rect.encloses(mrect);
|
||||
if (ok)
|
||||
ok = clip.encloses(mrect);
|
||||
if (ok) {
|
||||
ok = false;
|
||||
if (mrect.size.y > 0 && mrect.size.x > 0) {
|
||||
float aspect = (float)mrect.size.x /
|
||||
(float)mrect.size.y;
|
||||
ok = (aspect > 0.2f && aspect < 5.0f);
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
ok = check_region(index, mrect);
|
||||
if (ok) {
|
||||
bool result = region.update_region_size(mrect);
|
||||
if (result)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
ret = true;
|
||||
// flecs::log::dbg(
|
||||
// "state %d could grow region %d: %d - %d out of %d times",
|
||||
// 0, index, region.remains_area, count, 4);
|
||||
}
|
||||
print_can_grow(1, *this, index, "rect");
|
||||
// if (!ret)
|
||||
// flecs::log::dbg(
|
||||
// "state %d could not grow region rect %d: %d", 0,
|
||||
// index, region.remains_area);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
void growth_regions::grow_regions(flecs::entity grid_floor_e)
|
||||
{
|
||||
int i;
|
||||
bool grown = true;
|
||||
int state = 0;
|
||||
if (complete)
|
||||
return;
|
||||
#if 0
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
#endif
|
||||
state = 0;
|
||||
flecs::log::dbg("growing square");
|
||||
while (grown) {
|
||||
grown = false;
|
||||
int count = 0;
|
||||
for (i = 0; i < regions.size(); i++) {
|
||||
growth_regions::region ®ion = regions.write[i];
|
||||
const RegionRect2i &clip =
|
||||
parent_regions[region.parent_region].rect;
|
||||
RegionRect2i mrect = region.rect;
|
||||
flecs::log::dbg("grow_region_rects: region %d", i);
|
||||
if (!region.can_grow_region()) {
|
||||
flecs::log::dbg("grow_region_rects: skip %d",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
mrect = region.rect;
|
||||
bool result = false;
|
||||
result = grow_state0(i, clip);
|
||||
if (result)
|
||||
count++;
|
||||
}
|
||||
if (count > 0) {
|
||||
grown = true;
|
||||
flecs::log::dbg("grown squares %d times of %d", count,
|
||||
regions.size());
|
||||
}
|
||||
if (!grown)
|
||||
flecs::log::dbg(
|
||||
"grow_region_rects: could not grow more squares");
|
||||
}
|
||||
state = 1;
|
||||
grown = true;
|
||||
flecs::log::dbg("growing rect");
|
||||
while (grown) {
|
||||
grown = false;
|
||||
int count = 0;
|
||||
for (i = 0; i < regions.size(); i++) {
|
||||
growth_regions::region ®ion = regions.write[i];
|
||||
const RegionRect2i &clip =
|
||||
parent_regions[region.parent_region].rect;
|
||||
RegionRect2i mrect = region.rect;
|
||||
flecs::log::dbg("grow_region_rects: region %d", i);
|
||||
if (!region.can_grow_region()) {
|
||||
flecs::log::dbg("grow_region_rects: skip %d",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
mrect = region.rect;
|
||||
bool result = false;
|
||||
result = grow_state1(i, clip);
|
||||
if (result)
|
||||
count++;
|
||||
if (!result)
|
||||
flecs::log::dbg(
|
||||
"state %d could not grow region %d",
|
||||
state, i);
|
||||
else
|
||||
flecs::log::dbg(
|
||||
"state %d could grow region %d: %d",
|
||||
state, i, region.remains_area);
|
||||
}
|
||||
if (count > 0) {
|
||||
grown = true;
|
||||
flecs::log::dbg("grown rects %d times of %d", count,
|
||||
regions.size());
|
||||
}
|
||||
if (!grown)
|
||||
flecs::log::dbg(
|
||||
"grow_region_rects: could not grow any more rects");
|
||||
}
|
||||
flecs::log::dbg("grow_region_rects: complete");
|
||||
complete = true;
|
||||
flecs::log::dbg("grow_region_rects: %s: done",
|
||||
grid_floor_e.path().c_str());
|
||||
}
|
||||
#endif
|
||||
99
src/modules/stream/ui/growth_regions.h
Normal file
99
src/modules/stream/ui/growth_regions.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef GROWTH_REGIONS_H
|
||||
#define GROWTH_REGIONS_H
|
||||
#include <core/vector.h>
|
||||
#include <core/list.h>
|
||||
#include <core/pair.h>
|
||||
#include <core/math/vector2.h>
|
||||
#include "base_data.h"
|
||||
#include "region_rect2.h"
|
||||
#include "graph_module.h"
|
||||
struct region {
|
||||
flecs::entity_t parent;
|
||||
flecs::entity_t seed_et;
|
||||
flecs::entity_t region_et;
|
||||
RegionRect2i rect;
|
||||
int remains_area;
|
||||
bool can_grow_square;
|
||||
bool can_grow;
|
||||
bool complete;
|
||||
bool can_grow_region() const
|
||||
{
|
||||
bool ret = can_grow;
|
||||
if (remains_area <= 0)
|
||||
ret = false;
|
||||
return ret;
|
||||
}
|
||||
bool update_region_size(RegionRect2i &mrect)
|
||||
{
|
||||
bool ret = false;
|
||||
int old_area = rect.get_area();
|
||||
int new_area = mrect.get_area();
|
||||
int area_diff = new_area - old_area;
|
||||
if (area_diff > 0) {
|
||||
rect = mrect;
|
||||
remains_area -= area_diff;
|
||||
ret = true;
|
||||
}
|
||||
if (remains_area <= 0) {
|
||||
can_grow_square = false;
|
||||
can_grow = false;
|
||||
}
|
||||
flecs::log::dbg("update_region_size %d -> %d", area_diff, ret);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
struct growth_regions {
|
||||
List<struct grow_job> job_list;
|
||||
bool complete;
|
||||
bool check_region(int index, const RegionRect2i &rect) const;
|
||||
#if 0
|
||||
bool check_region(int index, const RegionRect2i &rect) const
|
||||
{
|
||||
int i;
|
||||
bool ret = true;
|
||||
for (i = 0; i < regions.size(); i++) {
|
||||
if (i == index)
|
||||
continue;
|
||||
if (rect.intersects(regions[i].rect)) {
|
||||
ret = false;
|
||||
flecs::log::dbg(
|
||||
"%d: %s intersects %s", i,
|
||||
(rect.operator String()).ascii().ptr(),
|
||||
(regions[i].rect.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
break;
|
||||
}
|
||||
}
|
||||
flecs::log::dbg("check_region: %d -> %d", index, ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
bool update_region_size(int index, RegionRect2i &mrect);
|
||||
#if 0
|
||||
bool update_region_size(int index, RegionRect2i &mrect)
|
||||
{
|
||||
bool ret = false;
|
||||
bool ok = check_region(index, mrect);
|
||||
if (ok)
|
||||
ret = regions.write[index].update_region_size(mrect);
|
||||
flecs::log::dbg("update_region_size %d -> %d", index, ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
void create_region(flecs::entity floor_e, flecs::entity seed_e,
|
||||
flecs::entity parent_e, flecs::entity region_e,
|
||||
const Vector2i &position, float area,
|
||||
int parent_index);
|
||||
flecs::entity create_cell(flecs::entity floor_e, flecs::entity region_e,
|
||||
int id);
|
||||
flecs::entity update_cell(flecs::entity floor_e, flecs::entity parent_e,
|
||||
flecs::entity region_e, int id);
|
||||
void split_region(flecs::entity grid_floor_e, int region_index,
|
||||
const List<Pair<flecs::entity, float> > ®ion_list);
|
||||
void grow_regions(flecs::entity grid_floor_e);
|
||||
bool grow_state0(int index, const RegionRect2i &clip);
|
||||
bool grow_state1(int index, const RegionRect2i &clip);
|
||||
};
|
||||
|
||||
#endif
|
||||
204
src/modules/stream/ui/queries.h
Normal file
204
src/modules/stream/ui/queries.h
Normal file
@@ -0,0 +1,204 @@
|
||||
#ifndef QUERIES_H
|
||||
#define QUERIES_H
|
||||
#include "base_data.h"
|
||||
#include "world_editor.h"
|
||||
#include "growth_regions.h"
|
||||
#include "graph_module.h"
|
||||
struct queries {
|
||||
flecs::query_builder<WorldEditor::components::buildings_layout_grid_size>
|
||||
qp;
|
||||
flecs::query_builder<WorldEditor::components::buildings_layout_grid_floor,
|
||||
growth_regions>
|
||||
qr;
|
||||
flecs::query_builder<
|
||||
const WorldEditor::components::buildings_layout_grid_cell>
|
||||
mark_cells;
|
||||
flecs::query<WorldEditor::components::buildings_layout_grid_size>
|
||||
get_qp()
|
||||
{
|
||||
return qp.build();
|
||||
}
|
||||
flecs::query<WorldEditor::components::buildings_layout_grid_floor,
|
||||
growth_regions>
|
||||
get_qr()
|
||||
{
|
||||
return qr.build();
|
||||
}
|
||||
flecs::query<const WorldEditor::components::buildings_layout_grid_cell>
|
||||
get_mark_cells()
|
||||
{
|
||||
return mark_cells.build();
|
||||
}
|
||||
queries(flecs::world &w)
|
||||
: qp(w.query_builder<WorldEditor::components::
|
||||
buildings_layout_grid_size>()
|
||||
.write<WorldEditor::components::
|
||||
buildings_layout_grid>())
|
||||
, qr(w.query_builder<
|
||||
WorldEditor::components::buildings_layout_grid_floor,
|
||||
growth_regions>())
|
||||
, mark_cells(
|
||||
w.query_builder<const WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
.without<WorldEditor::components::outside_wall>()
|
||||
.read<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
.write<WorldEditor::components::outside_wall>()
|
||||
.write<WorldEditor::components::final_cell>())
|
||||
{
|
||||
}
|
||||
int get_floor_index(flecs::entity e) const
|
||||
{
|
||||
return e.get<WorldEditor::components::
|
||||
buildings_layout_floor_index>()
|
||||
->index;
|
||||
}
|
||||
flecs::entity get_grid_floor(flecs::entity grid_e,
|
||||
flecs::entity graph_floor_e)
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(graph_floor_e.is_valid());
|
||||
int floor_index = get_floor_index(graph_floor_e);
|
||||
String floor_name = "floor_" + itos(floor_index);
|
||||
flecs::log::dbg("floor: %s", floor_name.ascii().ptr());
|
||||
flecs::entity floor_e = grid_e.lookup(floor_name.ascii().ptr());
|
||||
assert(floor_e.is_valid());
|
||||
return floor_e;
|
||||
}
|
||||
void create_floor_components(
|
||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size)
|
||||
const
|
||||
{
|
||||
assert(!floor_e.has<
|
||||
WorldEditor::components::buildings_layout_grid_floor>());
|
||||
assert(!floor_e.has<growth_regions>());
|
||||
floor_e.set<WorldEditor::components::buildings_layout_grid_floor>(
|
||||
{ Set<int>(), size.grid_size, size.growth_size });
|
||||
floor_e.set<growth_regions>({ List<struct grow_job>(), false });
|
||||
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
||||
}
|
||||
flecs::entity get_layout_grid_base()
|
||||
{
|
||||
const String &layout_grid_name = "buildings_layout_grid_v2";
|
||||
flecs::world ecs = BaseData::get_singleton()->get();
|
||||
flecs::entity layout_base_e =
|
||||
ecs.lookup(layout_grid_name.ascii().ptr());
|
||||
if (layout_base_e.is_valid()) {
|
||||
assert(layout_base_e.has<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_base>());
|
||||
return layout_base_e;
|
||||
} else {
|
||||
layout_base_e =
|
||||
ecs.entity(layout_grid_name.ascii().ptr());
|
||||
assert(layout_base_e.is_valid());
|
||||
layout_base_e.add<WorldEditor::components::
|
||||
buildings_layout_grid_base>();
|
||||
assert(layout_base_e.has<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_base>());
|
||||
return layout_base_e;
|
||||
}
|
||||
}
|
||||
flecs::entity get_layout_base()
|
||||
{
|
||||
const String &layout_base_name = "buildings_layout_graph";
|
||||
flecs::world ecs = BaseData::get_singleton()->get();
|
||||
flecs::entity layout_base_e =
|
||||
ecs.lookup(layout_base_name.ascii().ptr());
|
||||
if (layout_base_e.is_valid()) {
|
||||
assert(layout_base_e.has<
|
||||
WorldEditor::components::buildings_layout_base>());
|
||||
return layout_base_e;
|
||||
} else {
|
||||
layout_base_e =
|
||||
ecs.entity(layout_base_name.ascii().ptr());
|
||||
assert(layout_base_e.is_valid());
|
||||
layout_base_e.add<
|
||||
WorldEditor::components::buildings_layout_base>();
|
||||
return layout_base_e;
|
||||
}
|
||||
}
|
||||
};
|
||||
struct subregions {
|
||||
HashMap<flecs::entity_t, List<Pair<flecs::entity, float> > >
|
||||
sub_subregions;
|
||||
struct queries queries;
|
||||
subregions(flecs::world &ecs)
|
||||
: queries(ecs)
|
||||
{
|
||||
}
|
||||
void get_subregions(flecs::entity parent,
|
||||
List<Pair<flecs::entity, float> > *subregions)
|
||||
{
|
||||
flecs::query<const WorldEditor::components::buildings_layout_area>
|
||||
qprep = parent.world()
|
||||
.query_builder<
|
||||
const WorldEditor::components::
|
||||
buildings_layout_area>()
|
||||
.with(flecs::ChildOf, parent)
|
||||
.scope_open()
|
||||
.with<WorldEditor::components::
|
||||
buildings_layout_zone>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::
|
||||
buildings_layout_unit>()
|
||||
.or_()
|
||||
.with<WorldEditor::components::
|
||||
buildings_layout_room>()
|
||||
.scope_close()
|
||||
.build();
|
||||
qprep.each([&subregions](flecs::entity ce,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_area &area) {
|
||||
subregions->push_back({ ce, area.area });
|
||||
});
|
||||
}
|
||||
void build_subregions(
|
||||
flecs::entity grid_e, struct grid_misc &grid,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size)
|
||||
{
|
||||
const List<Pair<int, flecs::entity_t> >::Element *me =
|
||||
size.floors.front();
|
||||
List<flecs::entity_t> subregions_queue;
|
||||
while (me) {
|
||||
subregions_queue.push_back(me->get().second);
|
||||
flecs::entity_t base_floor_et = me->get().second;
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(base_floor_et);
|
||||
flecs::log::dbg("job_queue: base_floor: %s",
|
||||
base_floor_e.path().c_str());
|
||||
flecs::entity grid_floor_e =
|
||||
queries.get_grid_floor(grid_e, base_floor_e);
|
||||
flecs::log::dbg("job_queue: grid_floor: %s",
|
||||
grid_floor_e.path().c_str());
|
||||
if (!grid_floor_e
|
||||
.has<WorldEditor::components::
|
||||
buildings_layout_grid_floor>())
|
||||
queries.create_floor_components(
|
||||
grid_floor_e, base_floor_e, size);
|
||||
me = me->next();
|
||||
}
|
||||
while (!subregions_queue.empty()) {
|
||||
// eid is graph entity
|
||||
flecs::entity_t eid = subregions_queue.front()->get();
|
||||
subregions_queue.pop_front();
|
||||
List<Pair<flecs::entity, float> > subregions;
|
||||
flecs::entity item_e = grid_e.world().entity(eid);
|
||||
get_subregions(grid_e.world().entity(eid), &subregions);
|
||||
if (subregions.empty())
|
||||
flecs::log::dbg("!no subregions for: %s",
|
||||
item_e.path().c_str());
|
||||
sub_subregions[eid] = subregions;
|
||||
List<Pair<flecs::entity, float> >::Element *fe =
|
||||
subregions.front();
|
||||
while (fe) {
|
||||
subregions_queue.push_back(
|
||||
fe->get().first.id());
|
||||
fe = fe->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
235
src/modules/stream/ui/region_rect2.h
Normal file
235
src/modules/stream/ui/region_rect2.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/* ~/godot-projects/streaming_world/src/modules/stream/ui/region_rect2.h */
|
||||
#ifndef REGION_RECT2_H_
|
||||
#define REGION_RECT2_H_
|
||||
#include <core/math/vector2.h>
|
||||
#include <core/math/rect2.h>
|
||||
struct RegionRect2i {
|
||||
Point2i position;
|
||||
Size2i size;
|
||||
|
||||
const Point2i &get_position() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
void set_position(const Point2i &p_position)
|
||||
{
|
||||
position = p_position;
|
||||
}
|
||||
const Size2i &get_size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
void set_size(const Size2i &p_size)
|
||||
{
|
||||
size = p_size;
|
||||
}
|
||||
|
||||
int get_area() const
|
||||
{
|
||||
return size.width * size.height;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2i get_center() const
|
||||
{
|
||||
return position + (size / 2);
|
||||
}
|
||||
|
||||
inline bool intersects(const RegionRect2i &p_rect) const
|
||||
{
|
||||
if (position.x > (p_rect.position.x + p_rect.size.width - 1)) {
|
||||
return false;
|
||||
}
|
||||
if ((position.x + size.width - 1) < p_rect.position.x) {
|
||||
return false;
|
||||
}
|
||||
if (position.y > (p_rect.position.y + p_rect.size.height - 1)) {
|
||||
return false;
|
||||
}
|
||||
if ((position.y + size.height - 1) < p_rect.position.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool encloses(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return (p_rect.position.x >= position.x) &&
|
||||
(p_rect.position.y >= position.y) &&
|
||||
((p_rect.position.x + p_rect.size.x) <=
|
||||
(position.x + size.x)) &&
|
||||
((p_rect.position.y + p_rect.size.y) <=
|
||||
(position.y + size.y));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool has_no_area() const
|
||||
{
|
||||
return (size.x <= 0 || size.y <= 0);
|
||||
}
|
||||
inline RegionRect2i clip(const RegionRect2i &p_rect) const
|
||||
{ /// return a clipped rect
|
||||
|
||||
RegionRect2i new_rect = p_rect;
|
||||
|
||||
if (!intersects(new_rect)) {
|
||||
return RegionRect2i();
|
||||
}
|
||||
|
||||
new_rect.position.x = MAX(p_rect.position.x, position.x);
|
||||
new_rect.position.y = MAX(p_rect.position.y, position.y);
|
||||
|
||||
Point2 p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2 end = position + size;
|
||||
|
||||
new_rect.size.x =
|
||||
(int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
|
||||
new_rect.size.y =
|
||||
(int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
inline RegionRect2i merge(const RegionRect2i &p_rect) const
|
||||
{ ///< return a merged rect
|
||||
|
||||
RegionRect2i new_rect;
|
||||
|
||||
new_rect.position.x = MIN(p_rect.position.x, position.x);
|
||||
new_rect.position.y = MIN(p_rect.position.y, position.y);
|
||||
|
||||
new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x,
|
||||
position.x + size.x);
|
||||
new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y,
|
||||
position.y + size.y);
|
||||
|
||||
new_rect.size =
|
||||
new_rect.size - new_rect.position; //make relative again
|
||||
|
||||
return new_rect;
|
||||
};
|
||||
bool has_point(const Point2 &p_point) const
|
||||
{
|
||||
if (p_point.x < position.x) {
|
||||
return false;
|
||||
}
|
||||
if (p_point.y < position.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_point.x >= (position.x + size.x)) {
|
||||
return false;
|
||||
}
|
||||
if (p_point.y >= (position.y + size.y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return position == p_rect.position && size == p_rect.size;
|
||||
}
|
||||
bool operator!=(const RegionRect2i &p_rect) const
|
||||
{
|
||||
return position != p_rect.position || size != p_rect.size;
|
||||
}
|
||||
|
||||
RegionRect2i grow(int p_by) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g.position.x -= p_by;
|
||||
g.position.y -= p_by;
|
||||
g.size.width += p_by * 2;
|
||||
g.size.height += p_by * 2;
|
||||
return g;
|
||||
}
|
||||
|
||||
inline RegionRect2i grow_margin(Margin p_margin, int p_amount) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g = g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0,
|
||||
(MARGIN_TOP == p_margin) ? p_amount : 0,
|
||||
(MARGIN_RIGHT == p_margin) ? p_amount : 0,
|
||||
(MARGIN_BOTTOM == p_margin) ? p_amount :
|
||||
0);
|
||||
return g;
|
||||
}
|
||||
|
||||
inline RegionRect2i grow_individual(int p_left, int p_top, int p_right,
|
||||
int p_bottom) const
|
||||
{
|
||||
RegionRect2i g = *this;
|
||||
g.position.x -= p_left;
|
||||
g.position.y -= p_top;
|
||||
g.size.width += p_left + p_right;
|
||||
g.size.height += p_top + p_bottom;
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RegionRect2i expand(const Vector2i &p_vector) const
|
||||
{
|
||||
RegionRect2i r = *this;
|
||||
r.expand_to(p_vector);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void expand_to(const Point2i &p_vector)
|
||||
{
|
||||
Point2i begin = position;
|
||||
Point2i end = position + size;
|
||||
|
||||
if (p_vector.x < begin.x) {
|
||||
begin.x = p_vector.x;
|
||||
}
|
||||
if (p_vector.y < begin.y) {
|
||||
begin.y = p_vector.y;
|
||||
}
|
||||
|
||||
if (p_vector.x > end.x) {
|
||||
end.x = p_vector.x;
|
||||
}
|
||||
if (p_vector.y > end.y) {
|
||||
end.y = p_vector.y;
|
||||
}
|
||||
|
||||
position = begin;
|
||||
size = end - begin;
|
||||
}
|
||||
|
||||
operator String() const
|
||||
{
|
||||
return String(position) + ", " + String(size);
|
||||
}
|
||||
|
||||
operator Rect2() const
|
||||
{
|
||||
return Rect2(position, size);
|
||||
}
|
||||
RegionRect2i(const Rect2 &p_r2)
|
||||
: position(p_r2.position)
|
||||
, size(p_r2.size)
|
||||
{
|
||||
}
|
||||
RegionRect2i(const Rect2i &p_r2)
|
||||
: position(p_r2.position)
|
||||
, size(p_r2.size)
|
||||
{
|
||||
}
|
||||
RegionRect2i()
|
||||
{
|
||||
}
|
||||
RegionRect2i(int p_x, int p_y, int p_width, int p_height)
|
||||
: position(Point2(p_x, p_y))
|
||||
, size(Size2(p_width, p_height))
|
||||
{
|
||||
}
|
||||
RegionRect2i(const Point2 &p_pos, const Size2 &p_size)
|
||||
: position(p_pos)
|
||||
, size(p_size)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // REGION_RECT2_H_
|
||||
@@ -2,17 +2,40 @@
|
||||
#include <cassert>
|
||||
#include <core/ustring.h>
|
||||
#include <core/list.h>
|
||||
#include <core/hashfuncs.h>
|
||||
#include <core/hash_map.h>
|
||||
#include "region_tree.h"
|
||||
|
||||
void region_tree::split(const List<struct region> ®ions)
|
||||
void region_tree::split(flecs::entity grid_floor_e,
|
||||
const List<struct region> ®ions)
|
||||
{
|
||||
assert(children.size() == 0);
|
||||
const region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
||||
const List<struct region>::Element *e = regions.front();
|
||||
int count = 0;
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
while (e) {
|
||||
flecs::log::warn(
|
||||
"%lx: %s -> %s", region.region_et,
|
||||
(region.rect.operator String()).ascii().ptr(),
|
||||
(e->get().rect.operator String()).ascii().ptr());
|
||||
assert(region.rect.encloses(e->get().rect));
|
||||
struct region_tree *child = memnew(struct region_tree);
|
||||
child->parent = this;
|
||||
child->region = e->get();
|
||||
children.push_back(child);
|
||||
base_rtree->dump(grid_floor_e);
|
||||
flecs::log::dbg(
|
||||
"added region: %d: %s", count,
|
||||
(child->region.rect.operator String()).ascii().ptr());
|
||||
if (!base_rtree->check(grid_floor_e))
|
||||
flecs::log::err(
|
||||
"bad region %d: %s: %s", count,
|
||||
(region.rect.operator String()).ascii().ptr(),
|
||||
(e->get().rect.operator String()).ascii().ptr());
|
||||
base_rtree->dump(grid_floor_e);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
count++;
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
@@ -40,6 +63,8 @@ region_tree *region_tree::find(flecs::entity_t which)
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
struct region_tree *item = queue.front()->get();
|
||||
flecs::log::dbg("check %lx == %lx", item->region.region_et,
|
||||
which);
|
||||
if (item->region.region_et == which)
|
||||
return item;
|
||||
queue.pop_front();
|
||||
@@ -62,11 +87,12 @@ void region_tree::dump(flecs::entity grid_floor_e) const
|
||||
int i;
|
||||
for (i = 0; i < tabs; i++)
|
||||
stabs += "\t";
|
||||
flecs::log::warn("%sregion: %s", stabs.ascii().ptr(),
|
||||
flecs::log::warn("%sregion: %s: %lx", stabs.ascii().ptr(),
|
||||
grid_floor_e.world()
|
||||
.entity(item->region.region_et)
|
||||
.path()
|
||||
.c_str());
|
||||
.c_str(),
|
||||
item->region.region_et);
|
||||
flecs::log::warn(
|
||||
"%srect: %s", stabs.ascii().ptr(),
|
||||
(item->region.rect.operator String()).ascii().ptr());
|
||||
@@ -76,13 +102,20 @@ void region_tree::dump(flecs::entity grid_floor_e) const
|
||||
}
|
||||
}
|
||||
|
||||
void region_tree::grow()
|
||||
void region_tree::grow(flecs::entity grid_floor_e)
|
||||
{
|
||||
List<struct region_tree *> grow_list;
|
||||
List<struct region_tree *> queue;
|
||||
List<struct region_tree *>::Element *e, *e1;
|
||||
const struct region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
||||
assert(base_rtree);
|
||||
#ifdef TESTS
|
||||
flecs::log::warn("grow");
|
||||
#endif
|
||||
if (region.complete)
|
||||
queue.push_back(this);
|
||||
else
|
||||
flecs::log::warn("incomplete");
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
struct region_tree *item = queue.front()->get();
|
||||
@@ -95,216 +128,229 @@ void region_tree::grow()
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
}
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
flecs::log::warn("grow list: %d", grow_list.size());
|
||||
e = grow_list.front();
|
||||
int amount = 0;
|
||||
while (e) {
|
||||
struct region_tree *item = e->get();
|
||||
flecs::log::warn(
|
||||
"item: %s",
|
||||
(item->region.rect.operator String()).ascii().ptr());
|
||||
if (!item->region.can_grow) {
|
||||
e = e->next();
|
||||
flecs::log::err("can't grow");
|
||||
continue;
|
||||
int grow_count = 0;
|
||||
queue.clear();
|
||||
struct pointer_hasher {
|
||||
static _FORCE_INLINE_ uint32_t hash(void *ptr)
|
||||
{
|
||||
return hash_one_uint64((uint64_t)ptr);
|
||||
}
|
||||
RegionRect2i candidate = item->region.rect.grow(1);
|
||||
e1 = grow_list.front();
|
||||
bool ok = true;
|
||||
while (e1) {
|
||||
struct region_tree *check_item = e1->get();
|
||||
if (item != check_item) {
|
||||
flecs::log::warn("check item: %s candidate: %s",
|
||||
(check_item->region.rect
|
||||
.operator String())
|
||||
.ascii()
|
||||
.ptr(),
|
||||
(candidate.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
if (!check_item->check_candidate(candidate)) {
|
||||
ok = false;
|
||||
flecs::log::err("check failed");
|
||||
break;
|
||||
}
|
||||
};
|
||||
HashMap<struct region_tree *, int, pointer_hasher> state;
|
||||
while (1) {
|
||||
e = grow_list.front();
|
||||
while (e) {
|
||||
struct region_tree *item = e->get();
|
||||
flecs::log::warn("item: %s",
|
||||
(item->region.rect.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
if (!item->region.can_grow) {
|
||||
e = e->next();
|
||||
flecs::log::err("can't grow");
|
||||
continue;
|
||||
}
|
||||
e1 = e1->next();
|
||||
}
|
||||
if (ok) {
|
||||
item->update_candidate(candidate);
|
||||
amount++;
|
||||
} else {
|
||||
flecs::log::err("can't update candidate");
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
#if 0
|
||||
assert(false);
|
||||
if (region.complete)
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->region.can_grow || item->region.can_grow_square)
|
||||
continue;
|
||||
int i, j;
|
||||
int amount = 0;
|
||||
amount = 0;
|
||||
for (i = 0; i < (int)item->children.size(); i++) {
|
||||
if (item->children[i]->region.can_grow_square) {
|
||||
RegionRect2i candidate =
|
||||
item->children[i]->region.rect.grow(1);
|
||||
if (!item->region.rect.encloses(candidate)) {
|
||||
item->children.write[i]
|
||||
->region.can_grow_square =
|
||||
false;
|
||||
continue;
|
||||
}
|
||||
bool ok = item->check_candidate(i, candidate);
|
||||
if (ok) {
|
||||
item->children.write[i]
|
||||
->update_candidate(candidate);
|
||||
amount++;
|
||||
} else
|
||||
item->children.write[i]
|
||||
->region.can_grow_square =
|
||||
false;
|
||||
if (!state.has(item))
|
||||
state[item] = 0;
|
||||
RegionRect2i candidate = item->region.rect;
|
||||
switch (state[item]) {
|
||||
case 0:
|
||||
candidate = item->region.rect.grow(1);
|
||||
break;
|
||||
case 1:
|
||||
candidate = item->region.rect;
|
||||
candidate.size.x += 1;
|
||||
break;
|
||||
case 2:
|
||||
candidate = item->region.rect;
|
||||
candidate.size.y += 1;
|
||||
break;
|
||||
case 3:
|
||||
candidate = item->region.rect;
|
||||
candidate.position.x -= 1;
|
||||
candidate.size.x += 1;
|
||||
break;
|
||||
case 4:
|
||||
candidate = item->region.rect;
|
||||
candidate.position.y -= 1;
|
||||
candidate.size.y += 1;
|
||||
break;
|
||||
default:
|
||||
state[item]++;
|
||||
}
|
||||
}
|
||||
if (amount > 0) /* try again later */
|
||||
queue.push_back(item);
|
||||
#if 0
|
||||
for (i = 0; i < (int)item->children.size(); i++) {
|
||||
if (!can_grow_square)
|
||||
item->children.write[i]
|
||||
->region.can_grow_square =
|
||||
false;
|
||||
e1 = grow_list.front();
|
||||
bool ok = true;
|
||||
while (e1) {
|
||||
struct region_tree *check_item = e1->get();
|
||||
if (item != check_item) {
|
||||
flecs::log::warn(
|
||||
"check item: %s candidate: %s",
|
||||
(check_item->region.rect
|
||||
.operator String())
|
||||
.ascii()
|
||||
.ptr(),
|
||||
(candidate.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
if (!check_item->check_candidate(
|
||||
candidate)) {
|
||||
ok = false;
|
||||
flecs::log::err("check failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
e1 = e1->next();
|
||||
}
|
||||
while (can_grow) {
|
||||
amount = 0;
|
||||
for (i = 0; i < (int)item->children.size();
|
||||
i++) {
|
||||
if (!item->children[i]->region.can_grow)
|
||||
continue;
|
||||
int orig_area =
|
||||
item->children[i]
|
||||
->region.rect.get_area();
|
||||
RegionRect2i candidate =
|
||||
item->children[i]->region.rect;
|
||||
candidate.size.x += 1;
|
||||
if (!item->region.rect.encloses(
|
||||
candidate))
|
||||
continue;
|
||||
bool ok = item->check_candidate(
|
||||
i, candidate);
|
||||
if (ok) {
|
||||
item->children.write[i]
|
||||
->update_candidate(
|
||||
candidate);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size();
|
||||
i++) {
|
||||
if (!item->children[i]->region.can_grow)
|
||||
continue;
|
||||
int orig_area =
|
||||
item->children[i]
|
||||
->region.rect.get_area();
|
||||
RegionRect2i candidate =
|
||||
item->children[i]->region.rect;
|
||||
candidate.size.x += 1;
|
||||
candidate.position.x -= 1;
|
||||
if (!item->region.rect.encloses(
|
||||
candidate))
|
||||
continue;
|
||||
bool ok = item->check_candidate(
|
||||
i, candidate);
|
||||
if (ok) {
|
||||
item->children.write[i]
|
||||
->update_candidate(
|
||||
candidate);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size();
|
||||
i++) {
|
||||
if (!item->children[i]->region.can_grow)
|
||||
continue;
|
||||
int orig_area =
|
||||
item->children[i]
|
||||
->region.rect.get_area();
|
||||
RegionRect2i candidate =
|
||||
item->children[i]->region.rect;
|
||||
candidate.size.y += 1;
|
||||
if (!item->region.rect.encloses(
|
||||
candidate))
|
||||
continue;
|
||||
bool ok = item->check_candidate(
|
||||
i, candidate);
|
||||
if (ok) {
|
||||
item->children.write[i]
|
||||
->update_candidate(
|
||||
candidate);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size();
|
||||
i++) {
|
||||
if (!item->children[i]->region.can_grow)
|
||||
continue;
|
||||
int orig_area =
|
||||
item->children[i]
|
||||
->region.rect.get_area();
|
||||
RegionRect2i candidate =
|
||||
item->children[i]->region.rect;
|
||||
candidate.size.y += 1;
|
||||
candidate.position.y -= 1;
|
||||
if (!item->region.rect.encloses(
|
||||
candidate))
|
||||
continue;
|
||||
bool ok = item->check_candidate(
|
||||
i, candidate);
|
||||
if (ok) {
|
||||
item->children.write[i]
|
||||
->update_candidate(
|
||||
candidate);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size();
|
||||
i++) {
|
||||
if (item->children[i]
|
||||
->region.remains_area <
|
||||
-100) {
|
||||
item->children[i]
|
||||
->region.can_grow =
|
||||
if (ok) {
|
||||
struct region backup = item->region;
|
||||
item->update_candidate(candidate);
|
||||
if (!base_rtree->check(grid_floor_e)) {
|
||||
item->region = backup;
|
||||
flecs::log::err(
|
||||
"can't update candidate (after checking all rects)");
|
||||
if (state[item] == 0)
|
||||
item->region.can_grow_square =
|
||||
false;
|
||||
item->children[i]
|
||||
->region.complete =
|
||||
true;
|
||||
}
|
||||
state[item]++;
|
||||
}
|
||||
if (amount == 0)
|
||||
can_grow = false;
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
} else {
|
||||
flecs::log::err("can't update candidate");
|
||||
if (state[item] == 0)
|
||||
item->region.can_grow_square = false;
|
||||
state[item]++;
|
||||
}
|
||||
#endif
|
||||
if (item->region.remains_area < -2) {
|
||||
item->region.can_grow = false;
|
||||
item->region.can_grow_square = false;
|
||||
item->region.complete = true;
|
||||
}
|
||||
grow_count++;
|
||||
if (item->region.can_grow && state[item] < 5)
|
||||
queue.push_back(item);
|
||||
else {
|
||||
item->region.can_grow = false;
|
||||
item->region.complete = true;
|
||||
}
|
||||
e = e->next();
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
}
|
||||
if (queue.empty())
|
||||
break;
|
||||
while (!queue.empty()) {
|
||||
grow_list.push_back(queue.front()->get());
|
||||
queue.pop_front();
|
||||
}
|
||||
queue.clear();
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
}
|
||||
}
|
||||
|
||||
bool region_tree::check(flecs::entity grid_floor_e) const
|
||||
{
|
||||
List<const struct region_tree *> queue;
|
||||
assert(!parent);
|
||||
Vector<RegionRect2i> check_regions;
|
||||
Vector<RegionRect2i> root_regions;
|
||||
int i, j;
|
||||
if (children.size() == 0)
|
||||
return true;
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
for (i = 0; i < children.size(); i++)
|
||||
root_regions.push_back(children[i]->region.rect);
|
||||
flecs::log::dbg("root regions count: %d", root_regions.size());
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
const struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->is_leaf()) {
|
||||
const RegionRect2i &rect = item->region.rect;
|
||||
check_regions.push_back(rect);
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size(); i++) {
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
flecs::log::dbg("regions to check: %d", check_regions.size());
|
||||
for (i = 0; i < (int)root_regions.size(); i++)
|
||||
flecs::log::dbg(
|
||||
"root region: %d %s", i,
|
||||
(root_regions[i].operator String()).ascii().ptr());
|
||||
for (i = 0; i < (int)check_regions.size(); i++)
|
||||
flecs::log::dbg(
|
||||
"check region: %d %s", i,
|
||||
(check_regions[i].operator String()).ascii().ptr());
|
||||
int ok = true;
|
||||
for (i = 0; i < (int)check_regions.size(); i++) {
|
||||
if (!region.rect.encloses(check_regions[i])) {
|
||||
flecs::log::err("region is not inside parent");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (root_regions.size() > 0) {
|
||||
for (i = 0; i < (int)check_regions.size(); i++) {
|
||||
int count = 0;
|
||||
if (root_regions.find(check_regions[i]) >= 0)
|
||||
continue;
|
||||
for (j = 0; j < (int)root_regions.size(); j++)
|
||||
if (root_regions[j].encloses(check_regions[i]))
|
||||
count++;
|
||||
if (count == 0) {
|
||||
flecs::log::err(
|
||||
"region is out of root regions");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
return ok;
|
||||
for (i = 0; i < (int)check_regions.size(); i++) {
|
||||
for (j = 0; j < (int)check_regions.size(); j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
if (check_regions[i].intersects(check_regions[j]))
|
||||
ok = false;
|
||||
if (check_regions[i].encloses(check_regions[j]))
|
||||
ok = false;
|
||||
if (check_regions[j].encloses(check_regions[i]))
|
||||
ok = false;
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
if (!ok)
|
||||
flecs::log::err(
|
||||
"some leaf regions intersect other leaf regions");
|
||||
return ok;
|
||||
}
|
||||
|
||||
void region_tree::place(flecs::entity grid_floor_e) const
|
||||
{
|
||||
int i, j;
|
||||
int i, j, k;
|
||||
assert(!parent);
|
||||
List<const struct region_tree *> queue;
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
LocalVector<flecs::entity> delete_cells;
|
||||
grid_floor_e.children([&delete_cells](flecs::entity e) {
|
||||
if (e.has<WorldEditor::components::buildings_layout_grid_cell>())
|
||||
delete_cells.push_back(e);
|
||||
});
|
||||
for (i = 0; i < (int)delete_cells.size(); i++)
|
||||
delete_cells[i].destruct();
|
||||
delete_cells.clear();
|
||||
#if 0
|
||||
for (i = region.rect.position.x;
|
||||
i < region.rect.position.x + region.rect.size.x; i++)
|
||||
for (j = region.rect.position.y;
|
||||
@@ -316,6 +362,39 @@ void region_tree::place(flecs::entity grid_floor_e) const
|
||||
if (cell_e.is_valid())
|
||||
cell_e.destruct();
|
||||
}
|
||||
#endif
|
||||
queue.push_back(this);
|
||||
bool result = true;
|
||||
while (!queue.empty()) {
|
||||
const struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->is_leaf()) {
|
||||
const RegionRect2i &rect = item->region.rect;
|
||||
for (i = rect.position.x;
|
||||
i < rect.position.x + rect.size.x; i++) {
|
||||
for (j = rect.position.y;
|
||||
j < rect.position.y + rect.size.y; j++) {
|
||||
int cell_id = i + grid_size * j;
|
||||
result = check_cell(
|
||||
grid_floor_e,
|
||||
item->region.parent,
|
||||
item->region.region_et,
|
||||
cell_id);
|
||||
if (!result)
|
||||
break;
|
||||
}
|
||||
if (!result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
break;
|
||||
for (i = 0; i < (int)item->children.size(); i++) {
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
}
|
||||
assert(result);
|
||||
queue.clear();
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
const struct region_tree *item = queue.front()->get();
|
||||
@@ -324,8 +403,8 @@ void region_tree::place(flecs::entity grid_floor_e) const
|
||||
const RegionRect2i &rect = item->region.rect;
|
||||
for (i = rect.position.x;
|
||||
i < rect.position.x + rect.size.x; i++)
|
||||
for (j = rect.position.x;
|
||||
j < rect.position.x + rect.size.x; j++) {
|
||||
for (j = rect.position.y;
|
||||
j < rect.position.y + rect.size.y; j++) {
|
||||
int cell_id = i + grid_size * j;
|
||||
update_cell(grid_floor_e,
|
||||
item->region.parent,
|
||||
@@ -337,6 +416,31 @@ void region_tree::place(flecs::entity grid_floor_e) const
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < children.size(); i++) {
|
||||
for (j = children[i]->region.rect.position.x;
|
||||
j < children[i]->region.rect.position.x +
|
||||
children[i]->region.rect.size.x;
|
||||
j++)
|
||||
for (k = children[i]->region.rect.position.y;
|
||||
k < children[i]->region.rect.position.y +
|
||||
children[i]->region.rect.size.y;
|
||||
k++) {
|
||||
int id = j + grid_size * k;
|
||||
String cname("cell_" + itos(id));
|
||||
flecs::entity cell_e = grid_floor_e.lookup(
|
||||
cname.ascii().ptr());
|
||||
if (cell_e.is_valid())
|
||||
continue;
|
||||
#if 0
|
||||
update_cell(grid_floor_e,
|
||||
grid_floor_e.parent().id(),
|
||||
grid_floor_e.id(), id);
|
||||
#endif
|
||||
create_corridoor_cell(
|
||||
grid_floor_e,
|
||||
grid_floor_e.parent().id(), id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void region_tree::get_rects(List<RegionRect2i> *rect_list) const
|
||||
@@ -451,6 +555,63 @@ flecs::entity region_tree::update_cell(flecs::entity grid_floor_e,
|
||||
return cell_e;
|
||||
}
|
||||
|
||||
flecs::entity region_tree::create_corridoor_cell(flecs::entity grid_floor_e,
|
||||
flecs::entity_t parent_et,
|
||||
int id) const
|
||||
{
|
||||
// flecs::entity region_e = grid_floor_e.world().entity(region_et);
|
||||
flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
|
||||
String pname("cell_" + itos(id));
|
||||
flecs::entity cell_e = grid_floor_e.lookup(pname.ascii().ptr());
|
||||
if (!cell_e.is_valid()) {
|
||||
flecs::log::warn("creating new cell %s", pname.ascii().ptr());
|
||||
cell_e = grid_floor_e.world()
|
||||
.entity(pname.ascii().ptr())
|
||||
.child_of(grid_floor_e);
|
||||
assert(cell_e.is_valid());
|
||||
}
|
||||
// assert(cell_e.has<WorldEditor::components::belongs>(parent_e));
|
||||
/* already there */
|
||||
grid_floor_e
|
||||
.get_mut<WorldEditor::components::buildings_layout_grid_floor>()
|
||||
->cells.insert(id);
|
||||
grid_floor_e.modified<
|
||||
WorldEditor::components::buildings_layout_grid_floor>();
|
||||
cell_e.set<WorldEditor::components::buildings_layout_grid_cell>(
|
||||
{ "corridoor", id });
|
||||
cell_e.add<WorldEditor::components::corridoor>();
|
||||
return cell_e;
|
||||
}
|
||||
|
||||
bool region_tree::check_cell(flecs::entity grid_floor_e,
|
||||
flecs::entity_t parent_et,
|
||||
flecs::entity_t region_et, int id) const
|
||||
{
|
||||
flecs::entity region_e = grid_floor_e.world().entity(region_et);
|
||||
flecs::entity parent_e = grid_floor_e.world().entity(parent_et);
|
||||
flecs::log::dbg("check_cell: %s %d", region_e.path().c_str(), id);
|
||||
String pname("cell_" + itos(id));
|
||||
flecs::entity cell_e = grid_floor_e.lookup(pname.ascii().ptr());
|
||||
if (!cell_e.is_valid())
|
||||
return true;
|
||||
int mcount = 0;
|
||||
if (region_e.has<WorldEditor::components::buildings_layout_room>()) {
|
||||
cell_e.each<WorldEditor::components::belongs_room>(
|
||||
[&mcount, region_e, cell_e](flecs::entity e) {
|
||||
flecs::log::err(
|
||||
"while adding region %s to cell %s",
|
||||
region_e.path().c_str(),
|
||||
cell_e.path().c_str());
|
||||
flecs::log::err("already belongs to %s",
|
||||
e.path().c_str());
|
||||
mcount++;
|
||||
});
|
||||
}
|
||||
if (mcount == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void region_tree::update_candidate(const RegionRect2i &candidate)
|
||||
{
|
||||
int orig_area = region.rect.get_area();
|
||||
|
||||
@@ -6,7 +6,8 @@ struct region_tree {
|
||||
struct region region;
|
||||
Vector<struct region_tree *> children;
|
||||
struct region_tree *parent;
|
||||
void split(const List<struct region> ®ions);
|
||||
void split(flecs::entity grid_floor_e,
|
||||
const List<struct region> ®ions);
|
||||
const struct region_tree *find(flecs::entity_t which) const;
|
||||
struct region_tree *find(flecs::entity_t which);
|
||||
bool is_leaf() const
|
||||
@@ -14,7 +15,8 @@ struct region_tree {
|
||||
return children.size() == 0;
|
||||
}
|
||||
void dump(flecs::entity grid_floor_e) const;
|
||||
void grow();
|
||||
void grow(flecs::entity grid_floor_e);
|
||||
bool check(flecs::entity grid_floor_e) const;
|
||||
void place(flecs::entity grid_floor_e) const;
|
||||
void get_rects(List<RegionRect2i> *rect_list) const;
|
||||
|
||||
@@ -24,6 +26,11 @@ private:
|
||||
flecs::entity update_cell(flecs::entity grid_floor_e,
|
||||
flecs::entity_t parent_et,
|
||||
flecs::entity_t region_et, int id) const;
|
||||
flecs::entity create_corridoor_cell(flecs::entity grid_floor_e,
|
||||
flecs::entity_t parent_et,
|
||||
int id) const;
|
||||
bool check_cell(flecs::entity grid_floor_e, flecs::entity_t parent_et,
|
||||
flecs::entity_t region_et, int id) const;
|
||||
void update_candidate(const RegionRect2i &candidate);
|
||||
};
|
||||
#endif // REGION_TREE_H_
|
||||
@@ -123,6 +123,7 @@ public:
|
||||
struct border {};
|
||||
struct belongs_room {};
|
||||
struct outside_wall {};
|
||||
struct corridoor {};
|
||||
struct buildings_layout_grid_floor {
|
||||
Set<int> cells;
|
||||
int grid_size;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
all: graph_test entity_test rect2i regions
|
||||
LIBS=
|
||||
SDL_LIBS=$(shell pkg-config sdl2 --libs)
|
||||
SDL_CFLAGS=$(shell pkg-config sdl2 --cflags)
|
||||
IMGUI_OBJS= ./imgui/imgui.o ./imgui/imgui_draw.o ./imgui/imgui_tables.o ./imgui/imgui_widgets.o ./imgui/imgui_impl_sdlrenderer2.o ./imgui/imgui_impl_sdl2.o
|
||||
# LIBS= ./godot_mockery/libgodot-mockery.a
|
||||
|
||||
CFLAGS = -I../src/flecs/distr -g
|
||||
CXXFLAGS = -I../src/flecs/distr -I../src/modules/stream/ui -I./godot_mockery -I../src/godot -I../src/godot/platform/x11 -I. -I../src/modules/stream -g
|
||||
CFLAGS = -I../src/flecs/distr $(SDL_CFLAGS) -I./cglm/include -I./flecs-game/include -g
|
||||
CXXFLAGS = -I../src/flecs/distr -I../src/modules/stream/ui -I./godot_mockery -I../src/godot -I../src/godot/platform/x11 -I. -I../src/modules/stream -I./imgui $(SDL_CFLAGS) -g
|
||||
#CXXFLAGS = -I../src/flecs/distr -I../src/modules/stream/ui -I../src/godot -I../src/godot/platform/x11 -I. -I../src/modules/stream -g
|
||||
|
||||
graph_test: graph_module.o flecs.o $(LIBS)
|
||||
@@ -20,8 +23,14 @@ rect2i: rect2i.o $(LIBS)
|
||||
region_tree.o: ../src/modules/stream/ui/region_tree.cpp
|
||||
$(CC) $(CFLAGS) $(CXXFLAGS) -DTESTS -o $@ -c $<
|
||||
|
||||
regions: regions.o flecs.o region_tree.o godot_mockery/core/os/memory.o godot_mockery/core/ustring.o $(LIBS)
|
||||
$(CXX) -o $@ regions.o flecs.o region_tree.o godot_mockery/core/os/memory.o godot_mockery/core/ustring.o $(LIBS)
|
||||
#graph_module_growth.o: ../src/modules/stream/ui/graph_module_growth.cpp
|
||||
# $(CC) $(CFLAGS) $(CXXFLAGS) -DTESTS -o $@ -c $<
|
||||
#
|
||||
#graph_module_core.o: ../src/modules/stream/ui/graph_module.cpp
|
||||
# $(CC) $(CFLAGS) $(CXXFLAGS) -DTESTS -o $@ -c $<
|
||||
|
||||
regions: regions.o flecs.o region_tree.o godot_mockery/core/os/memory.o godot_mockery/core/ustring.o $(SDL_LIBS) $(IMGUI_OBJS) $(LIBS)
|
||||
$(CXX) -o $@ regions.o flecs.o region_tree.o godot_mockery/core/os/memory.o godot_mockery/core/ustring.o $(IMGUI_OBJS) $(LIBS) $(SDL_LIBS)
|
||||
|
||||
MOCK_OBJS=godot_mockery/core/os/memory.o godot_mockery/core/error_macros.o \
|
||||
godot_mockery/core/ustring.o godot_mockery/core/array.o \
|
||||
@@ -58,7 +67,7 @@ godot_mockery/core/math/%.o: ../src/godot/core/math/%.cpp
|
||||
$(CC) $(CFLAGS) $(CXXFLAGS) -DTESTS -o $@ -c $<
|
||||
|
||||
clean:
|
||||
rm -f godot_mockery/core/*.o godot_mockery/core/os/*.o *.o graph_test entity_test rect2i regions
|
||||
rm -f godot_mockery/core/*.o godot_mockery/core/os/*.o *.o graph_test entity_test rect2i regions $(FLECS_OBJS)
|
||||
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
Submodule tests/flecs-systems-sokol deleted from 29f521a7d4
@@ -460,4 +460,72 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const char *p_cstr) {
|
||||
uint32_t hashv = 5381;
|
||||
uint32_t c;
|
||||
|
||||
while ((c = *p_cstr++)) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const char *p_cstr, int p_len) {
|
||||
uint32_t hashv = 5381;
|
||||
for (int i = 0; i < p_len; i++) {
|
||||
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const CharType *p_cstr, int p_len) {
|
||||
uint32_t hashv = 5381;
|
||||
for (int i = 0; i < p_len; i++) {
|
||||
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const CharType *p_cstr) {
|
||||
uint32_t hashv = 5381;
|
||||
uint32_t c;
|
||||
|
||||
while ((c = *p_cstr++)) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash() const {
|
||||
/* simple djb2 hashing */
|
||||
|
||||
const CharType *chr = c_str();
|
||||
uint32_t hashv = 5381;
|
||||
uint32_t c;
|
||||
|
||||
while ((c = *chr++)) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint64_t String::hash64() const {
|
||||
/* simple djb2 hashing */
|
||||
|
||||
const CharType *chr = c_str();
|
||||
uint64_t hashv = 5381;
|
||||
uint64_t c;
|
||||
|
||||
while ((c = *chr++)) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,45 @@
|
||||
#include "../src/modules/stream/ui/region_tree.h"
|
||||
#include "../src/modules/stream/ui/grid_misc.h"
|
||||
#include "../src/modules/stream/world_editor.h"
|
||||
#include "../src/modules/stream/ui/queries.h"
|
||||
#include "../src/modules/stream/ui/building_layout_graph.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl2.h"
|
||||
#include "imgui_impl_sdlrenderer2.h"
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
using graph_module = BuildingLayoutGraph::graph_module;
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
SDL_Window *window = NULL;
|
||||
SDL_Surface *screenSurface = NULL;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_WindowFlags window_flags;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
HashMap<String, Color> colors;
|
||||
make_random r(172);
|
||||
|
||||
flecs::world ecs;
|
||||
ecs.component<WorldEditor::components::buildings_layout_grid_floor>();
|
||||
ecs.component<WorldEditor::components::buildings_layout_grid_cell>();
|
||||
flecs::log::set_level(1);
|
||||
flecs::entity graph_base_e = ecs.entity("graph");
|
||||
flecs::entity graph_e = ecs.entity("v1").child_of(graph_base_e);
|
||||
flecs::entity grid_base_e = ecs.entity("grid");
|
||||
flecs::entity grid_e = ecs.entity("v1").child_of(grid_base_e);
|
||||
flecs::entity grid_floor_e = ecs.entity("floor_0").child_of(grid_e);
|
||||
int grid_size = 27;
|
||||
grid_floor_e.set<WorldEditor::components::buildings_layout_grid_floor>({.grid_size = grid_size, .size_left = grid_size * grid_size});
|
||||
List<struct region> region_list;
|
||||
struct region region;
|
||||
region.region_et = graph_e.id();
|
||||
region.rect = RegionRect2i(0, 0, 25, 25);
|
||||
region.rect = RegionRect2i(1, 1, grid_size - 2, grid_size - 2);
|
||||
region.complete = true;
|
||||
region.can_grow = false;
|
||||
region.can_grow_square = false;
|
||||
struct region_tree regions;
|
||||
regions.region = region;
|
||||
regions.dump(grid_floor_e);
|
||||
@@ -20,9 +47,32 @@ int main()
|
||||
zone2_e = ecs.entity("zone2").child_of(graph_e),
|
||||
zone3_e = ecs.entity("zone3").child_of(graph_e);
|
||||
struct region region_data[] = {
|
||||
{.region_et = zone1_e.id(), .rect = {0, 0, 1, 1}},
|
||||
{.region_et = zone2_e.id(), .rect = {2, 2, 1, 1}},
|
||||
{.region_et = zone3_e.id(), .rect = {4, 4, 1 ,1}}
|
||||
{
|
||||
.parent = graph_e.id(),
|
||||
.region_et = zone1_e.id(),
|
||||
.rect = {4, 4, 1, 1},
|
||||
.remains_area = 140,
|
||||
.can_grow_square = true,
|
||||
.can_grow = true,
|
||||
.complete = false
|
||||
},
|
||||
{
|
||||
.parent = graph_e.id(),
|
||||
.region_et = zone2_e.id(),
|
||||
.rect = {4, 9, 1, 1},
|
||||
.remains_area = 80,
|
||||
.can_grow_square = true,
|
||||
.can_grow = true,
|
||||
.complete = false},
|
||||
{
|
||||
.parent = graph_e.id(),
|
||||
.region_et = zone3_e.id(),
|
||||
.rect = {20, 15, 1 ,1},
|
||||
.remains_area = 50,
|
||||
.can_grow_square = true,
|
||||
.can_grow = true,
|
||||
.complete = false
|
||||
}
|
||||
};
|
||||
for (i = 0; i < sizeof(region_data) / sizeof(region_data[0]); i++)
|
||||
region_list.push_back(region_data[i]);
|
||||
@@ -30,6 +80,109 @@ int main()
|
||||
regions.dump(grid_floor_e);
|
||||
regions.grow();
|
||||
regions.dump(grid_floor_e);
|
||||
regions.place(grid_floor_e);
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef SDL_HINT_IME_SHOW_UI
|
||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||
#endif
|
||||
window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
|
||||
window = SDL_CreateWindow("RegionTest", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 1024, window_flags);
|
||||
if (window == NULL)
|
||||
goto out;
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer)
|
||||
goto out;
|
||||
// screenSurface = SDL_GetWindowSurface(window);
|
||||
// if (!screenSurface)
|
||||
// goto out;
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
}
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer2_Init(renderer);
|
||||
// SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
|
||||
// SDL_UpdateWindowSurface(window);
|
||||
SDL_Event event;
|
||||
while(1) {
|
||||
SDL_PollEvent(&event);
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
switch(event.type) {
|
||||
case SDL_QUIT:
|
||||
goto shutdown;
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||
goto shutdown;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
ecs.progress();
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) {
|
||||
SDL_Delay(10);
|
||||
continue;
|
||||
}
|
||||
ImGui_ImplSDLRenderer2_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
{
|
||||
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
||||
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::Render();
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
|
||||
SDL_RenderClear(renderer);
|
||||
ecs.query_builder<const WorldEditor::components::buildings_layout_grid_cell>()
|
||||
.build().each([grid_size, renderer, &colors, &r](flecs::entity e, const WorldEditor::components::buildings_layout_grid_cell &cell)
|
||||
{
|
||||
// flecs::log::warn("cell: %s: %s: %d", e.path().c_str(), cell.type.ascii().ptr(), cell.index);
|
||||
int x = cell.index % grid_size;
|
||||
int y = cell.index / grid_size;
|
||||
int px = 1280 * x / grid_size;
|
||||
int py = 1024 * y / grid_size;
|
||||
int w = 1280 / grid_size;
|
||||
int h = 1024 / grid_size;
|
||||
// flecs::log::warn("position: %d %d", x, y);
|
||||
if (!colors.has(cell.type))
|
||||
colors[cell.type] = Color((float)(r.get() % 256) / 256.0f, (float)(r.get() % 256) / 256.0f, (float)(r.get() % 256) / 256.0f, 1.0f);
|
||||
const Color &c = colors[cell.type];
|
||||
SDL_SetRenderDrawColor(renderer, (uint8_t)(c.r * 255), (uint8_t)(c.g * 255), (uint8_t)(c.b * 255), 255);
|
||||
SDL_Rect rect = {px, py, w, h};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 15, 15, 255);
|
||||
SDL_RenderDrawRect(renderer, &rect);
|
||||
});
|
||||
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
shutdown:
|
||||
ImGui_ImplSDLRenderer2_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user