Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TMetaInjectionPrimitive.h
Go to the documentation of this file.
1#pragma once
2
5#include "Core/HitProbe.h"
6#include "Utility/traits.h"
7
8#include <Common/assertion.h>
9
10#include <concepts>
11#include <utility>
12
13namespace ph
14{
15
16namespace detail
17{
18
19template<typename GetterType>
20concept CPrimitiveMetaGetter = requires (const GetterType getter)
21{
22 { getter() } -> std::same_as<const PrimitiveMetadata*>;
23};
24
25template<typename GetterType>
26concept CPrimitiveGetter = requires (const GetterType getter)
27{
28 { getter() } -> std::convertible_to<const Primitive*>;
29};
30
31}// end namespace detail
32
34{
36
40
42 {
43 return metadata;
44 }
45};
46
48{
50
51 template<typename... DeducedArgs>
52 explicit EmbeddedPrimitiveMetaGetter(DeducedArgs&&... args)
53 : metadata(std::forward<DeducedArgs>(args)...)
54 {}
55
57 {
58 return &metadata;
59 }
60};
61
62template<CDerived<Primitive> PrimitiveType>
64{
65 const PrimitiveType* primitive;
66
67 explicit TReferencedPrimitiveGetter(const PrimitiveType* const primitive)
69 {}
70
71 const PrimitiveType* operator () () const
72 {
73 return primitive;
74 }
75};
76
77template<CDerived<Primitive> PrimitiveType>
79{
80 PrimitiveType primitive;
81
82 template<typename... DeducedArgs>
83 explicit TEmbeddedPrimitiveGetter(DeducedArgs&&... args)
84 : primitive(std::forward<DeducedArgs>(args)...)
85 {}
86
87 const PrimitiveType* operator () () const
88 {
89 return &primitive;
90 }
91};
92
93// TODO: could use EBO on some cases
94
95template<detail::CPrimitiveMetaGetter PrimitiveMetaGetter, detail::CPrimitiveGetter PrimitiveGetter>
97{
98public:
99 TMetaInjectionPrimitive(PrimitiveMetaGetter metaGetter, PrimitiveGetter primitiveGetter)
100 : Primitive()
101 , m_metaGetter(std::move(metaGetter))
102 , m_primitiveGetter(std::move(primitiveGetter))
103 {}
104
105 bool isIntersecting(const Ray& ray, HitProbe& probe) const override
106 {
107 if(m_primitiveGetter()->isIntersecting(ray, probe))
108 {
109 // Hit detail will be modified by this primitive
110 probe.pushIntermediateHit(this);
111
112 return true;
113 }
114 else
115 {
116 return false;
117 }
118 }
119
121 const Ray& ray,
122 HitProbe& probe,
123 const Ray& srcRay,
124 HitProbe& srcProbe) const override
125 {
126 PH_ASSERT(srcProbe.getTopHit() == this);
127 srcProbe.popHit();
128
129 if(srcProbe.getTopHit()->reintersect(ray, probe, srcRay, srcProbe))
130 {
131 probe.pushIntermediateHit(this);
132 return true;
133 }
134 else
135 {
136 return false;
137 }
138 }
139
141 const Ray& ray,
142 HitProbe& probe,
143 HitDetail* const out_detail) const override
144 {
145 // If failed, it is likely to be caused by: 1. mismatched/missing probe push or pop in
146 // the hit stack; 2. the hit event is invalid
147 PH_ASSERT(probe.getTopHit() == this);
148 probe.popHit();
149
150 // Current hit is not necessary the injectee (as obtained via `getInjectee()`). For example,
151 // if the injectee contains multiple instances then it could simply skip over to one of them.
152 probe.getTopHit()->calcHitDetail(ray, probe, out_detail);
153
154 // This is a representative of the original primitive
155 out_detail->setHitIntrinsics(
156 this,
157 out_detail->getUVW(),
158 out_detail->getRayT(),
159 out_detail->getFaceID(),
160 out_detail->getFaceTopology());
161 }
162
163 math::AABB3D calcAABB() const override
164 {
165 return m_primitiveGetter()->calcAABB();
166 }
167
168 bool isOccluding(const Ray& ray) const override
169 {
170 return m_primitiveGetter()->isOccluding(ray);
171 }
172
173 bool mayOverlapVolume(const math::AABB3D& volume) const override
174 {
175 return m_primitiveGetter()->mayOverlapVolume(volume);
176 }
177
180 SampleFlow& sampleFlow,
181 HitProbe& probe) const override
182 {
183 m_primitiveGetter()->genPosSample(query, sampleFlow, probe);
184
185 // Hit detail will be modified by this primitive
186 probe.pushIntermediateHit(this);
187 }
188
189 void calcPosPdf(PrimitivePosPdfQuery& query) const override
190 {
191 m_primitiveGetter()->calcPosPdf(query);
192 }
193
194 real calcExtendedArea() const override
195 {
196 return m_primitiveGetter()->calcExtendedArea();
197 }
198
199 const PrimitiveMetadata* getMetadata() const override
200 {
201 // Metadata from `m_primitiveGetter()->getMetadata()` (if any) is intentionally overridden
202 // by the injected one
203 return m_metaGetter();
204 }
205
209 const auto* getInjectee() const
210 {
211 return m_primitiveGetter();
212 }
213
214private:
215 PrimitiveMetaGetter m_metaGetter;
216 PrimitiveGetter m_primitiveGetter;
217};
218
219}// end namespace ph
Detailed information regarding a ray-primitive intersection.
Definition HitDetail.h:26
uint64 getFaceID() const
Get the face ID associated to the hit.
Definition HitDetail.h:153
math::Vector3R getUVW() const
Definition HitDetail.h:168
real getRayT() const
Get the parametric distance from the incident ray's origin. Notice that parametric distance is not or...
Definition HitDetail.h:148
FaceTopology getFaceTopology() const
Definition HitDetail.h:158
HitDetail & setHitIntrinsics(const Primitive *primitive, const math::Vector3R &uvw, real rayT, uint64 faceID=NO_FACE_ID, FaceTopology faceTopology=FaceTopology(EFaceTopology::General))
Set essential attributes that are independent to the coordinate system.
Definition HitDetail.cpp:23
Lightweight ray intersection testing and reporting object. If an intersection is found,...
Definition HitProbe.h:27
const Intersectable * getTopHit() const
Definition HitProbe.h:154
void popHit()
Removes the most recent hit target from the stack.
Definition HitProbe.h:127
void pushIntermediateHit(const Intersectable *hitTarget)
Adds a hit target that will participate in hit detail's calculation to the stack.
Definition HitProbe.h:112
virtual bool reintersect(const Ray &ray, HitProbe &probe, const Ray &srcRay, HitProbe &srcProbe) const =0
Intersect the intersected object again with a different ray.
virtual void calcHitDetail(const Ray &ray, HitProbe &probe, HitDetail *out_detail) const =0
Calculates properties of a hit, such as coordinates and normal.
A physical shape in the scene.
Definition Primitive.h:23
Collection of attached components to a primitive. This type effectively "glues" various components th...
Definition PrimitiveMetadata.h:22
Information for the probability of generating a specific sample point on a primitive.
Definition PrimitivePosPdfQuery.h:91
Information for generating a sample point on a primitive.
Definition PrimitivePosSampleQuery.h:132
Represents a ray in space.
Definition Ray.h:21
A sample with arbitrary dimensions with fine-grained sampling control.
Definition SampleFlow.h:19
Definition TMetaInjectionPrimitive.h:97
void calcHitDetail(const Ray &ray, HitProbe &probe, HitDetail *const out_detail) const override
Calculates properties of a hit, such as coordinates and normal.
Definition TMetaInjectionPrimitive.h:140
void calcPosPdf(PrimitivePosPdfQuery &query) const override
Given a point on the surface of this primitive, calculates the PDF of sampling this point.
Definition TMetaInjectionPrimitive.h:189
bool mayOverlapVolume(const math::AABB3D &volume) const override
Conservatively checks whether this object overlaps a volume.
Definition TMetaInjectionPrimitive.h:173
bool isOccluding(const Ray &ray) const override
Determines whether this object blocks the ray.
Definition TMetaInjectionPrimitive.h:168
const PrimitiveMetadata * getMetadata() const override
Definition TMetaInjectionPrimitive.h:199
bool reintersect(const Ray &ray, HitProbe &probe, const Ray &srcRay, HitProbe &srcProbe) const override
Intersect the intersected object again with a different ray.
Definition TMetaInjectionPrimitive.h:120
const auto * getInjectee() const
Gets the primitive that has got metadata injected.
Definition TMetaInjectionPrimitive.h:209
void genPosSample(PrimitivePosSampleQuery &query, SampleFlow &sampleFlow, HitProbe &probe) const override
Generates a sample point on the surface of this primitive.
Definition TMetaInjectionPrimitive.h:178
real calcExtendedArea() const override
Calculates the area extended by this primitive. The term "extended" implies single-sided,...
Definition TMetaInjectionPrimitive.h:194
math::AABB3D calcAABB() const override
Calculates Axis-Aligned Bounding Box (AABB) of itself.
Definition TMetaInjectionPrimitive.h:163
TMetaInjectionPrimitive(PrimitiveMetaGetter metaGetter, PrimitiveGetter primitiveGetter)
Definition TMetaInjectionPrimitive.h:99
bool isIntersecting(const Ray &ray, HitProbe &probe) const override
Determine whether a given ray hits the object.
Definition TMetaInjectionPrimitive.h:105
Definition TMetaInjectionPrimitive.h:26
Definition TMetaInjectionPrimitive.h:20
The root for all renderer implementations.
Definition EEngineProject.h:6
Definition TAABB2D.h:96
Definition TMetaInjectionPrimitive.h:48
PrimitiveMetadata metadata
Definition TMetaInjectionPrimitive.h:49
const PrimitiveMetadata * operator()() const
Definition TMetaInjectionPrimitive.h:56
EmbeddedPrimitiveMetaGetter(DeducedArgs &&... args)
Definition TMetaInjectionPrimitive.h:52
Definition TMetaInjectionPrimitive.h:34
const PrimitiveMetadata * operator()() const
Definition TMetaInjectionPrimitive.h:41
ReferencedPrimitiveMetaGetter(const PrimitiveMetadata *const metadata)
Definition TMetaInjectionPrimitive.h:37
const PrimitiveMetadata * metadata
Definition TMetaInjectionPrimitive.h:35
Definition TMetaInjectionPrimitive.h:79
const PrimitiveType * operator()() const
Definition TMetaInjectionPrimitive.h:87
TEmbeddedPrimitiveGetter(DeducedArgs &&... args)
Definition TMetaInjectionPrimitive.h:83
PrimitiveType primitive
Definition TMetaInjectionPrimitive.h:80
Definition TMetaInjectionPrimitive.h:64
TReferencedPrimitiveGetter(const PrimitiveType *const primitive)
Definition TMetaInjectionPrimitive.h:67
const PrimitiveType * operator()() const
Definition TMetaInjectionPrimitive.h:71
const PrimitiveType * primitive
Definition TMetaInjectionPrimitive.h:65