ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/rt/RtraceSimulManager.h
Revision: 2.16
Committed: Wed Oct 23 23:40:41 2024 UTC (12 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.15: +5 -1 lines
Log Message:
feat: Added GetHeadLen() method for efficiency

File Contents

# Content
1 /* RCSid $Id: RtraceSimulManager.h,v 2.15 2024/10/10 21:02:52 greg Exp $ */
2 /*
3 * RtraceSimulManager.h
4 *
5 * Rtrace simulation manager class declaration (along with base class)
6 * Enqueuing rays will block caller iff #rays >= ThreadsAvail()
7 * Reporting call-backs made from EnqueBundle() and FlushQueue()
8 *
9 * Created by Greg Ward on 11/10/22.
10 */
11
12 #ifndef RtraceSimulManager_h
13 #define RtraceSimulManager_h
14
15 #include "ray.h"
16 #include "abitmap.h"
17
18 extern char * octname; // global octree name
19
20 extern int castonly; // doing ray-casting only?
21
22 /// Ray reporting callback method -- returns # successfully reported, -1 to abort
23 typedef int RayReportCall(RAY *r, void *cd);
24
25 /// Multi-threaded simulation manager base class
26 class RadSimulManager {
27 char * header; // header (less intro and format)
28 int hlen; // header string length
29 protected:
30 // Assign ray to subthread (fails if NThreads()<2)
31 bool SplitRay(RAY *r);
32 public:
33 RadSimulManager(const char *octn = NULL) {
34 header = NULL; hlen = 0;
35 LoadOctree(octn);
36 }
37 ~RadSimulManager() {
38 Cleanup();
39 }
40 /// Load octree and prepare renderer
41 bool LoadOctree(const char *octn);
42 /// Prepare header from previous input (or clear)
43 /// Normally called during octree load
44 bool NewHeader(const char *inspec = NULL);
45 /// Add a line to header (adds newline if none)
46 bool AddHeader(const char *str);
47 /// Append program line to header
48 bool AddHeader(int ac, char *av[]);
49 /// Get current header length in bytes
50 int GetHeadLen() const {
51 return hlen;
52 }
53 /// Get header lines or empty string
54 const char * GetHeadStr() const {
55 return hlen ? header : "";
56 }
57 /// Look for specific header keyword, return value
58 const char * GetHeadStr(const char *key, bool inOK = false) const;
59 /// How many cores are available?
60 static int GetNCores();
61 /// Set number of computation threads (0 => #cores)
62 int SetThreadCount(int nt = 0);
63 /// Check thread count (1 means no multi-threading)
64 int NThreads() const {
65 return ray_pnprocs + !ray_pnprocs;
66 }
67 /// How many threads are currently unoccupied?
68 int ThreadsAvailable() const;
69 /// Are we ready?
70 bool Ready() const {
71 return (octname && nobjects > 0);
72 }
73 /// Process a ray (in subthread), optional result
74 bool ProcessRay(RAY *r);
75 /// Wait for next result (or fail)
76 bool WaitResult(RAY *r);
77 /// Close octree, free data, return status
78 int Cleanup(bool everything = false);
79 };
80
81 /// Flags to control rendering operations
82 enum {RTdoFIFO=1, RTtraceSources=2, RTlimDist=4, RTimmIrrad=8, RTmask=15};
83
84 /// rtrace-like simulation manager (at most one such object)
85 class RtraceSimulManager : public RadSimulManager {
86 RayReportCall * cookedCall; // callback for cooked primary rays
87 void * ccData; // client data for cooked primary rays
88 RayReportCall * traceCall; // call for every ray in tree
89 void * tcData; // client data for traced rays
90 int curFlags; // current operating flags
91 ABitMap srcFollowed; // source flags changed
92 // Call-back for global ray-tracing context
93 static void RTracer(RAY *r);
94 // Call-back for FIFO
95 static int Rfifout(RAY *r);
96 // Check for changes to render flags, etc.
97 bool UpdateMode();
98 protected:
99 RNUMBER lastRayID; // last ray ID assigned
100 public:
101 int rtFlags; // operation (RT*) flags
102 RtraceSimulManager(RayReportCall *cb = NULL, void *cd = NULL,
103 const char *octn = NULL) : RadSimulManager(octn) {
104 lastRayID = 0;
105 rtFlags = curFlags = 0;
106 SetCookedCall(cb, cd);
107 traceCall = NULL; tcData = NULL;
108 }
109 ~RtraceSimulManager() {
110 FlushQueue();
111 }
112 /// Set number of computation threads (0 => #cores)
113 int SetThreadCount(int nt = 0) {
114 if (nt <= 0) nt = castonly ? 1 : GetNCores();
115 if (nt == NThreads()) return nt;
116 if (nt < NThreads() && FlushQueue() < 0) return 0;
117 return RadSimulManager::SetThreadCount(nt);
118 }
119 /// Add ray bundle to queue w/ optional 1st ray ID
120 int EnqueueBundle(const FVECT orig_direc[], int n,
121 RNUMBER rID0 = 0);
122 /// Enqueue a single ray w/ optional ray ID
123 bool EnqueueRay(const FVECT org, const FVECT dir,
124 RNUMBER rID = 0) {
125 if (dir == org+1)
126 return(EnqueueBundle((const FVECT *)org, 1, rID) > 0);
127 FVECT orgdir[2];
128 VCOPY(orgdir[0], org); VCOPY(orgdir[1], dir);
129 return(EnqueueBundle(orgdir, 1, rID) > 0);
130 }
131 /// Set/change cooked ray callback
132 void SetCookedCall(RayReportCall *cb, void *cd = NULL) {
133 if (cookedCall && (cookedCall != cb) | (ccData != cd))
134 FlushQueue();
135 cookedCall = cb;
136 ccData = cb ? cd : NULL;
137 }
138 /// Set/change trace callback (before threading)
139 void SetTraceCall(RayReportCall *cb, void *cd = NULL) {
140 traceCall = cb;
141 tcData = cb ? cd : NULL;
142 }
143 /// Are we ready?
144 bool Ready() const {
145 return (cookedCall != NULL) | (traceCall != NULL) &&
146 RadSimulManager::Ready();
147 }
148 /// Finish pending rays and complete callbacks (return #sent)
149 int FlushQueue();
150 /// Close octree, free data, return status
151 int Cleanup(bool everything = false) {
152 SetCookedCall(NULL);
153 SetTraceCall(NULL);
154 rtFlags = 0;
155 UpdateMode();
156 lastRayID = 0;
157 return RadSimulManager::Cleanup(everything);
158 }
159 };
160
161 /// Determine if vector is all zeroes
162 inline bool
163 IsZeroVec(const FVECT vec)
164 {
165 return (vec[0] == 0.0) & (vec[1] == 0.0) & (vec[2] == 0.0);
166 }
167
168 #endif /* RtraceSimulManager_h */