Project
Loading...
Searching...
No Matches
Magnet.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12/********************************************************************************
13 * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
14 * *
15 * This software is distributed under the terms of the *
16 * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
17 * copied verbatim in the file "LICENSE" *
18 ********************************************************************************/
19
20// -------------------------------------------------------------------------
21// ----- main responsible: Sandro Wenzel (sandro.wenzel@cern.ch) -----
22// -------------------------------------------------------------------------
23
26#include <DetectorsPassive/Magnet.h>
27#include <TGeoCompositeShape.h>
28#include <TGeoManager.h>
29#include <TGeoMatrix.h>
30#include <TGeoMedium.h>
31#include <TGeoPgon.h>
32#include <TGeoVolume.h>
33#include <TGeoXtru.h>
34#ifdef NDEBUG
35#undef NDEBUG
36#endif
37#include <cassert>
38
39using namespace o2::passive;
40
41Magnet::~Magnet() = default;
42
43Magnet::Magnet() : PassiveBase("MAG", "") {}
44Magnet::Magnet(const char* name, const char* Title) : PassiveBase(name, Title) {}
45Magnet::Magnet(const Magnet& rhs) = default;
46
47Magnet& Magnet::operator=(const Magnet& rhs)
48{
49 // self assignment
50 if (this == &rhs) {
51 return *this;
52 }
53
54 // base class assignment
55 PassiveBase::operator=(rhs);
56
57 return *this;
58}
59
61{
63 //
64 // Create materials for L3 magnet
65 //
66 Int_t isxfld = 2.;
67 Float_t sxmgmx = 10.;
69
70 // The coils, the yoke and the crown sit outside the region the field map
71 // covers, so they are tracked without a field. The doors and the plugs are
72 // the exception: they reach the beam axis inside the solenoid and keep it.
73 Int_t isxfldNoField = 0;
74 Float_t epsil, stmin, deemax, tmaxfd, stemax;
75
76 // --- Define the various materials for GEANT ---
77 // Steel
78 Float_t asteel[4] = {55.847, 51.9961, 58.6934, 28.0855};
79 Float_t zsteel[4] = {26., 24., 28., 14.};
80 Float_t wsteel[4] = {.715, .18, .1, .005};
81 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
82 Float_t zAir[4] = {6., 7., 8., 18.};
83 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
84 Float_t dAir = 1.20479E-3;
85 Float_t aWater[2] = {1.00794, 15.9994};
86 Float_t zWater[2] = {1., 8.};
87 Float_t wWater[2] = {0.111894, 0.888106};
88
89 // Aluminum
90 matmgr.Material("MAG", 9, "Al0$", 26.98, 13., 2.7, 8.9, 37.2);
91 matmgr.Material("MAG", 29, "Al1$", 26.98, 13., 2.7, 8.9, 37.2);
92
93 // Stainless Steel
94 matmgr.Mixture("MAG", 19, "STAINLESS STEEL1", asteel, zsteel, 7.88, 4, wsteel);
95 matmgr.Mixture("MAG", 39, "STAINLESS STEEL2", asteel, zsteel, 7.88, 4, wsteel);
96 matmgr.Mixture("MAG", 59, "STAINLESS STEEL3", asteel, zsteel, 7.88, 4, wsteel);
97
98 // Iron
99 matmgr.Material("MAG", 10, "Fe0$", 55.85, 26., 7.87, 1.76, 17.1);
100 matmgr.Material("MAG", 30, "Fe1$", 55.85, 26., 7.87, 1.76, 17.1);
101
102 // Air
103 matmgr.Mixture("MAG", 15, "AIR0$", aAir, zAir, dAir, 4, wAir);
104 matmgr.Mixture("MAG", 35, "AIR1$", aAir, zAir, dAir, 4, wAir);
105
106 // Water
107 matmgr.Mixture("MAG", 16, "WATER", aWater, zWater, 1., 2, wWater);
108
109 // ****************
110 // Defines tracking media parameters.
111 // Les valeurs sont commentees pour laisser le defaut
112 // a GEANT (version 3-21, page CONS200), f.m.
113 epsil = .001; // Tracking precision,
114 stemax = -1.; // Maximum displacement for multiple scat
115 tmaxfd = -20.; // Maximum angle due to field deflection
116 deemax = -.3; // Maximum fractional energy loss, DLS
117 stmin = -.8;
118 // ***************
119
120 // IRON
121 matmgr.Medium("MAG", 10, "FE_C0", 10, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
122 matmgr.Medium("MAG", 30, "FE_C1", 30, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
123
124 // ALUMINUM
125 matmgr.Medium("MAG", 9, "ALU_C0", 9, 0, isxfldNoField, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
126 matmgr.Medium("MAG", 29, "ALU_C1", 29, 0, isxfldNoField, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
127
128 // AIR
129 matmgr.Medium("MAG", 15, "AIR_C0", 15, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
130 matmgr.Medium("MAG", 35, "AIR_C1", 35, 0, isxfldNoField, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
131
132 // Steel
133 matmgr.Medium("MAG", 19, "ST_C0", 19, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
134 matmgr.Medium("MAG", 39, "ST_C1", 39, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
135 matmgr.Medium("MAG", 49, "ST_C1_NF", 39, 0, isxfldNoField, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
136 matmgr.Medium("MAG", 59, "ST_C3", 59, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
137 // WATER
138 matmgr.Medium("MAG", 16, "WATER", 16, 0, isxfldNoField, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
139}
140
142{
144
145 // Octagon
146 const Int_t kNSides = 8;
147 const Float_t kStartAngle = 22.5; // deg
148 const Float_t kFullAngle = 360.0; // deg
149 // Mother volume
150 const Float_t kRBMotherInner = 600.00; // cm
151 const Float_t kRBMotherOuter = 790.50; // cm
152 const Float_t kLBMother = 706.00; // cm
153 // Yoke
154 const Float_t kRYokeInner = 703.50; // cm
155 const Float_t kRYokeOuter = 790.50; // cm
156 const Float_t kLYoke = 620.00; // cm
157 // Coil
158 const Float_t kRCoilInner = 593.00; // cm
159 const Float_t kRCoilOuter = 682.00; // cm
160 const Float_t kLCoil = 588.00; // cm
161 // Cooling
162 const Float_t kRCoolingOuter = 1.70; // cm
163 const Float_t kRCoolingInner = 1.00; // cm
164 // Thermal Shield
165 const Float_t kRThermalShieldInner = 566.00; // cm
166 const Float_t kRThermalShieldOuter = 571.00; // cm
167 // Crown
168 const Float_t kRCrownInner = 600.00; // cm
169 const Float_t kRCrownOuter = 785.50; // cm
170 const Float_t kLCrown1 = 605.00; // cm
171 const Float_t kLCrown2 = 620.00; // cm
172 const Float_t kLCrown3 = 706.00; // cm
173 // Door
174 const Float_t kRDoorOuter = 600.00; // cm
175 const Float_t kRPlugInner = 183.50; // cm
176 const Float_t kLDoor1 = 615.50; // cm
177 const Float_t kLDoor2 = 714.60; // cm
178 //
179 const Float_t kDegRad = TMath::Pi() / 180.;
180
181 //
182 // Top volume
183 TGeoVolume* top = gGeoManager->GetVolume("barrel");
184 assert(top);
185
186 // Media
188 auto medAir = matmgr.getTGeoMedium("MAG_AIR_C1");
189 auto medAlu = matmgr.getTGeoMedium("MAG_ALU_C1");
190 auto medAluI = matmgr.getTGeoMedium("MAG_ALU_C0");
191 auto medSteel = matmgr.getTGeoMedium("MAG_ST_C1");
192 auto medSteelNF = matmgr.getTGeoMedium("MAG_ST_C1_NF");
193 auto medWater = matmgr.getTGeoMedium("MAG_WATER");
194 //
195 // Offset between LHC and LEP axis
196 Float_t os = -30.;
197
198 //
199 // Define Barrel Mother
200 //
201 TGeoPgon* shBMother = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
202 shBMother->DefineSection(0, -kLBMother, kRBMotherInner, kRBMotherOuter);
203 shBMother->DefineSection(1, kLBMother, kRBMotherInner, kRBMotherOuter);
204 //
205 TGeoVolumeAssembly* voBMother = new TGeoVolumeAssembly("L3BM");
206 //
207 // Define Thermal Shield
208 //
209 // Only one layer
210 // This can be improved: replace by (protection - shield - insulation) !
211 //
212 TGeoPgon* shThermSh = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
213 shThermSh->DefineSection(0, -kLCoil, kRThermalShieldInner, kRThermalShieldOuter);
214 shThermSh->DefineSection(1, kLCoil, kRThermalShieldInner, kRThermalShieldOuter);
215 //
216 TGeoVolume* voThermSh = new TGeoVolume("L3TS", shThermSh, medAluI);
217 voBMother->AddNode(voThermSh, 1, new TGeoTranslation(0., 0., 0.));
218 //
219 // Define Coils and cooling circuits
220 //
221 TGeoPgon* shCoilMother = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
222 shCoilMother->DefineSection(0, -kLCoil, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter);
223 shCoilMother->DefineSection(1, kLCoil, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter);
224 //
225 // Coils
226 TGeoVolume* voCoilMother = new TGeoVolume("L3CM", shCoilMother, medAir);
227 voBMother->AddNode(voCoilMother, 1, new TGeoTranslation(0., 0., 0.));
228 // The 168 turns, placed explicitly rather than as a TGeoPgon division.
229 // Geant4's G4ParameterisationPolyhedraZ rebuilds the shared master solid while
230 // navigating, so a divided polyhedra crashes a multithreaded native-Geant4 run.
231 const Int_t kNCoilTurns = 168;
232 const Float_t kDzCoilTurn = kLCoil / kNCoilTurns;
233 TGeoPgon* shCoilTurn = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
234 shCoilTurn->DefineSection(0, -kDzCoilTurn, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter);
235 shCoilTurn->DefineSection(1, kDzCoilTurn, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter);
236 TGeoVolume* voCoilTurn = new TGeoVolume("L3CD", shCoilTurn, medAir);
237 for (Int_t iTurn = 0; iTurn < kNCoilTurns; ++iTurn) {
238 voCoilMother->AddNode(voCoilTurn, iTurn + 1,
239 new TGeoTranslation(0., 0., -kLCoil + (2 * iTurn + 1) * kDzCoilTurn));
240 }
241 TGeoPgon* shCoils = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
242 shCoils->DefineSection(0, -3., kRCoilInner, kRCoilOuter);
243 shCoils->DefineSection(1, 3., kRCoilInner, kRCoilOuter);
244 //
245 TGeoVolume* voCoils = new TGeoVolume("L3C0", shCoils, medAlu);
246 voCoilTurn->AddNode(voCoils, 1, new TGeoTranslation(0., 0., 0.));
247 //
248 // Hexagonal Cooling circuits
249 //
250 const Float_t kRCC = kRCoolingOuter;
251 const Float_t kRCW = kRCoolingInner;
252 const Float_t kRCL = kRCC * TMath::Tan(30. / 180. * TMath::Pi());
253 const Float_t kRWL = kRCW * TMath::Tan(30. / 180. * TMath::Pi());
254 // Outer Circuits
255 //
256 // Pipe
257 TGeoPgon* shCoolingPipeO = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 4);
258 shCoolingPipeO->DefineSection(0, -kRCC, kRCoilOuter + kRCC, kRCoilOuter + kRCC + 0.01);
259 shCoolingPipeO->DefineSection(1, -kRCL, kRCoilOuter, kRCoilOuter + 2. * kRCC);
260 shCoolingPipeO->DefineSection(2, kRCL, kRCoilOuter, kRCoilOuter + 2. * kRCC);
261 shCoolingPipeO->DefineSection(3, kRCC, kRCoilOuter + kRCC, kRCoilOuter + kRCC + 0.01);
262 //
263 TGeoVolume* voCoolingPipeO = new TGeoVolume("L3CCO", shCoolingPipeO, medAlu);
264 voCoilTurn->AddNode(voCoolingPipeO, 1, new TGeoTranslation(0., 0., 0.));
265 //
266 TGeoPgon* shCoolingWaterO = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 4);
267 shCoolingWaterO->DefineSection(0, -kRCW, kRCoilOuter + kRCC, kRCoilOuter + kRCC + 0.01);
268 shCoolingWaterO->DefineSection(1, -kRWL, kRCoilOuter + (kRCC - kRCW), kRCoilOuter + kRCC + kRCW);
269 shCoolingWaterO->DefineSection(2, kRWL, kRCoilOuter + (kRCC - kRCW), kRCoilOuter + kRCC + kRCW);
270 shCoolingWaterO->DefineSection(3, kRCW, kRCoilOuter + kRCC, kRCoilOuter + kRCC + 0.01);
271 //
272 TGeoVolume* voCoolingWaterO = new TGeoVolume("L3CWO", shCoolingWaterO, medWater);
273 voCoolingPipeO->AddNode(voCoolingWaterO, 1, new TGeoTranslation(0., 0., 0.));
274
275 // Inner Circuits
276 //
277 // Pipe
278 TGeoPgon* shCoolingPipeI = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 4);
279 shCoolingPipeI->DefineSection(0, -kRCC, kRCoilInner - kRCC, kRCoilInner - kRCC + 0.01);
280 shCoolingPipeI->DefineSection(1, -kRCL, kRCoilInner - 2. * kRCC, kRCoilInner);
281 shCoolingPipeI->DefineSection(2, kRCL, kRCoilInner - 2. * kRCC, kRCoilInner);
282 shCoolingPipeI->DefineSection(3, kRCC, kRCoilInner - kRCC, kRCoilInner - kRCC + 0.01);
283 //
284 TGeoVolume* voCoolingPipeI = new TGeoVolume("L3CCI", shCoolingPipeI, medAlu);
285 voCoilTurn->AddNode(voCoolingPipeI, 1, new TGeoTranslation(0., 0., 0.));
286 //
287 TGeoPgon* shCoolingWaterI = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 4);
288 shCoolingWaterI->DefineSection(0, -kRCW, kRCoilInner - kRCC, kRCoilInner - kRCC + 0.01);
289 shCoolingWaterI->DefineSection(1, -kRWL, kRCoilInner - kRCC - kRCW, kRCoilInner - (kRCC - kRCW));
290 shCoolingWaterI->DefineSection(2, kRWL, kRCoilInner - kRCC - kRCW, kRCoilInner - (kRCC - kRCW));
291 shCoolingWaterI->DefineSection(3, kRCW, kRCoilInner - kRCC, kRCoilInner - kRCC + 0.01);
292 //
293 TGeoVolume* voCoolingWaterI = new TGeoVolume("L3CWI", shCoolingWaterI, medWater);
294 voCoolingPipeI->AddNode(voCoolingWaterI, 1, new TGeoTranslation(0., 0., 0.));
295
296 //
297 // Define Yoke
298 //
299 TGeoPgon* shYoke = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2);
300 shYoke->DefineSection(0, -kLYoke, kRYokeInner, kRYokeOuter);
301 shYoke->DefineSection(1, +kLYoke, kRYokeInner, kRYokeOuter);
302 //
303 TGeoVolume* voYoke = new TGeoVolume("L3YO", shYoke, medSteelNF);
304 voBMother->AddNode(voYoke, 1, new TGeoTranslation(0., 0., 0.));
305
306 //
307 // Define Crown
308 //
309 TGeoPgon* shCrown = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 4);
310 shCrown->DefineSection(0, kLCrown1, kRCrownInner, kRYokeInner);
311 shCrown->DefineSection(1, kLCrown2, kRCrownInner, kRYokeInner);
312 shCrown->DefineSection(2, kLCrown2, kRCrownInner, kRCrownOuter);
313 shCrown->DefineSection(3, kLCrown3, kRCrownInner, kRCrownOuter);
314 //
315 TGeoVolume* voCrown = new TGeoVolume("L3CR", shCrown, medSteelNF);
316
317 //
318 // Door including "Plug"
319 //
320 Float_t slo = 2. * kRDoorOuter * TMath::Tan(22.5 * kDegRad);
321 Float_t sli = 2. * kRPlugInner * TMath::Tan(22.5 * kDegRad);
322 Double_t xpol1[12], xpol2[12], ypol1[12], ypol2[12];
323
324 xpol1[0] = 2.;
325 ypol1[0] = kRDoorOuter;
326 xpol1[1] = slo / 2.;
327 ypol1[1] = kRDoorOuter;
328 xpol1[2] = kRDoorOuter;
329 ypol1[2] = slo / 2.;
330 xpol1[3] = kRDoorOuter;
331 ypol1[3] = -slo / 2.;
332 xpol1[4] = slo / 2.;
333 ypol1[4] = -kRDoorOuter;
334 xpol1[5] = 2.;
335 ypol1[5] = -kRDoorOuter;
336 xpol1[6] = 2.;
337 ypol1[6] = -kRPlugInner - os;
338 xpol1[7] = sli / 2.;
339 ypol1[7] = -kRPlugInner - os;
340 xpol1[8] = kRPlugInner;
341 ypol1[8] = -sli / 2. - os;
342 xpol1[9] = kRPlugInner;
343 ypol1[9] = sli / 2. - os;
344 xpol1[10] = sli / 2.;
345 ypol1[10] = kRPlugInner - os;
346 xpol1[11] = 2.;
347 ypol1[11] = kRPlugInner - os;
348
349 TGeoXtru* shL3DoorR = new TGeoXtru(2);
350 shL3DoorR->DefinePolygon(12, xpol1, ypol1);
351 shL3DoorR->DefineSection(0, kLDoor1);
352 shL3DoorR->DefineSection(1, kLDoor2);
353 TGeoVolume* voL3DoorR = new TGeoVolume("L3DoorR", shL3DoorR, medSteel);
354
355 for (Int_t i = 0; i < 12; i++) {
356 xpol2[i] = -xpol1[11 - i];
357 ypol2[i] = ypol1[11 - i];
358 }
359
360 TGeoXtru* shL3DoorL = new TGeoXtru(2);
361 shL3DoorL->DefinePolygon(12, xpol2, ypol2);
362 shL3DoorL->DefineSection(0, kLDoor1);
363 shL3DoorL->DefineSection(1, kLDoor2);
364 TGeoVolume* voL3DoorL = new TGeoVolume("L3DoorL", shL3DoorL, medSteel);
365 //
366 // Plug support plate
367 //
368 Float_t ro = kRPlugInner + 50.;
369 slo = 2. * ro * TMath::Tan(22.5 * kDegRad);
370
371 xpol1[0] = 2.;
372 ypol1[0] = ro - os;
373 xpol1[1] = slo / 2.;
374 ypol1[1] = ro - os;
375 xpol1[2] = ro;
376 ypol1[2] = slo / 2. - os;
377 xpol1[3] = ro;
378 ypol1[3] = -slo / 2. - os;
379 xpol1[4] = slo / 2.;
380 ypol1[4] = -ro - os;
381 xpol1[5] = 2.;
382 ypol1[5] = -ro - os;
383
384 for (Int_t i = 0; i < 12; i++) {
385 xpol2[i] = -xpol1[11 - i];
386 ypol2[i] = ypol1[11 - i];
387 }
388
389 TGeoXtru* shL3PlugSPR = new TGeoXtru(2);
390 shL3PlugSPR->DefinePolygon(12, xpol1, ypol1);
391 shL3PlugSPR->DefineSection(0, kLDoor1 - 10.);
392 shL3PlugSPR->DefineSection(1, kLDoor1);
393 TGeoVolume* voL3PlugSPR = new TGeoVolume("L3PlugSPR", shL3PlugSPR, medSteel);
394
395 TGeoXtru* shL3PlugSPL = new TGeoXtru(2);
396 shL3PlugSPL->DefinePolygon(12, xpol2, ypol2);
397 shL3PlugSPL->DefineSection(0, kLDoor1 - 10.);
398 shL3PlugSPL->DefineSection(1, kLDoor1);
399 TGeoVolume* voL3PlugSPL = new TGeoVolume("L3PlugSPL", shL3PlugSPL, medSteel);
400
401 // Position crown and door
402 TGeoRotation* rotxz = new TGeoRotation("rotxz", 90., 0., 90., 90., 180., 0.);
403
404 TGeoVolumeAssembly* l3 = new TGeoVolumeAssembly("L3MO");
405 voBMother->AddNode(voCrown, 1, new TGeoTranslation(0., 0., 0.));
406 voBMother->AddNode(voCrown, 2, new TGeoCombiTrans(0., 0., 0., rotxz));
407 l3->AddNode(voBMother, 1, new TGeoTranslation(0., 0., 0.));
408 l3->AddNode(voL3DoorR, 1, new TGeoTranslation(0., 0., 0.));
409 l3->AddNode(voL3DoorR, 2, new TGeoCombiTrans(0., 0., 0., rotxz));
410 l3->AddNode(voL3DoorL, 1, new TGeoTranslation(0., 0., 0.));
411 l3->AddNode(voL3DoorL, 2, new TGeoCombiTrans(0., 0., 0., rotxz));
412 l3->AddNode(voL3PlugSPR, 1, new TGeoTranslation(0., 0., 0.));
413 l3->AddNode(voL3PlugSPR, 2, new TGeoCombiTrans(0., 0., 0., rotxz));
414 l3->AddNode(voL3PlugSPL, 1, new TGeoTranslation(0., 0., 0.));
415 l3->AddNode(voL3PlugSPL, 2, new TGeoCombiTrans(0., 0., 0., rotxz));
416 top->AddNode(l3, 1, new TGeoTranslation(0., 0., 0.));
417}
418
419FairModule* Magnet::CloneModule() const { return new Magnet(*this); }
Definition of the Detector class.
int32_t i
ClassImp(IdPath)
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
static MaterialManager & Instance()
void createMaterials()
Definition Magnet.cxx:60
void ConstructGeometry() override
Definition Magnet.cxx:141
FairModule * CloneModule() const override
Clone this object (used in MT mode only)
Definition Magnet.cxx:419
a common base class for passive modules - implementing generic functions
Definition PassiveBase.h:24
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLuint const GLchar * name
Definition glcorearb.h:781