21 |
|
if (octname) { // already running? |
22 |
|
if (octn && !strcmp(octn, octname)) |
23 |
|
return true; |
24 |
< |
Cleanup(); |
24 |
> |
Cleanup(false); |
25 |
|
} |
26 |
|
if (!octn) |
27 |
|
return false; |
44 |
|
return nThreads = 1; // XXX temporary |
45 |
|
} |
46 |
|
|
47 |
+ |
// Assign ray to subthread (fails if NThreads()<2) |
48 |
+ |
bool |
49 |
+ |
RadSimulManager::SplitRay(RAY *r) |
50 |
+ |
{ |
51 |
+ |
if (NThreads() < 2 || ThreadsAvailable() < 1) |
52 |
+ |
return false; |
53 |
+ |
|
54 |
+ |
return false; // UNIMPLEMENTED |
55 |
+ |
} |
56 |
+ |
|
57 |
+ |
// Process a ray (in subthread), optional result |
58 |
+ |
bool |
59 |
+ |
RadSimulManager::ProcessRay(RAY *r) |
60 |
+ |
{ |
61 |
+ |
if (!r || !Ready()) return false; |
62 |
+ |
if (NThreads() < 2) { // single-threaded mode? |
63 |
+ |
samplendx++; |
64 |
+ |
rayvalue(r); |
65 |
+ |
return true; |
66 |
+ |
} |
67 |
+ |
if (ThreadsAvailable() >= 1) { |
68 |
+ |
SplitRay(r); // queue not yet full |
69 |
+ |
return false; |
70 |
+ |
} |
71 |
+ |
RAY toDo = *r; |
72 |
+ |
if (!WaitResult(r)) // need a free thread |
73 |
+ |
return false; |
74 |
+ |
SplitRay(&toDo); // queue up new ray |
75 |
+ |
return true; // return older result |
76 |
+ |
} |
77 |
+ |
|
78 |
+ |
// Wait for next result (or fail) |
79 |
+ |
bool |
80 |
+ |
RadSimulManager::WaitResult(RAY *r) |
81 |
+ |
{ |
82 |
+ |
return false; // UNIMPLEMENTED |
83 |
+ |
} |
84 |
+ |
|
85 |
|
// Close octree, free data, return status |
86 |
|
int |
87 |
< |
RadSimulManager::Cleanup() |
87 |
> |
RadSimulManager::Cleanup(bool everything) |
88 |
|
{ |
89 |
< |
ray_done(0); |
89 |
> |
ray_done(everything); |
90 |
|
return 0; |
91 |
|
} |
92 |
|
|
127 |
|
} else // cannot undo this... |
128 |
|
rtFlags |= RTtraceSources; |
129 |
|
} |
130 |
< |
if (misMatch & RTdoFIFO) { |
131 |
< |
if (!FlushQueue()) |
94 |
< |
return false; |
95 |
< |
} |
130 |
> |
if (misMatch & RTdoFIFO && FlushQueue() < 0) |
131 |
> |
return false; |
132 |
|
curFlags = rtFlags; |
133 |
|
// update trace callback |
134 |
|
if (traceCall) { |
175 |
|
} |
176 |
|
} |
177 |
|
|
178 |
+ |
// Add a ray result to FIFO, flushing what we can |
179 |
+ |
int |
180 |
+ |
RtraceSimulManager::QueueResult(const RAY &ra) |
181 |
+ |
{ |
182 |
+ |
return 0; // UNIMPLEMENTED |
183 |
+ |
} |
184 |
+ |
|
185 |
|
// Add ray bundle to queue w/ optional 1st ray ID |
186 |
|
int |
187 |
|
RtraceSimulManager::EnqueueBundle(const FVECT orig_direc[], int n, RNUMBER rID0) |
199 |
|
return -1; |
200 |
|
|
201 |
|
while (n-- > 0) { // queue each ray |
159 |
– |
double d; |
202 |
|
VCOPY(res.rorg, orig_direc[0]); |
203 |
|
VCOPY(res.rdir, orig_direc[1]); |
204 |
|
orig_direc += 2; |
209 |
|
res.revf = rayirrad; |
210 |
|
else if (castonly) |
211 |
|
res.revf = raycast; |
212 |
< |
d = normalize(res.rdir); |
212 |
> |
double d = normalize(res.rdir); |
213 |
> |
bool sendRes = (cookedCall != NULL); |
214 |
|
if (d > 0) { // direction vector is valid? |
215 |
|
if (curFlags & RTlimDist) |
216 |
|
res.rmax = d; |
217 |
< |
samplendx++; |
218 |
< |
rayvalue(&res); // XXX single-threaded for now |
219 |
< |
++nqueued; |
217 |
> |
if ((sendRes &= ProcessRay(&res)) && |
218 |
> |
rtFlags & RTdoFIFO && NThreads() > 1) { |
219 |
> |
if (QueueResult(res) < 0) |
220 |
> |
return -1; |
221 |
> |
sendRes = false; |
222 |
> |
} |
223 |
|
} else if (ThreadsAvailable() < NThreads() && |
224 |
< |
!FlushQueue()) |
224 |
> |
FlushQueue() < 0) |
225 |
|
return -1; |
226 |
< |
if (cookedCall) |
226 |
> |
if (sendRes) // may be dummy ray |
227 |
|
(*cookedCall)(&res, ccData); |
228 |
+ |
nqueued++; |
229 |
|
} |
230 |
|
return nqueued; |
231 |
|
} |
232 |
|
|
233 |
|
// Finish pending rays and complete callbacks |
234 |
< |
bool |
234 |
> |
int |
235 |
|
RtraceSimulManager::FlushQueue() |
236 |
|
{ |
237 |
< |
return true; // XXX no-op for now |
237 |
> |
int nsent = 0; |
238 |
> |
RAY res; |
239 |
> |
|
240 |
> |
while (WaitResult(&res)) { |
241 |
> |
if (!cookedCall) continue; |
242 |
> |
if (rtFlags & RTdoFIFO) { |
243 |
> |
int ns = QueueResult(res); |
244 |
> |
if (ns < 0) return ns; |
245 |
> |
nsent += ns; |
246 |
> |
} else { |
247 |
> |
(*cookedCall)(&res, ccData); |
248 |
> |
nsent++; |
249 |
> |
} |
250 |
> |
} |
251 |
> |
return nsent; |
252 |
|
} |