ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.cpp
Revision: 2.2
Committed: Wed Jul 26 23:27:44 2023 UTC (21 months, 1 week ago) by greg
Branch: MAIN
Changes since 2.1: +8 -1 lines
Log Message:
feat: Preparing for multi-threading

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: RtraceSimulManager.cpp,v 2.1 2023/02/08 17:41:48 greg Exp $";
3 #endif
4 /*
5 * RtraceSimulManager.cpp
6 *
7 * Rtrace simulation manager class implementation
8 *
9 * Created by Greg Ward on 2/2/2023.
10 */
11
12 #include "RtraceSimulManager.h"
13 #include "source.h"
14
15 extern int castonly; // doing ray-casting only?
16
17 // Load octree and prepare renderer
18 bool
19 RadSimulManager::LoadOctree(const char *octn)
20 {
21 if (octname) { // already running?
22 if (octn && !strcmp(octn, octname))
23 return true;
24 Cleanup();
25 }
26 if (!octn)
27 return false;
28
29 ray_init((char *)octn);
30 return true;
31 }
32
33 // How many processors are there?
34 int
35 RadSimulManager::GetNCores()
36 {
37 return 1; // XXX temporary
38 }
39
40 // Set number of computation threads (0 => #cores)
41 int
42 RadSimulManager::SetThreadCount(int nt)
43 {
44 return nThreads = 1; // XXX temporary
45 }
46
47 // Close octree, free data, return status
48 int
49 RadSimulManager::Cleanup()
50 {
51 ray_done(0);
52 return 0;
53 }
54
55 // How many threads are currently unoccupied?
56 int
57 RadSimulManager::ThreadsAvailable() const
58 {
59 return 1; // XXX temporary
60 }
61
62 // Global pointer to simulation manager for trace call-back (only one)
63 static const RtraceSimulManager * ourRTsimMan = NULL;
64
65 void // static call-back
66 RtraceSimulManager::RTracer(RAY *r)
67 {
68 (*ourRTsimMan->traceCall)(r, ourRTsimMan->tcData);
69 }
70
71 // Check for changes to render flags & adjust accordingly
72 bool
73 RtraceSimulManager::UpdateMode()
74 {
75 rtFlags &= RTmask;
76 if (!cookedCall)
77 rtFlags &= ~RTdoFIFO;
78 if (!traceCall)
79 rtFlags &= ~RTtraceSources;
80 if (rtFlags & RTimmIrrad)
81 rtFlags &= ~RTlimDist;
82
83 int misMatch = rtFlags ^ curFlags;
84 // updates based on toggled flags
85 if (misMatch & RTtraceSources) {
86 if (rtFlags & RTtraceSources) {
87 for (int sn = 0; sn < nsources; sn++)
88 source[sn].sflags |= SFOLLOW;
89 } else // cannot undo this...
90 rtFlags |= RTtraceSources;
91 }
92 if (misMatch & RTdoFIFO) {
93 if (!FlushQueue())
94 return false;
95 }
96 curFlags = rtFlags;
97 // update trace callback
98 if (traceCall) {
99 if (ourRTsimMan && ourRTsimMan != this)
100 error(WARNING, "Competing top-level simulation managers?");
101 ourRTsimMan = this;
102 trace = RTracer;
103 } else if (ourRTsimMan == this) {
104 trace = NULL;
105 ourRTsimMan = NULL;
106 }
107 return true;
108 }
109
110 extern "C" int m_normal(OBJREC *m, RAY *r);
111
112 /* compute irradiance rather than radiance */
113 static void
114 rayirrad(RAY *r)
115 {
116 /* pretend we hit surface */
117 r->rxt = r->rot = 1e-5;
118 VSUM(r->rop, r->rorg, r->rdir, r->rot);
119 r->ron[0] = -r->rdir[0];
120 r->ron[1] = -r->rdir[1];
121 r->ron[2] = -r->rdir[2];
122 r->rod = 1.0;
123 /* compute result */
124 r->revf = raytrace;
125 m_normal(&Lamb, r);
126 r->revf = rayirrad;
127 }
128
129 /* compute first ray intersection only */
130 static void
131 raycast(RAY *r)
132 {
133 if (!localhit(r, &thescene)) {
134 if (r->ro == &Aftplane) { /* clipped */
135 r->ro = NULL;
136 r->rot = FHUGE;
137 } else
138 sourcehit(r);
139 }
140 }
141
142 // Add ray bundle to queue w/ optional 1st ray ID
143 int
144 RtraceSimulManager::EnqueueBundle(const FVECT orig_direc[], int n, RNUMBER rID0)
145 {
146 int nqueued = 0;
147 RAY res;
148
149 if (!Ready())
150 return -1;
151
152 if (castonly && !cookedCall)
153 error(CONSISTENCY, "EnqueueBundle() called in castonly mode without cookedCall");
154
155 if (!UpdateMode()) // update rendering mode if requested
156 return -1;
157
158 while (n-- > 0) { // queue each ray
159 double d;
160 VCOPY(res.rorg, orig_direc[0]);
161 VCOPY(res.rdir, orig_direc[1]);
162 orig_direc += 2;
163 rayorigin(&res, PRIMARY, NULL, NULL);
164 if (rID0) res.rno = rID0++;
165 else res.rno = ++lastRayID;
166 if (curFlags & RTimmIrrad)
167 res.revf = rayirrad;
168 else if (castonly)
169 res.revf = raycast;
170 d = normalize(res.rdir);
171 if (d > 0) { // direction vector is valid?
172 if (curFlags & RTlimDist)
173 res.rmax = d;
174 samplendx++;
175 rayvalue(&res); // XXX single-threaded for now
176 ++nqueued;
177 } else if (ThreadsAvailable() < NThreads() &&
178 !FlushQueue())
179 return -1;
180 if (cookedCall)
181 (*cookedCall)(&res, ccData);
182 }
183 return nqueued;
184 }
185
186 // Finish pending rays and complete callbacks
187 bool
188 RtraceSimulManager::FlushQueue()
189 {
190 return true; // XXX no-op for now
191 }