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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: RtraceSimulManager.cpp,v 2.1 2023/02/08 17:41:48 greg Exp $";
3 greg 2.1 #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 greg 2.2 // How many processors are there?
34     int
35     RadSimulManager::GetNCores()
36     {
37     return 1; // XXX temporary
38     }
39    
40 greg 2.1 // 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     }