00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _AKIMAGESOURCE_H_
00029 #define _AKIMAGESOURCE_H_
00030
00031 #include <AK/Tools/Common/AkVectors.h>
00032 #include <AK/Tools/Common/AkListBare.h>
00033
00034 #ifdef _WIN64
00035 #define AK_RUNTIME 1
00036 #endif
00037
00038 const int MIRROR_COUNT = 6;
00039
00040 class AkPortalLink
00041 {
00042 public:
00043 AkPortalLink():
00044 m_BoxID(-1),
00045 m_FaceID(-1)
00046 {
00047 }
00048
00049 AkPortalLink(
00050 AkInt32 in_BoxID,
00051 AkInt32 in_FaceID,
00052 AkBoundingBox in_Opening):
00053 m_BoxID(in_BoxID),
00054 m_FaceID(in_FaceID),
00055 m_Opening(in_Opening)
00056 {
00057 }
00058
00059 AkInt32 m_BoxID;
00060 AkInt32 m_FaceID;
00061 AkBoundingBox m_Opening;
00062 };
00063
00064 class AkImageSourceReflector
00065 {
00066 public:
00067 AkImageSourceReflector();
00068 AkImageSourceReflector(
00069 Ak3DVector in_p1,
00070 Ak3DVector in_p2,
00071 Ak3DVector in_p4,
00072 AkUInt32 in_uMaterialID
00073 );
00074
00075 ~AkImageSourceReflector();
00076
00077 AKRESULT Set(
00078 Ak3DVector in_p1,
00079 Ak3DVector in_p2,
00080 Ak3DVector in_p4,
00081 AkUInt32 in_uMaterialID
00082 );
00083
00084 AKRESULT Reflect(
00085 Ak3DVector in_p,
00086 Ak3DVector& out_p
00087 ) const;
00088
00089 bool UpdatePortal(
00090 const AkPlane& in_PlaneB,
00091 AkBoundingBox& out_BoundingBox
00092 );
00093
00094 AkUInt32 GetMaterialID() const
00095 {
00096 return m_uMaterialID;
00097 }
00098
00099 const AkPlane GetPlane() const
00100 {
00101 return m_Plane;
00102 }
00103
00104 private:
00105
00106 AkUInt32 m_uMaterialID;
00107
00108 AkMatrix4x4 m_pReflectionMatrix;
00109
00110 AkPlane m_Plane;
00111 };
00112
00113 enum AkImageSourceBoxState
00114 {
00115 AkImageSourceBox_Unused,
00116 AkImageSourceBox_Used
00117 };
00118
00119 struct AkAcousticPortalParams
00120 {
00121 AkAcousticPortalParams() :
00122 fDensity(0.f),
00123 fDiffusion(0.f)
00124 {}
00125
00126 AkReal32 fDensity;
00127 AkReal32 fDiffusion;
00128 };
00129
00130 class AkSynthSpaceAllocManager
00131 {
00132 public:
00133 static AkSynthSpaceAllocManager* Create(AK::IAkPluginMemAlloc * in_pAllocator)
00134 {
00135 AKASSERT(!m_pInstance);
00136 AKASSERT(in_pAllocator);
00137 m_pInstance = (AkSynthSpaceAllocManager *)AK_PLUGIN_NEW(in_pAllocator, AkSynthSpaceAllocManager(in_pAllocator));
00138 return m_pInstance;
00139 }
00140
00141 static AkSynthSpaceAllocManager* Instance()
00142 {
00143 return m_pInstance;
00144 }
00145
00146 static void Destroy(AK::IAkPluginMemAlloc * in_pAllocator = NULL)
00147 {
00148 if (m_pInstance)
00149 {
00150 AKASSERT(in_pAllocator);
00151 if (in_pAllocator)
00152 {
00153 AK_PLUGIN_DELETE(in_pAllocator, m_pInstance);
00154 m_pInstance = NULL;
00155 }
00156 }
00157 }
00158
00159 AK::IAkPluginMemAlloc * GetAllocator(void)
00160 {
00161 return m_pAllocator;
00162 };
00163
00164 private:
00165 AkSynthSpaceAllocManager(AK::IAkPluginMemAlloc * in_pAllocator):
00166 m_pAllocator(in_pAllocator)
00167 {};
00168
00169 static AkSynthSpaceAllocManager* m_pInstance;
00170 AK::IAkPluginMemAlloc * m_pAllocator;
00171 };
00172
00173 class AkAcousticPortal
00174 {
00175 public:
00176
00177 struct AkSynthSpaceAllocator
00178 {
00179 static void * Alloc(size_t in_uSize)
00180 {
00181 return AkSynthSpaceAllocManager::Instance()->GetAllocator()->Malloc(in_uSize);
00182 }
00183
00184 static void Free(void * in_pAddress)
00185 {
00186 AkSynthSpaceAllocManager::Instance()->GetAllocator()->Free(in_pAddress);
00187 }
00188 };
00189 typedef AkArray< void*, void*, AkSynthSpaceAllocator, 2 > BufferArray;
00190
00191 typedef AkArray<AkPortalLink, AkPortalLink&, AkSynthSpaceAllocator, 10> AkPortalLinkDatabase;
00192 typedef AkArray<AkBoundingBox, const AkBoundingBox&, AkSynthSpaceAllocator, 10> AkBoundingBoxList;
00193
00194 AkAcousticPortal() :
00195 m_ID(0),
00196 m_State(AkImageSourceBox_Unused)
00197 {
00198 }
00199 ~AkAcousticPortal(){};
00200
00201 void Init(
00202 const Ak3DVector & in_center,
00203 const Ak3DVector & in_size,
00204 const Ak3DVector & in_Front,
00205 const Ak3DVector & in_Up,
00206 const AkAcousticPortalParams & in_LateParams);
00207
00208 void Release();
00209
00210 void AddOrUpdateLink(AkPortalLink& in_link)
00211 {
00212 bool found = false;
00213 for (AkPortalLinkDatabase::Iterator it = m_LinkDB.Begin(); it != m_LinkDB.End() && !found; ++it)
00214 {
00215 AkPortalLink& link = static_cast<AkPortalLink&>(*it);
00216 if (link.m_BoxID == in_link.m_BoxID &&
00217 link.m_FaceID == in_link.m_FaceID)
00218 {
00219 link.m_Opening.Update(in_link.m_Opening.m_Min);
00220 link.m_Opening.Update(in_link.m_Opening.m_Max);
00221 found = true;
00222 }
00223 }
00224
00225 if (!found)
00226 {
00227 m_LinkDB.AddLast(in_link);
00228 }
00229 }
00230
00231 void FindIntersections(AkUInt32 in_ListenerBox, AkUInt32 in_EmmiterBox, AkBoundingBoxList& out_portalList)
00232 {
00233 bool emmiterBoxFound = false;
00234
00235 for (AkPortalLinkDatabase::Iterator it = m_LinkDB.Begin(); it != m_LinkDB.End() && emmiterBoxFound != true; ++it)
00236 {
00237 const AkPortalLink& link = static_cast<AkPortalLink>(*it);
00238 if (link.m_BoxID == (AkInt32)in_EmmiterBox)
00239 {
00240 emmiterBoxFound = true;
00241 }
00242 }
00243
00244 if (emmiterBoxFound)
00245 {
00246 for (AkPortalLinkDatabase::Iterator it = m_LinkDB.Begin(); it != m_LinkDB.End() && emmiterBoxFound != false; ++it)
00247 {
00248 const AkPortalLink& link = static_cast<AkPortalLink>(*it);
00249 if (link.m_BoxID == (AkInt32)in_ListenerBox)
00250 {
00251 out_portalList.AddLast(link.m_Opening);
00252 }
00253 }
00254 }
00255 }
00256
00257 bool IsUsed() const { return m_State == AkImageSourceBox_Used; }
00258 bool IsAvailable() const { return m_State != AkImageSourceBox_Used; }
00259 AkUInt32 GetID() const { return m_ID; }
00260
00261 const AkBox & GetBox() const { return m_Box; }
00262
00263 private:
00264 AkInt32 m_ID;
00265 AkBox m_Box;
00266 AkImageSourceBoxState m_State;
00267 AkAcousticPortalParams m_PortalParams;
00268
00269 AkPortalLinkDatabase m_LinkDB;
00270
00271 };
00272
00273 class AkImageSourceBox
00274 {
00275 public:
00276 AkImageSourceBox() :
00277 m_ID(0),
00278 m_State(AkImageSourceBox_Unused)
00279 {
00280 }
00281 ~AkImageSourceBox(){};
00282
00283 void Init(
00284 const Ak3DVector & in_center,
00285 const Ak3DVector & in_size,
00286 const Ak3DVector & in_Front,
00287 const Ak3DVector & in_Up,
00288 const AkUInt32 in_DiffuseReverberator,
00289 AkInt32 in_wall_mask,
00290 AkUInt32* in_AcousticTextures,
00291 AkInt32 in_startIndex);
00292
00293 void Release();
00294
00295 void ModePosition(
00296 Ak3DVector in_p,
00297 Ak3DVector& out_p1,
00298 AkUInt16 in_i1
00299 ) const;
00300
00301 void ModePosition(
00302 Ak3DVector in_p,
00303 Ak3DVector in_mode,
00304 Ak3DVector& out_p1,
00305 Ak3DVector& out_p2,
00306 AkUInt16 in_i1,
00307 AkUInt16 in_i2) const;
00308
00309 void Reflect(
00310 AkInt32 in_index,
00311 Ak3DVector in_p,
00312 Ak3DVector& out_p) const;
00313
00314 AkUInt32 GetMaterialID(
00315 AkInt32 in_index) const;
00316
00317 bool FindIntersections(AkAcousticPortal* in_portal);
00318
00319 void SetCrossSectionsPerFace(AkAcousticPortal* in_portal);
00320
00321 bool SeparatingAxisExists(
00322 const Ak3DVector& in_Axis,
00323 const AkBox& in_Box);
00324
00325 AkUInt32 GetDiffuseReverberator() const;
00326
00327 bool IsUsed() const { return m_State == AkImageSourceBox_Used; }
00328 bool IsAvailable() const { return m_State != AkImageSourceBox_Used; }
00329 AkUInt32 GetID() const { return m_ID; }
00330
00331 const AkBox GetBox() const { return m_Box; };
00332
00333 private:
00334 AkInt32 m_ID;
00335 AkBox m_Box;
00336 AkImageSourceReflector m_ImageSourceReflector[MIRROR_COUNT];
00337 AkImageSourceBoxState m_State;
00338 AkUInt32 m_DiffuseReverberator;
00339 };
00340
00341 #endif // _AKIMAGESOURCE_H_