scene_quad_mesh.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "scene_quad_mesh.h"
  17. #include "scene.h"
  18. namespace embree
  19. {
  20. QuadMesh::QuadMesh (Scene* parent, RTCGeometryFlags flags, size_t numQuads, size_t numVertices, size_t numTimeSteps)
  21. : Geometry(parent,QUAD_MESH,numQuads,numTimeSteps,flags)
  22. {
  23. quads.init(parent->device,numQuads,sizeof(Quad));
  24. vertices.resize(numTimeSteps);
  25. for (size_t i=0; i<numTimeSteps; i++) {
  26. vertices[i].init(parent->device,numVertices,sizeof(Vec3fa));
  27. }
  28. enabling();
  29. }
  30. void QuadMesh::enabling()
  31. {
  32. if (numTimeSteps == 1) parent->world.numQuads += quads.size();
  33. else parent->worldMB.numQuads += quads.size();
  34. }
  35. void QuadMesh::disabling()
  36. {
  37. if (numTimeSteps == 1) parent->world.numQuads -= quads.size();
  38. else parent->worldMB.numQuads -= quads.size();
  39. }
  40. void QuadMesh::setMask (unsigned mask)
  41. {
  42. if (parent->isStatic() && parent->isBuild())
  43. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  44. this->mask = mask;
  45. Geometry::update();
  46. }
  47. void QuadMesh::setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride, size_t size)
  48. {
  49. if (parent->isStatic() && parent->isBuild())
  50. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  51. /* verify that all accesses are 4 bytes aligned */
  52. if (((size_t(ptr) + offset) & 0x3) || (stride & 0x3))
  53. throw_RTCError(RTC_INVALID_OPERATION,"data must be 4 bytes aligned");
  54. unsigned bid = type & 0xFFFF;
  55. if (type >= RTC_VERTEX_BUFFER0 && type < RTCBufferType(RTC_VERTEX_BUFFER0 + numTimeSteps))
  56. {
  57. size_t t = type - RTC_VERTEX_BUFFER0;
  58. vertices[t].set(ptr,offset,stride,size);
  59. vertices[t].checkPadding16();
  60. vertices0 = vertices[0];
  61. }
  62. else if (type >= RTC_USER_VERTEX_BUFFER0 && type < RTC_USER_VERTEX_BUFFER0+RTC_MAX_USER_VERTEX_BUFFERS)
  63. {
  64. if (bid >= userbuffers.size()) userbuffers.resize(bid+1);
  65. userbuffers[bid] = APIBuffer<char>(parent->device,numVertices(),stride);
  66. userbuffers[bid].set(ptr,offset,stride,size);
  67. userbuffers[bid].checkPadding16();
  68. }
  69. else if (type == RTC_INDEX_BUFFER)
  70. {
  71. if (size != (size_t)-1) disabling();
  72. quads.set(ptr,offset,stride,size);
  73. setNumPrimitives(size);
  74. if (size != (size_t)-1) enabling();
  75. }
  76. else
  77. throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
  78. }
  79. void* QuadMesh::map(RTCBufferType type)
  80. {
  81. if (parent->isStatic() && parent->isBuild())
  82. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  83. if (type == RTC_INDEX_BUFFER) {
  84. return quads.map(parent->numMappedBuffers);
  85. }
  86. else if (type >= RTC_VERTEX_BUFFER0 && type < RTCBufferType(RTC_VERTEX_BUFFER0 + numTimeSteps)) {
  87. return vertices[type - RTC_VERTEX_BUFFER0].map(parent->numMappedBuffers);
  88. }
  89. else {
  90. throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
  91. return nullptr;
  92. }
  93. }
  94. void QuadMesh::unmap(RTCBufferType type)
  95. {
  96. if (parent->isStatic() && parent->isBuild())
  97. throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");
  98. if (type == RTC_INDEX_BUFFER) {
  99. quads.unmap(parent->numMappedBuffers);
  100. }
  101. else if (type >= RTC_VERTEX_BUFFER0 && type < RTCBufferType(RTC_VERTEX_BUFFER0 + numTimeSteps)) {
  102. vertices[type - RTC_VERTEX_BUFFER0].unmap(parent->numMappedBuffers);
  103. vertices0 = vertices[0];
  104. }
  105. else {
  106. throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
  107. }
  108. }
  109. void QuadMesh::immutable ()
  110. {
  111. const bool freeQuads = !parent->needQuadIndices;
  112. const bool freeVertices = !parent->needQuadVertices;
  113. if (freeQuads) quads.free();
  114. if (freeVertices )
  115. for (auto& buffer : vertices)
  116. buffer.free();
  117. }
  118. bool QuadMesh::verify ()
  119. {
  120. /*! verify consistent size of vertex arrays */
  121. if (vertices.size() == 0) return false;
  122. for (const auto& buffer : vertices)
  123. if (buffer.size() != numVertices())
  124. return false;
  125. /*! verify quad indices */
  126. for (size_t i=0; i<quads.size(); i++) {
  127. if (quads[i].v[0] >= numVertices()) return false;
  128. if (quads[i].v[1] >= numVertices()) return false;
  129. if (quads[i].v[2] >= numVertices()) return false;
  130. if (quads[i].v[3] >= numVertices()) return false;
  131. }
  132. /*! verify vertices */
  133. for (const auto& buffer : vertices)
  134. for (size_t i=0; i<buffer.size(); i++)
  135. if (!isvalid(buffer[i]))
  136. return false;
  137. return true;
  138. }
  139. void QuadMesh::interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats)
  140. {
  141. /* test if interpolation is enabled */
  142. #if defined(DEBUG)
  143. if ((parent->aflags & RTC_INTERPOLATE) == 0)
  144. throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene");
  145. #endif
  146. /* calculate base pointer and stride */
  147. assert((buffer >= RTC_VERTEX_BUFFER0 && buffer < RTCBufferType(RTC_VERTEX_BUFFER0 + numTimeSteps)) ||
  148. (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1));
  149. const char* src = nullptr;
  150. size_t stride = 0;
  151. if (buffer >= RTC_USER_VERTEX_BUFFER0) {
  152. src = userbuffers[buffer&0xFFFF].getPtr();
  153. stride = userbuffers[buffer&0xFFFF].getStride();
  154. } else {
  155. src = vertices[buffer&0xFFFF].getPtr();
  156. stride = vertices[buffer&0xFFFF].getStride();
  157. }
  158. for (size_t i=0; i<numFloats; i+=VSIZEX)
  159. {
  160. const vboolx valid = vintx((int)i)+vintx(step) < vintx(numFloats);
  161. const size_t ofs = i*sizeof(float);
  162. const Quad& tri = quad(primID);
  163. const vfloatx p0 = vfloatx::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]);
  164. const vfloatx p1 = vfloatx::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]);
  165. const vfloatx p2 = vfloatx::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]);
  166. const vfloatx p3 = vfloatx::loadu(valid,(float*)&src[tri.v[3]*stride+ofs]);
  167. const vboolx left = u+v <= 1.0f;
  168. const vfloatx Q0 = select(left,p0,p2);
  169. const vfloatx Q1 = select(left,p1,p3);
  170. const vfloatx Q2 = select(left,p3,p1);
  171. const vfloatx U = select(left,u,vfloatx(1.0f)-u);
  172. const vfloatx V = select(left,v,vfloatx(1.0f)-v);
  173. const vfloatx W = 1.0f-U-V;
  174. if (P) {
  175. vfloatx::storeu(valid,P+i,madd(W,Q0,madd(U,Q1,V*Q2)));
  176. }
  177. if (dPdu) {
  178. assert(dPdu); vfloatx::storeu(valid,dPdu+i,select(left,Q1-Q0,Q0-Q1));
  179. assert(dPdv); vfloatx::storeu(valid,dPdv+i,select(left,Q2-Q0,Q0-Q2));
  180. }
  181. if (ddPdudu) {
  182. assert(ddPdudu); vfloatx::storeu(valid,ddPdudu+i,vfloatx(zero));
  183. assert(ddPdvdv); vfloatx::storeu(valid,ddPdvdv+i,vfloatx(zero));
  184. assert(ddPdudv); vfloatx::storeu(valid,ddPdudv+i,vfloatx(zero));
  185. }
  186. }
  187. }
  188. }