Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include <tier0/platform.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <stdlib.h>
  7. #include "bitmap/float_bm.h"
  8. #include <filesystem.h>
  9. #include <mathlib/vector.h>
  10. static Vector face_xvector[6]={ // direction of x pixels on face
  11. Vector(-1,0,0), // back
  12. Vector(1,0,0), // down
  13. Vector(1,0,0), // front
  14. Vector(0,1,0), // left
  15. Vector(0,-1,0), // right
  16. Vector(1,0,0) // up
  17. };
  18. static Vector face_yvector[6]={ // direction of y pixels on face
  19. Vector(0,0,-1), // back
  20. Vector(0,1,0), // down
  21. Vector(0,0,-1), // front
  22. Vector(0,0,-1), // left
  23. Vector(0,0,-1), // right
  24. Vector(0,-1,0) // up
  25. };
  26. static Vector face_zvector[6]={
  27. Vector(1,1,1), // back
  28. Vector(-1,-1,-1), // down
  29. Vector(-1,-1,1), // front
  30. Vector(1,-1,1), // left
  31. Vector(-1,1,1), // right
  32. Vector(-1,1,1) // up
  33. };
  34. static char const *namepts[6]={"%sbk.pfm","%sdn.pfm","%sft.pfm","%slf.pfm","%srt.pfm","%sup.pfm"};
  35. FloatCubeMap_t::FloatCubeMap_t(char const *basename)
  36. {
  37. for(int f=0;f<6;f++)
  38. {
  39. char fnamebuf[512];
  40. sprintf(fnamebuf,namepts[f],basename);
  41. face_maps[f].LoadFromPFM(fnamebuf);
  42. }
  43. }
  44. void FloatCubeMap_t::WritePFMs(char const *basename)
  45. {
  46. for(int f=0;f<6;f++)
  47. {
  48. char fnamebuf[512];
  49. sprintf(fnamebuf,namepts[f],basename);
  50. face_maps[f].WritePFM(fnamebuf);
  51. }
  52. }
  53. Vector FloatCubeMap_t::PixelDirection(int face, int x, int y)
  54. {
  55. FloatBitMap_t const &bm=face_maps[face];
  56. float xc=x*1.0/(bm.Width-1);
  57. float yc=y*1.0/(bm.Height-1);
  58. Vector dir=2*xc*face_xvector[face]+
  59. 2*yc*face_yvector[face]+face_zvector[face];
  60. VectorNormalize(dir);
  61. return dir;
  62. }
  63. Vector FloatCubeMap_t::FaceNormal(int face)
  64. {
  65. float xc=0.5;
  66. float yc=0.5;
  67. Vector dir=2*xc*face_xvector[face]+
  68. 2*yc*face_yvector[face]+face_zvector[face];
  69. VectorNormalize(dir);
  70. return dir;
  71. }
  72. void FloatCubeMap_t::Resample( FloatCubeMap_t &out, float flPhongExponent )
  73. {
  74. // terribly slow brute force algorithm just so I can try it out
  75. for(int dface=0;dface<6;dface++)
  76. {
  77. for(int dy=0;dy<out.face_maps[dface].Height;dy++)
  78. for(int dx=0;dx<out.face_maps[dface].Width;dx++)
  79. {
  80. float sum_weights=0;
  81. float sum_rgb[3]={0,0,0};
  82. for(int sface=0;sface<6;sface++)
  83. {
  84. // easy 15% optimization - check if faces point away from each other
  85. if (DotProduct(FaceNormal(sface),FaceNormal(sface))>-0.9)
  86. {
  87. Vector ddir=out.PixelDirection(dface,dx,dy);
  88. for(int sy=0;sy<face_maps[sface].Height;sy++)
  89. for(int sx=0;sx<face_maps[sface].Width;sx++)
  90. {
  91. float dp=DotProduct(ddir,PixelDirection(sface,sx,sy));
  92. if (dp>0.0)
  93. {
  94. dp=pow( dp, flPhongExponent );
  95. sum_weights += dp;
  96. for(int c=0;c<3;c++)
  97. sum_rgb[c] += dp*face_maps[sface].Pixel( sx, sy, c );
  98. }
  99. }
  100. }
  101. }
  102. for(int c=0;c<3;c++)
  103. out.face_maps[dface].Pixel( dx, dy, c )=sum_rgb[c]*(1.0/sum_weights);
  104. }
  105. }
  106. }