X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=eabf89645796ad273a1a78531c031497a40b3772;hb=28bf5dfda4876c1aea86811c7dec26992bfe6435;hp=c9851ee57bb6ec63e8822a8aeae444c19f4442eb;hpb=e27a7539a5cd40fb3a15c6daef0e18817b7c9bd8;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index c9851ee..eabf896 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -20,7 +20,7 @@ interface uses e_graphics, g_basic, MAPSTRUCT, g_textures, Classes, - g_phys, wadreader, BinEditor, g_panel, g_grid, g_sap, md5, xprofiler; + g_phys, wadreader, BinEditor, g_panel, g_grid, z_aabbtree, md5, xprofiler; type TMapInfo = record @@ -136,7 +136,8 @@ var gdbg_map_use_grid_render: Boolean = true; gdbg_map_use_grid_coldet: Boolean = true; - gdbg_map_use_sap: Boolean = false; + gdbg_map_use_tree_draw: Boolean = true; + gdbg_map_use_tree_coldet: Boolean = false; profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! implementation @@ -190,6 +191,22 @@ type PArrID: Integer; end; +type + TDynAABBTreeMap = class(TDynAABBTree) + function getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh): Boolean; override; + end; + +function TDynAABBTreeMap.getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh): Boolean; +var + pan: TPanel; +begin + if (flesh = nil) then begin result := false; exit; end; + pan := (flesh as TPanel); + aabb := AABB2D.Create(pan.X, pan.Y, pan.X+pan.Width, pan.Y+pan.Height); + //e_WriteLog(Format('getFleshAABB(%d;%d) AABB:(%f,%f)-(%f,%f); valid=%d; volume=%f; x=%d; y=%d; w=%d; h=%d', [pan.tag, pan.ArrIdx, aabb.minX, aabb.minY, aabb.maxX, aabb.maxY, Integer(aabb.valid), aabb.volume, pan.X, pan.Y, pan.Width, pan.Height]), MSG_NOTIFY); + result := aabb.valid; +end; + var PanelById: array of TPanelID; Textures: TLevelTextureArray; @@ -197,7 +214,7 @@ var FlagPoints: Array [FLAG_RED..FLAG_BLUE] of PFlagPoint; //DOMFlagPoints: Array of TFlagPoint; gMapGrid: TBodyGrid = nil; - gMapSAP: TSweepAndPrune = nil; + mapTree: TDynAABBTree = nil; procedure g_Map_ProfilersBegin (); @@ -429,6 +446,7 @@ begin panels^[len] := TPanel.Create(PanelRec, AddTextures, CurTex, Textures); panels^[len].ArrIdx := len; + panels^[len].tag := panelTypeToTag(PanelRec.PanelType); if sav then panels^[len].SaveIt := True; @@ -985,16 +1003,17 @@ var tag := panelTypeToTag(tag); for idx := High(panels) downto 0 do begin + panels[idx].tag := tag; gMapGrid.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); - gMapSAP.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); + mapTree.insertObject(panels[idx], true); // as static object end; end; begin gMapGrid.Free(); gMapGrid := nil; - gMapSAP.Free(); - gMapSAP := nil; + mapTree.Free(); + mapTree := nil; fixMinMax(gWalls); fixMinMax(gRenderBackgrounds); @@ -1013,7 +1032,7 @@ begin end; gMapGrid := TBodyGrid.Create(mapX0, mapY0, mapX1-mapX0+1, mapY1-mapY0+1); - gMapSAP := TSweepAndPrune.Create(); + mapTree := TDynAABBTreeMap.Create(); addPanelsToGrid(gWalls, PANEL_WALL); // and PANEL_CLOSEDOOR addPanelsToGrid(gRenderBackgrounds, PANEL_BACK); @@ -1026,7 +1045,8 @@ begin addPanelsToGrid(gBlockMon, PANEL_BLOCKMON); gMapGrid.dumpStats(); - gMapSAP.dumpStats(); + e_WriteLog(Format('tree depth: %d; %d nodes used, %d nodes allocated', [mapTree.computeTreeHeight, mapTree.nodeCount, mapTree.nodeAlloced]), MSG_NOTIFY); + mapTree.forEachLeaf(nil); end; function g_Map_Load(Res: String): Boolean; @@ -1063,8 +1083,8 @@ var begin gMapGrid.Free(); gMapGrid := nil; - gMapSAP.Free(); - gMapSAP := nil; + mapTree.Free(); + mapTree := nil; Result := False; gMapInfo.Map := Res; @@ -1892,6 +1912,18 @@ var dplAddPanel(pan); end; + function checkerTree (obj: TObject): Boolean; + var + pan: TPanel; + begin + result := false; // don't stop, ever + pan := (obj as TPanel); + if (pan.tag <> ptag) then exit; + if (PanelType = PANEL_CLOSEDOOR) then begin if not pan.Door then exit; end else begin if pan.Door then exit; end; + //e_WriteLog(Format(' body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); + dplAddPanel(pan); + end; + procedure DrawPanels (stp: Integer; var panels: TPanelArray; drawDoors: Boolean=False); var idx: Integer; @@ -1926,9 +1958,9 @@ begin if gdbg_map_use_grid_render then begin - if gdbg_map_use_sap then + if gdbg_map_use_tree_draw then begin - gMapSAP.forEachInAABB(x0, y0, wdt, hgt, checker); + mapTree.aabbQuery(x0, y0, wdt, hgt, checkerTree); end else begin @@ -1971,10 +2003,20 @@ procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: pan.DrawShadowVolume(lightX, lightY, radius); end; + function checkerTree (obj: TObject): Boolean; + var + pan: TPanel; + begin + result := false; // don't stop, ever + pan := (obj as TPanel); + if (pan.tag <> GridTagWallDoor) then exit; // only walls + pan.DrawShadowVolume(lightX, lightY, radius); + end; + begin - if gdbg_map_use_sap then + if gdbg_map_use_tree_draw then begin - gMapSAP.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker); + mapTree.aabbQuery(lightX-radius, lightY-radius, radius*2, radius*2, checkerTree); end else begin @@ -2235,15 +2277,23 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; + function checkerTree (obj: TObject): Boolean; + var + pan: TPanel; + begin + pan := (obj as TPanel); + result := checker(obj, pan.tag); + end; + begin //TODO: detailed profile if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('wall coldet'); try if gdbg_map_use_grid_coldet then begin - if gdbg_map_use_sap then + if gdbg_map_use_tree_coldet then begin - gMapSAP.forEachInAABB(X, Y, Width, Height, checker); + result := mapTree.aabbQuery(X, Y, Width, Height, checkerTree); end else begin @@ -2306,6 +2356,18 @@ var end; end; + function checkerTree (obj: TObject): Boolean; + var + pan: TPanel; + begin + result := false; + pan := (obj as TPanel); + if (pan.tag = GridTagWater) or (pan.tag = GridTagAcid1) or (pan.tag = GridTagAcid2) then result := checker(obj, pan.tag); + end; + +{var + cctype1: Integer = 3; // priority: 0: water, 1: acid1, 2: acid2; 3: others (nothing) + texid1: DWORD;} begin //TODO: detailed profile? if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquid coldet'); @@ -2313,9 +2375,19 @@ begin if gdbg_map_use_grid_coldet then begin texid := TEXTURE_NONE; - if gdbg_map_use_sap then + if gdbg_map_use_tree_coldet then begin - gMapSAP.forEachInAABB(X, Y, Width, Height, checker); + mapTree.aabbQuery(X, Y, Width, Height, checkerTree); + { + cctype1 := cctype; + texid1 := texid; + cctype := 3; + texid := TEXTURE_NONE; + gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + if (cctype1 <> cctype) or (texid1 <> texid) then + begin + e_WriteLog(Format('g_Map_CollideLiquid_Texture(%d, %d, %u, %u): tree(cctype:%d;texid:%u); grid(cctype:%d;texid:%u)', [X, Y, Width, Height, cctype1, texid1, cctype, texid]), MSG_WARNING); + end;} end else begin