Changeset 472 for GraphicTest/Packages/bgrabitmap/bgracoordpool3d.pas
- Timestamp:
- Apr 9, 2015, 9:58:36 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgracoordpool3d.pas
r452 r472 6 6 7 7 uses 8 Classes, SysUtils, BGRABitmapTypes, BGRASSE ;8 Classes, SysUtils, BGRABitmapTypes, BGRASSE, BGRAMatrix3D; 9 9 10 10 type … … 15 15 {32} projectedCoord: TPointF; 16 16 {40} InvZ: single; 17 {44} used: longbool;17 {44} used: wordbool; customNormalUsed: wordbool; 18 18 {48} viewNormal: TPoint3D_128; 19 end; {64} 20 21 { TBGRACoordPool3D } 22 23 TBGRACoordPool3D = class 19 {64} customNormal: TPoint3D_128; 20 end; {80} 21 22 PBGRANormalData3D = ^TBGRANormalData3D; 23 TBGRANormalData3D = packed record 24 {0} customNormal: TPoint3D_128; 25 {16} viewNormal: TPoint3D_128; 26 {32} used: longbool; 27 {36} filler1,filler2,filler3: longword; 28 end; {48} 29 30 { TBGRAGenericPool } 31 32 TBGRAGenericPool = class 24 33 private 25 34 FFirstFree: integer; 26 FNbCoord,FCapacity: integer; 35 FNbElements,FCapacity: integer; 36 FElementSize: PtrInt; 37 FUsedCapacity : integer; 38 function GetElement(AIndex: integer): Pointer; 39 procedure SetCapacity(ACapacity: integer); 40 protected 27 41 FPoolData: TMemoryBlockAlign128; 28 FUsedCapacity : integer;29 function GetCoordData(AIndex: integer): PBGRACoordData3D;30 procedure SetCapacity(ACapacity: integer);42 function GetUsed({%H-}AElement: integer): boolean; virtual; 43 procedure SetUsed({%H-}AElement: integer; {%H-}AUsed: boolean); virtual; 44 procedure Remove(AIndex: integer); //does not work if GetUsed/SetUsed are not implemented 31 45 public 32 constructor Create(ACapacity: integer );46 constructor Create(ACapacity: integer; AElementSize: integer); 33 47 destructor Destroy; override; 34 procedure Remove(AIndex: integer);35 48 function Add: integer; 36 property CoordData[AIndex: integer]: PBGRACoordData3D read GetCoordData;49 property Element[AIndex: integer]: Pointer read GetElement; 37 50 property Capacity: integer read FCapacity; 38 51 property UsedCapacity: integer read FUsedCapacity; 39 52 end; 40 53 54 { TBGRACoordPool3D } 55 56 TBGRACoordPool3D = class(TBGRAGenericPool) 57 private 58 function GetCoordData(AIndex: integer): PBGRACoordData3D; 59 protected 60 function GetUsed(AElement: integer): boolean; override; 61 procedure SetUsed(AElement: integer; AUsed: boolean); override; 62 public 63 procedure Remove(AIndex: integer); 64 constructor Create(ACapacity: integer); 65 procedure ComputeWithMatrix(const AMatrix: TMatrix3D; const AProjection: TProjection3D); 66 property CoordData[AIndex: integer]: PBGRACoordData3D read GetCoordData; 67 end; 68 69 { TBGRANormalPool3D } 70 71 TBGRANormalPool3D = class(TBGRAGenericPool) 72 private 73 function GetNormalData(AIndex: integer): PBGRANormalData3D; 74 protected 75 function GetUsed(AElement: integer): boolean; override; 76 procedure SetUsed(AElement: integer; AUsed: boolean); override; 77 public 78 procedure Remove(AIndex: integer); 79 constructor Create(ACapacity: integer); 80 procedure ComputeWithMatrix(const AMatrix: TMatrix3D); 81 property NormalData[AIndex: integer]: PBGRANormalData3D read GetNormalData; 82 end; 83 41 84 implementation 42 85 43 { TBGRACoordPool3D } 44 45 procedure TBGRACoordPool3D.SetCapacity(ACapacity: integer); 86 { TBGRAGenericPool } 87 88 function TBGRAGenericPool.GetElement(AIndex: integer): Pointer; 89 begin 90 result := Pointer(PByte(FPoolData.Data)+AIndex*FElementSize); 91 end; 92 93 procedure TBGRAGenericPool.SetCapacity(ACapacity: integer); 46 94 var NewPoolData: TMemoryBlockAlign128; 47 95 begin … … 52 100 else 53 101 begin 54 NewPoolData := TMemoryBlockAlign128.Create(ACapacity* sizeof(TBGRACoordData3D));102 NewPoolData := TMemoryBlockAlign128.Create(ACapacity*FElementSize); 55 103 if FCapacity <> 0 then 56 104 begin … … 58 106 if FCapacity < ACapacity then 59 107 begin 60 move(FPoolData.Data^, NewPoolData.Data^, FCapacity* sizeof(TBGRACoordData3D));108 move(FPoolData.Data^, NewPoolData.Data^, FCapacity*FElementSize); 61 109 //pad with zeros 62 fillchar((pbyte(NewPoolData.Data)+FCapacity* sizeof(TBGRACoordData3D))^,(ACapacity-FCapacity)*sizeof(TBGRACoordData3D),0);110 fillchar((pbyte(NewPoolData.Data)+FCapacity*FElementSize)^,(ACapacity-FCapacity)*FElementSize,0); 63 111 end 64 112 else //previous block is greater or equal 65 move(FPoolData.Data^, NewPoolData.Data^, ACapacity* sizeof(TBGRACoordData3D));113 move(FPoolData.Data^, NewPoolData.Data^, ACapacity*FElementSize); 66 114 FreeAndNil(FPoolData); 67 115 end else 68 116 //clear new block 69 fillchar(pbyte(NewPoolData.Data)^,ACapacity* sizeof(TBGRACoordData3D),0);117 fillchar(pbyte(NewPoolData.Data)^,ACapacity*FElementSize,0); 70 118 71 119 FPoolData := NewPoolData; … … 75 123 end; 76 124 77 constructor TBGRACoordPool3D.Create(ACapacity: integer); 125 function TBGRAGenericPool.GetUsed(AElement: integer): boolean; 126 begin 127 result := false; 128 end; 129 130 procedure TBGRAGenericPool.SetUsed(AElement: integer; AUsed: boolean); 131 begin 132 //nothing 133 end; 134 135 constructor TBGRAGenericPool.Create(ACapacity: integer; AElementSize: integer); 78 136 begin 79 137 FCapacity := 0; 80 138 FPoolData := nil; 81 FNb Coord:= 0;139 FNbElements:= 0; 82 140 FFirstFree := 0; 83 141 FUsedCapacity := 0; 142 FElementSize:= AElementSize; 84 143 SetCapacity(ACapacity); 85 144 end; 86 145 87 destructor TBGRACoordPool3D.Destroy; 88 begin 89 FPoolData.Free; 146 destructor TBGRAGenericPool.Destroy; 147 begin 148 FreeAndNil(FPoolData); 149 FCapacity := 0; 150 FNbElements:= 0; 151 FFirstFree := 0; 152 FUsedCapacity := 0; 90 153 inherited Destroy; 91 154 end; 92 155 93 procedure TBGRACoordPool3D.Remove(AIndex: integer); 94 begin 95 if CoordData[AIndex]^.used then 96 begin 97 CoordData[AIndex]^.used := false; 156 procedure TBGRAGenericPool.Remove(AIndex: integer); 157 begin 158 if (AIndex < 0) or (AIndex >= FUsedCapacity) then 159 raise ERangeError.Create('Index out of bounds'); 160 if GetUsed(AIndex) then 161 begin 162 SetUsed(AIndex, false); 98 163 if AIndex < FFirstFree then FFirstFree := AIndex; 99 164 if AIndex = FUsedCapacity-1 then 100 165 begin 101 while (FUsedCapacity > 0) and not CoordData[FUsedCapacity-1]^.useddo166 while (FUsedCapacity > 0) and not GetUsed(FUsedCapacity-1) do 102 167 dec(FUsedCapacity); 103 168 end; … … 105 170 end; 106 171 107 function TBGRA CoordPool3D.Add: integer;172 function TBGRAGenericPool.Add: integer; 108 173 begin 109 174 //check for free space 110 175 while FFirstFree < FCapacity do 111 176 begin 112 if not CoordData[FFirstFree]^.usedthen113 begin 114 CoordData[FFirstFree]^.used := false;177 if not GetUsed(FFirstFree) then 178 begin 179 SetUsed(FFirstFree,True); 115 180 result := FFirstFree; 116 181 inc(FFirstFree); … … 124 189 //no free space 125 190 SetCapacity(FCapacity*2+8); 126 CoordData[FFirstFree]^.used := false;191 SetUsed(FFirstFree, true); 127 192 result := FFirstFree; 128 193 inc(FFirstFree); … … 131 196 end; 132 197 198 { TBGRACoordPool3D } 199 200 constructor TBGRACoordPool3D.Create(ACapacity: integer); 201 begin 202 inherited Create(ACapacity,SizeOf(TBGRACoordData3D)); 203 end; 204 205 procedure TBGRACoordPool3D.ComputeWithMatrix(const AMatrix: TMatrix3D; 206 const AProjection: TProjection3D); 207 var 208 P: PBGRACoordData3D; 209 I: NativeInt; 210 begin 211 if UsedCapacity = 0 then exit; 212 P := PBGRACoordData3D(FPoolData.Data); 213 {$IFDEF CPUI386} 214 {$asmmode intel} 215 if UseSSE then 216 begin 217 Matrix3D_SSE_Load(AMatrix); 218 asm 219 mov eax,[AProjection] 220 movups xmm4,[eax] 221 xorps xmm1,xmm1 222 end; 223 i := UsedCapacity; 224 if UseSSE3 then 225 begin 226 while i > 0 do 227 with P^ do 228 begin 229 if used then 230 begin 231 MatrixMultiplyVect3D_SSE3_Aligned(sceneCoord,viewCoord); 232 if viewCoord.z > 0 then 233 begin 234 asm 235 mov eax, P 236 movaps xmm3, [eax+16] //viewCoord 237 movaps xmm2,xmm3 238 shufps xmm2,xmm3,2+8+32+128 239 rcpps xmm2,xmm2 //xmm2 = InvZ 240 movss [eax+40],xmm2 //-> InvZ 241 242 mulps xmm3,xmm4 //xmm3 *= Projection.Zoom 243 mulps xmm3,xmm2 //xmm3 *= InvZ 244 245 movhlps xmm0,xmm4 //xmm0 = Projection.Center 246 addps xmm3,xmm0 //xmm3 += Projection.Center 247 248 movlps [eax+32],xmm3 //->projectedCoord 249 movaps [eax+48],xmm1 //->normal 250 end; 251 end else 252 asm 253 mov eax, P 254 movlps [eax+32],xmm1 //0->projectedCoord 255 movaps [eax+48],xmm1 //->normal 256 end; 257 if customNormalUsed then 258 MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(customNormal,viewNormal); 259 end; 260 dec(i); 261 inc(p); 262 end; 263 end else 264 begin 265 while i > 0 do 266 with P^ do 267 begin 268 if used then 269 begin 270 MatrixMultiplyVect3D_SSE_Aligned(sceneCoord,viewCoord); 271 if viewCoord.z > 0 then 272 begin 273 asm 274 mov eax, P 275 movaps xmm3, [eax+16] //viewCoord 276 movaps xmm2,xmm3 277 shufps xmm2,xmm3,2+8+32+128 278 rcpps xmm2,xmm2 //xmm2 = InvZ 279 movss [eax+40],xmm2 //-> InvZ 280 281 mulps xmm3,xmm4 //xmm3 *= Projection.Zoom 282 mulps xmm3,xmm2 //xmm3 *= InvZ 283 284 movhlps xmm0,xmm4 //xmm0 = Projection.Center 285 addps xmm3,xmm0 //xmm3 += Projection.Center 286 287 movlps [eax+32],xmm3 //->projectedCoord 288 movaps [eax+48],xmm1 //->normal 289 end; 290 end else 291 asm 292 mov eax, P 293 movlps [eax+32],xmm1 //0 ->projectedCoord 294 movaps [eax+48],xmm1 //->normal 295 end; 296 if customNormalUsed then 297 MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(customNormal,viewNormal); 298 end; 299 dec(i); 300 inc(p); 301 end; 302 end; 303 end 304 else 305 {$ENDIF} 306 begin 307 i := UsedCapacity; 308 while i > 0 do 309 with P^ do 310 begin 311 if used then 312 begin 313 viewCoord := AMatrix*sceneCoord; 314 if customNormalUsed then 315 viewNormal := MultiplyVect3DWithoutTranslation(AMatrix,customNormal) 316 else 317 ClearPoint3D_128(viewNormal); 318 if viewCoord.z > 0 then 319 begin 320 InvZ := 1/viewCoord.z; 321 projectedCoord := PointF(viewCoord.x*InvZ*AProjection.Zoom.x + AProjection.Center.x, 322 viewCoord.y*InvZ*AProjection.Zoom.Y + AProjection.Center.y); 323 end else 324 projectedCoord := PointF(0,0); 325 end; 326 dec(i); 327 inc(p); 328 end; 329 end; 330 end; 331 133 332 function TBGRACoordPool3D.GetCoordData(AIndex: integer): PBGRACoordData3D; 134 333 begin … … 136 335 end; 137 336 337 function TBGRACoordPool3D.GetUsed(AElement: integer): boolean; 338 begin 339 Result:= CoordData[AElement]^.used; 340 end; 341 342 procedure TBGRACoordPool3D.SetUsed(AElement: integer; AUsed: boolean); 343 begin 344 CoordData[AElement]^.used := AUsed; 345 end; 346 347 procedure TBGRACoordPool3D.Remove(AIndex: integer); 348 begin 349 inherited Remove(AIndex); 350 end; 351 352 { TBGRANormalPool3D } 353 354 function TBGRANormalPool3D.GetNormalData(AIndex: integer): PBGRANormalData3D; 355 begin 356 result := PBGRANormalData3D(FPoolData.Data)+AIndex; 357 end; 358 359 function TBGRANormalPool3D.GetUsed(AElement: integer): boolean; 360 begin 361 Result:= NormalData[AElement]^.used; 362 end; 363 364 procedure TBGRANormalPool3D.SetUsed(AElement: integer; AUsed: boolean); 365 begin 366 NormalData[AElement]^.used := AUsed; 367 end; 368 369 procedure TBGRANormalPool3D.Remove(AIndex: integer); 370 begin 371 inherited Remove(AIndex); 372 end; 373 374 constructor TBGRANormalPool3D.Create(ACapacity: integer); 375 begin 376 inherited Create(ACapacity,SizeOf(TBGRANormalData3D)); 377 end; 378 379 procedure TBGRANormalPool3D.ComputeWithMatrix(const AMatrix: TMatrix3D); 380 var 381 P: PBGRANormalData3D; 382 I: NativeInt; 383 begin 384 if UsedCapacity = 0 then exit; 385 P := PBGRANormalData3D(FPoolData.Data); 386 {$IFDEF CPUI386} 387 {$asmmode intel} 388 if UseSSE then 389 begin 390 Matrix3D_SSE_Load(AMatrix); 391 i := UsedCapacity; 392 if UseSSE3 then 393 begin 394 while i > 0 do 395 with P^ do 396 begin 397 if used then 398 MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(customNormal,viewNormal); 399 dec(i); 400 inc(p); 401 end; 402 end else 403 begin 404 while i > 0 do 405 with P^ do 406 begin 407 if used then 408 MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(customNormal,viewNormal); 409 dec(i); 410 inc(p); 411 end; 412 end; 413 end 414 else 415 {$ENDIF} 416 begin 417 i := UsedCapacity; 418 while i > 0 do 419 with P^ do 420 begin 421 if used then 422 viewNormal := MultiplyVect3DWithoutTranslation(AMatrix,customNormal); 423 dec(i); 424 inc(p); 425 end; 426 end; 427 end; 428 138 429 end. 139 430
Note:
See TracChangeset
for help on using the changeset viewer.