Ejemplo n.º 1
0
TVector3 TVector3::operator * (const TaylorModel& d) const
{
  return TVector3(i_[0] * d, i_[1] * d, i_[2] * d);
}
Ejemplo n.º 2
0
TVector3 TVector3::operator * (FCL_REAL d) const
{
  return TVector3(i_[0] * d, i_[1] * d, i_[2] * d);
}
Ejemplo n.º 3
0
void PrimitiveSuperellipsoid::setup() {
  power = TVector3( 2.0f / e, e / n, 2.0f / n );
}
Ejemplo n.º 4
0
//__________________________________________________________________
void external_sector() {

  // Sector volume
  TVector3 CircleCenter = TVector3(0.,0.,0.);
  TVector3 LineStart = TVector3( 0.5*rib_width_x,0.,0.);
  TVector3 LineEnd = TVector3( 0.5*rib_width_x, 500.,0.);

  TVector3 crosspoint = LineCrossesCircle(CircleCenter, outer_flanch_in_rad,
					  LineStart, LineEnd);

  Double_t yWidth, zWidth, kz;
  Double_t kx,my,phi_cent;
  //  crosspoint.Print();

  Double_t x_large = (crosspoint.Y()-.5*rib_width_x/TMath::Tan(phi_step/2.))*
    TMath::Sin(phi_step/2.);
  Double_t x_small = (inner_flanch_out_rad*TMath::Sin(phi_step/2.) -
    .5*rib_width_x)/TMath::Cos(phi_step/2.) ;

  Double_t zSector = tpc_z - tpc_drift_z; // z thickness of trap

  yWidth = .5*(x_large - x_small)/TMath::Tan(phi_step/2.);

  zWidth = .5*zSector; // 

  kz = 0.;

  //  make sector

  Fill_TRAP(x_small, x_large, yWidth, zWidth);

  position << 0.0 << " " << 0.0 << " " << 0.0;

  Double_t center_rad = inner_flanch_out_rad + yWidth;

  Mpdshape* extsect = new Mpdshape(f, "tpc01ES", "tpc01ec#1", "TRAP", "air",
				   points.str(), position.str());
  extsect->SetSegment(1);

  Int_t imodule=1;

  Double_t zCurrent,zRot;

  Mpdshape *layer_G10 = new Mpdshape(f, "tpc01ESG10", "tpc01ES#1", "TRAP", "G10",
			     points.str(), position.str());
  layer_G10->SetSegment(1);

  Mpdshape *layer_Cu = new Mpdshape(f, "tpc01ESCu", "tpc01ES#1",
			    "TRAP", "copper", points.str(), position.str());
  layer_Cu->SetSegment(1);

  Mpdshape *layer_Al = new Mpdshape(f, "tpc01ESAl", "tpc01ES#1", "TRAP",
			    "aluminium ",points.str(), position.str());
  layer_Al->SetSegment(1);
  // ========================================

    for (Int_t k = 0; k < Nsect; k++) {

      phi_cent = k*phi_step; // radians
      kx = center_rad* TMath::Cos(phi_cent);
      my = center_rad* TMath::Sin(phi_cent);
      zRot = step*k  - 90.;
      //      cout << " X " << kx << " Y " << my << "Z  " << kz << endl;
      extsect->SetPosition(kx, my, kz);
      extsect->SetRotation(zRot, 0.0, 0.0);
      extsect->DumpWithIncrement();

      //+++++++++++++++++==================
#ifdef FEESIM
      if (imodule == 1) {
	external_sector_layers(x_small, x_large, yWidth,
			       layer_G10, layer_Cu, layer_Al);
      }

      imodule++;

      zCurrent =  -.5*zSector + 0.5*zG10;

      layer_G10->SetPosition(0., 0., zCurrent);
      layer_G10->DumpWithIncrement();

      zCurrent =  zCurrent + 0.5*(zG10 + zCu);
      layer_Cu->SetPosition(0., 0., zCurrent);
      layer_Cu->DumpWithIncrement();
      
      zCurrent =  zCurrent + 0.5*(zAl + zCu);
      layer_Al->SetPosition(0., 0.,zCurrent);
      layer_Al->DumpWithIncrement();
#endif      
    }
  cout << "==== external sectors filled ====\n";
}
Ejemplo n.º 5
0
TVector3 TVector3::operator - () const
{
  return TVector3(-i_[0], -i_[1], -i_[2]);
}
Ejemplo n.º 6
0
DGLE_RESULT DGLE_API CMesh::RecalculateTangentSpace()
{
	if (!_pBuffer)
		return S_FALSE;
	
	TDrawDataDesc desc;
		
	_pBuffer->GetBufferDrawDataDesc(desc);

	if (desc.uiTextureVertexOffset == -1 ||
		(desc.uiTangentOffset == -1 && desc.uiBinormalOffset != -1) || (desc.uiTangentOffset != -1 && desc.uiBinormalOffset == -1)) // confusing situation should never happen
		return E_ABORT;

	if (desc.uiNormalOffset == -1)
		RecalculateNormals(false);

	uint stride, verts_data_size, verts_count, idxs_data_size, idxs_count;
	_CopyMeshData(desc, stride, verts_data_size, verts_count, idxs_data_size, idxs_count);

	TDrawDataDesc desc_new(desc);
	bool do_delete_new = false;

	if (desc.uiTangentOffset == -1 && desc.uiBinormalOffset == -1)
	{
		do_delete_new = true;

		const uint new_verts_data_size = verts_data_size + verts_count * 6 * sizeof(float);
		desc_new.pData = new uint8[new_verts_data_size + idxs_data_size];
		memcpy(desc_new.pData, desc.pData, verts_data_size);

		desc_new.uiTangentOffset = verts_data_size;
		desc_new.uiTangentStride = 0;

		desc_new.uiBinormalOffset = verts_data_size + verts_count * 3 * sizeof(float);
		desc_new.uiBinormalStride = 0;

		if (idxs_count != 0)
		{
			desc_new.pIndexBuffer = &desc_new.pData[new_verts_data_size];
			memcpy(&desc_new.pData[new_verts_data_size], &desc.pData[verts_data_size], idxs_data_size);
		}

		memset(&desc_new.pData[verts_data_size], 0, new_verts_data_size - verts_data_size);
	}
	else
	{
		const uint t_stride = desc_new.uiTangentStride == 0 ? 3 * sizeof(float) : desc_new.uiTangentStride,
			b_stride = desc_new.uiBinormalStride == 0 ? 3 * sizeof(float) : desc_new.uiBinormalStride;

		for (uint i = 0; i < verts_count; ++i)
		{
			*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiTangentOffset + i * t_stride])) = TVector3();
			*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiBinormalOffset + i * b_stride])) = TVector3();
		}
	}

	const uint t_stride = desc_new.uiTangentStride == 0 ? 3 * sizeof(float) : desc_new.uiTangentStride,
		b_stride = desc_new.uiBinormalStride == 0 ? 3 * sizeof(float) : desc_new.uiBinormalStride,
		tex_stride = desc_new.uiTextureVertexStride == 0 ? 2 * sizeof(float) : desc_new.uiTextureVertexStride,
		v_stride = desc_new.uiVertexStride == 0 ? 3 * sizeof(float) : desc_new.uiVertexStride,
		n_stride = desc_new.uiNormalStride == 0 ? 3 * sizeof(float) : desc_new.uiNormalStride,
		count = idxs_count == 0 ? verts_count / 3 : idxs_count / 3;

	for(uint i = 0; i < count; ++i)
	{
		uint face[3];

		if (idxs_count == 0)
		{
			face[0] = i * 3;
			face[1] = i * 3 + 1;
			face[2] = i * 3 + 2;
		}
		else
			if (desc_new.bIndexBuffer32)
			{
				face[0] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[0];
				face[1] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[1];
				face[2] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[2];
			}
			else
			{
				face[0] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[0];
				face[1] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[1];
				face[2] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[2];
			}
			
		const TPoint3 * const v[3] = {
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[0] * v_stride]),
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[1] * v_stride]),
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[2] * v_stride])};

		const TPoint2 * const t[3] = {
			reinterpret_cast<TPoint2 *>(&desc_new.pData[desc_new.uiTextureVertexOffset + face[0] * tex_stride]),
			reinterpret_cast<TPoint2 *>(&desc_new.pData[desc_new.uiTextureVertexOffset + face[1] * tex_stride]),
			reinterpret_cast<TPoint2 *>(&desc_new.pData[desc_new.uiTextureVertexOffset + face[2] * tex_stride])};

		const TVector3 v1 = *v[1] - *v[0], v2 = *v[2] - *v[0];
		const TVector2 v3 = *t[1] - *t[0], v4 = *t[2] - *t[0];

		const float d = v3.Cross(v4);

		if (d == 0.f) continue;

		const float r = 1.f / d;

		const TVector3 sdir = TVector3(v4.y * v1.x - v4.x * v2.x, v4.y * v1.y - v4.x * v2.y, v4.y * v1.z - v4.x * v2.z) * r,
			tdir = TVector3(v3.x * v2.x - v3.y * v1.x, v3.x * v2.y - v3.y * v1.y, v3.x * v2.z - v3.y * v1.z) * r;

		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiTangentOffset + face[0] * t_stride])) += sdir;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiTangentOffset + face[1] * t_stride])) += sdir;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiTangentOffset + face[2] * t_stride])) += sdir;

		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiBinormalOffset + face[0] * b_stride])) += tdir;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiBinormalOffset + face[1] * b_stride])) += tdir;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiBinormalOffset + face[2] * b_stride])) += tdir;
	}

	for (uint i = 0; i < verts_count; ++i)
	{
		const TVector3 * const normal = reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + i * n_stride]);
		TVector3 *tangent = reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiTangentOffset + i * t_stride]),
			*binormal = reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiBinormalOffset + i * b_stride]);
		
		float dot_1 = normal->Dot(*tangent), dot_2;
		*tangent = (*tangent - *normal * dot_1).Normalize();
		dot_1 = normal->Dot(*tangent);
		dot_2 = tangent->Dot(*binormal);
		*binormal = (*binormal - *normal * dot_1 + *tangent * dot_2).Normalize();
	}

	PARANOIC_CHECK_RES(_pBuffer->Reallocate(desc_new, verts_count, idxs_count, CRDM_TRIANGLES));

	if (do_delete_new)
		delete[] desc_new.pData;

	delete[] desc.pData;

	return S_OK;
}
Ejemplo n.º 7
0
TVector3 getPosition(Double_t angle) {
    Double_t r = innerRadius;
    Double_t x = r*TMath::Cos(angle*TMath::DegToRad());
    Double_t y = r*TMath::Sin(angle*TMath::DegToRad());
    return TVector3(x, y, 0);
}
Ejemplo n.º 8
0
TVector3 TVector3::operator + (const TVector3& other) const
{
  return TVector3(i_[0] + other.i_[0], i_[1] + other.i_[1], i_[2] + other.i_[2]);
}
Ejemplo n.º 9
0
void rotate_3vector(void){

  PI = TMath::Pi();

  TVector3 beam = TVector3(0.,0.,1.);
  TVector3 scat = TVector3(0.2,0.4,1.);
  std::cout << "beam x : " << beam.x() << std::endl;
  std::cout << "beam y : " << beam.y() << std::endl;
  std::cout << "beam z : " << beam.z() << std::endl;
  std::cout << "scat x : " << scat.x() << std::endl;
  std::cout << "scat y : " << scat.y() << std::endl;
  std::cout << "scat z : " << scat.z() << std::endl;

  double bx=beam.x();
  double by=beam.y();
  double bz=beam.z();
  double sx=scat.x();
  double sy=scat.y();
  double sz=scat.z();

  double theta  = acos((bx*sx + by*sy + bz*sz)/sqrt(bx*bx + by*by + bz*bz)/sqrt(sx*sx + sy*sy + sz*sz));
  double theta_ = acos(sz/sqrt(sx*sx+sy*sy+sz*sz));

  std::cout << "theta  : " << theta  << std::endl;
  std::cout << "theta_ : " << theta_ << std::endl;

  TVector3 beam2 = TVector3(0, 1, 0);
  double bx2=beam2.x();
  double by2=beam2.y();
  double bz2=beam2.z();

  std::cout << "beam2 x (nom) : " << beam2.x()/sqrt(bx2*bx2+by2*by2+bz2*bz2) << std::endl;
  std::cout << "beam2 y (nom) : " << beam2.y()/sqrt(bx2*bx2+by2*by2+bz2*bz2) << std::endl;
  std::cout << "beam2 z (nom) : " << beam2.z()/sqrt(bx2*bx2+by2*by2+bz2*bz2) << std::endl;

  double theta_tmp  = - atan(by2/sqrt(bx2*bx2 + bz2*bz2));
  double phi_tmp    = atan2(bx2, bz2);

  std::cout << "theta_tmp  : " << theta_tmp  << std::endl;
  std::cout << "phi_tmp  : " << phi_tmp  << std::endl;

  beam.RotateX(theta_tmp);
  beam.RotateY(phi_tmp);

  scat.RotateX(theta_tmp);
  scat.RotateY(phi_tmp);

  bx=beam.x();
  by=beam.y();
  bz=beam.z();
  sx=scat.x();
  sy=scat.y();
  sz=scat.z();

  std::cout << "roteta beam x : " << bx << std::endl;
  std::cout << "roteta beam y : " << by << std::endl;
  std::cout << "roteta beam z : " << bz << std::endl;
  std::cout << "roteta scat x : " << sx << std::endl;
  std::cout << "roteta scat y : " << sy << std::endl;
  std::cout << "roteta scat z : " << sz << std::endl;


  double theta_rotate  = acos((bx*sx + by*sy + bz*sz)/sqrt(bx*bx + by*by + bz*bz)/sqrt(sx*sx + sy*sy + sz*sz));

  std::cout << "===========================" << std::endl;
  std::cout << "theta         : " << theta  << std::endl;
  std::cout << "theta_rotate  : " << theta_rotate  << std::endl;

}
Ejemplo n.º 10
0
CLight::CLight(uint uiInstIdx):
CInstancedObj(uiInstIdx), _bEnabled(true), _eType(LT_DIRECTIONAL),
_stMainCol(ColorWhite()), _stPos(TPoint3()), _stDir(TVector3(0.f, 0.f, 1.f)),
_fRange(100.f), _fIntensity(1.f), _fAngle(90.f)
{}
Ejemplo n.º 11
0
bool CCharShape::Collision (const TVector3& pos, const TPolyhedron& ph) {
    ResetNode (0);
    TranslateNode (0, TVector3 (pos.x, pos.y, pos.z));
    return CheckCollision (ph);
}
Ejemplo n.º 12
0
bool CCharShape::Load (const string& dir, const string& filename, bool with_actions) {
    CSPList list (500);

    useActions = with_actions;
    CreateRootNode ();
    newActions = true;

    if (!list.Load (dir, filename)) {
        Message ("could not load character", filename);
        return false;
    }

    for (size_t i=0; i<list.Count(); i++) {
        const string& line = list.Line(i);
        int node_name = SPIntN (line, "node", -1);
        int parent_name = SPIntN (line, "par", -1);
        string mat_name = SPStrN (line, "mat", "");
        string name = SPStrN (line, "joint", "");
        string fullname = SPStrN (line, "name", "");

        if (SPIntN (line, "material", 0) > 0) {
            CreateMaterial (line);
        } else {
            double visible = SPFloatN (line, "vis", -1.0);
            bool shadow = SPBoolN (line, "shad", false);
            string order = SPStrN (line, "order", "");
            CreateCharNode (parent_name, node_name, name, fullname, order, shadow);
            TVector3 rot = SPVector3N (line, "rot", NullVec);
            MaterialNode (node_name, mat_name);
            for (size_t ii = 0; ii < order.size(); ii++) {
                int act = order[ii]-48;
                switch (act) {
                case 0: {
                    TVector3 trans = SPVector3N (line, "trans", TVector3 (0,0,0));
                    TranslateNode (node_name, trans);
                    break;
                }
                case 1:
                    RotateNode (node_name, 1, rot.x);
                    break;
                case 2:
                    RotateNode (node_name, 2, rot.y);
                    break;
                case 3:
                    RotateNode (node_name, 3, rot.z);
                    break;
                case 4: {
                    TVector3 scale = SPVector3N (line, "scale", TVector3 (1,1,1));
                    ScaleNode (node_name, scale);
                    break;
                }
                case 5:
                    VisibleNode (node_name, visible);
                    break;
                case 9:
                    RotateNode (node_name, 2, rot.z);
                    break;
                default:
                    break;
                }
            }
        }
    }
    newActions = false;
    return true;
}
Ejemplo n.º 13
0
// --------------------------------------------------------------------
//                      add_track_mark
// --------------------------------------------------------------------
void add_track_mark(const CControl *ctrl, int *id) {
    if (param.perf_level < 3)
		return;

	TTerrType *TerrList = &Course.TerrList[0];

	*id = Course.GetTerrainIdx (ctrl->cpos.x, ctrl->cpos.z, 0.5);
	if (*id < 1) {
		break_track_marks();
		return;
	}

	if (!TerrList[*id].trackmarks) {
		break_track_marks();
		return;
	}

	TVector3 vel = ctrl->cvel;
    double speed = NormVector (vel);
    if (speed < SPEED_TO_START_TRENCH) {
		break_track_marks();
		return;
    }

    TVector3 width_vector = CrossProduct (ctrl->cdirection, TVector3 (0, 1, 0));
    double magnitude = NormVector (width_vector);
    if (magnitude == 0) {
		break_track_marks();
		return;
    }

    TVector3 left_vector = ScaleVector (TRACK_WIDTH/2.0, width_vector);
    TVector3 right_vector = ScaleVector (-TRACK_WIDTH/2.0, width_vector);
    TVector3 left_wing =  SubtractVectors (ctrl->cpos, left_vector);
    TVector3 right_wing = SubtractVectors (ctrl->cpos, right_vector);
    double left_y = Course.FindYCoord (left_wing.x, left_wing.z);
    double right_y = Course.FindYCoord (right_wing.x, right_wing.z);

	if (fabs(left_y-right_y) > MAX_TRACK_DEPTH) {
		break_track_marks();
		return;
    }

    TPlane surf_plane = Course.GetLocalCoursePlane (ctrl->cpos);
    double dist_from_surface = DistanceToPlane (surf_plane, ctrl->cpos);
	// comp_depth = get_compression_depth(Snow);
	double comp_depth = 0.1;
    if (dist_from_surface >= (2 * comp_depth)) {
		break_track_marks();
		return;
    }

	if(track_marks.quads.size() < MAX_TRACK_MARKS)
		track_marks.quads.push_back(track_quad_t());
	list<track_quad_t>::iterator qprev = track_marks.current_mark;
	if(track_marks.current_mark == track_marks.quads.end())
		track_marks.current_mark = track_marks.quads.begin();
	else
		track_marks.current_mark = incrementRingIterator(track_marks.current_mark);
	list<track_quad_t>::iterator q = track_marks.current_mark;

    if (!continuing_track) {
		q->track_type = TRACK_HEAD;
		q->v1 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v2 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->v3 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v4 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n1 = Course.FindCourseNormal (q->v1.x, q->v1.z);
		q->n2 = Course.FindCourseNormal (q->v2.x, q->v2.z);
		q->t1 = TVector2(0.0, 0.0);
		q->t2 = TVector2(1.0, 0.0);
    } else {
		q->track_type = TRACK_TAIL;
		if (qprev != track_marks.quads.end()) {
		    q->v1 = qprev->v3;
	    	q->v2 = qprev->v4;
		    q->n1 = qprev->n3;
		    q->n2 = qprev->n4;
		    q->t1 = qprev->t3;
		    q->t2 = qprev->t4;
	if (qprev->track_type == TRACK_TAIL) qprev->track_type = TRACK_MARK;
		}
		q->v3 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v4 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n3 = Course.FindCourseNormal (q->v3.x, q->v3.z);
		q->n4 = Course.FindCourseNormal (q->v4.x, q->v4.z);
		double tex_end = speed*g_game.time_step/TRACK_WIDTH;
		if (q->track_type == TRACK_HEAD) {
		    q->t3= TVector2 (0.0, 1.0);
		    q->t4= TVector2 (1.0, 1.0);
		} else {
		    q->t3 = TVector2 (0.0, q->t1.y + tex_end);
		    q->t4 = TVector2 (1.0, q->t2.y + tex_end);
		}
    }
    q->alpha = min ((2*comp_depth-dist_from_surface)/(4*comp_depth), 1.0);
    continuing_track = true;
}
Ejemplo n.º 14
0
TVector3 TVector3::cross(const TVector3& other) const
{
  return TVector3(i_[1] * other.i_[2] - i_[2] * other.i_[1], 
                  i_[2] * other.i_[0] - i_[0] * other.i_[2],
                  i_[0] * other.i_[1] - i_[1] * other.i_[0]);
}
Ejemplo n.º 15
0
void upg_stereo_straw_g1() {

ostringstream fname; 
fname << "upg_stereo_straw_" << numLayers << "_layers_" << Int_t(floor(innerRadius)) << "_x_" << Int_t(floor(outerRadius)) << ".01.geo";
const char* filename = (fname.str()).c_str();

// output file for straw endcap geometry
ofstream* f = new ofstream(filename, ios::out | ios::trunc);                                                                            

//************************* Main procedure START *****************************

Mpdshape* layer =  initDrawLayer(f, TVector3(angleLayers, 0.0, 0.0), TVector3(0, 0, initDist + layerThickness/2.0), 0);
Mpdshape* layerR = initDrawLayer(f, TVector3(angleLayers, 0.0, 0.0), TVector3(0, 0, initDist + layerThickness*1 + layerThickness/2.0), angleStereo);
Mpdshape* layerL = initDrawLayer(f, TVector3(angleLayers, 0.0, 0.0), TVector3(0, 0, initDist + layerThickness*2 + layerThickness/2.0), -angleStereo);
drawLayer(layer, TVector3(angleLayers,0,0), TVector3(0,0,initDist + layerThickness*3 + layerThickness/2.0));


for (Int_t i = 4; i < numLayers; i+=4) {                                                                                                          
    drawLayer(layer, TVector3((i/4.+1)*angleLayers,0,0), TVector3(0,0, initDist + layerThickness/2.0 + i*layerThickness));
    drawLayer(layerR, TVector3((i/4.+1)*angleLayers,0,0), TVector3(0,0, initDist + layerThickness/2.0 + (i+1)*layerThickness));
    drawLayer(layerL, TVector3((i/4.+1)*angleLayers,0,0), TVector3(0,0, initDist + layerThickness/2.0 + (i+2)*layerThickness));
    drawLayer(layer, TVector3((i/4.+1)*angleLayers,0,0), TVector3(0,0, initDist + layerThickness/2.0 + (i+3)*layerThickness));
} 


//*********************** Main procedure END *********************************
delete layerL;
delete layer;
delete layerR;

f->close();
return;

}
Ejemplo n.º 16
0
TVector3 TVector3::cross(const Vec3f& other) const
{
  return TVector3(i_[1] * other[2] - i_[2] * other[1], 
                  i_[2] * other[0] - i_[0] * other[2],
                  i_[0] * other[1] - i_[1] * other[0]);
}
Ejemplo n.º 17
0
void r3ball(Int_t nEvents = 1,
	    TMap& fDetList,
            TString Target = "LeadTarget",
            Bool_t fVis = kFALSE,
            TString fMC = "TGeant3",
            TString fGenerator = "box",
            Bool_t fUserPList = kFALSE,
            Bool_t fR3BMagnet = kTRUE,
            Bool_t fCalifaHitFinder = kFALSE,
            Bool_t fStarTrackHitFinder = kFALSE,
            Double_t fMeasCurrent = 2000.,
            TString OutFile = "r3bsim.root",
            TString ParFile = "r3bpar.root",
            TString InFile = "evt_gen.dat",
            double energy1, double energy2)
{


  TString dir = getenv("VMCWORKDIR");
  TString r3bdir = dir + "/macros";
  
  TString r3b_geomdir = dir + "/geometry";
  gSystem->Setenv("GEOMPATH",r3b_geomdir.Data());
  
  TString r3b_confdir = dir + "gconfig";
  gSystem->Setenv("CONFIG_DIR",r3b_confdir.Data());
  
  // In general, the following parts need not be touched
  // ========================================================================
  
  // ----    Debug option   -------------------------------------------------
  gDebug = 0;
  // ------------------------------------------------------------------------
  
  // -----   Timer   --------------------------------------------------------
  TStopwatch timer;
  timer.Start();
  // ------------------------------------------------------------------------
  
  
  // -----   Create simulation run   ----------------------------------------
  FairRunSim* run = new FairRunSim();
  run->SetName(fMC.Data());              // Transport engine
  run->SetOutputFile(OutFile.Data());          // Output file
  FairRuntimeDb* rtdb = run->GetRuntimeDb();
  
  FairLogger::GetLogger()->SetLogScreenLevel("DEBUG");
  
  //  R3B Special Physics List in G4 case
  if ( (fUserPList  == kTRUE ) &&
       (fMC.CompareTo("TGeant4")   == 0)
      ){
    run->SetUserConfig("g4R3bConfig.C");
    run->SetUserCuts("SetCuts.C");
  }
  
  
  // -----   Create media   -------------------------------------------------
  run->SetMaterials("media_r3b.geo");       // Materials
  
  
  // Magnetic field map type
  Int_t fFieldMap = 0;
  
  
  // Global Transformations
  //- Two ways for a Volume Rotation are supported
  //-- 1) Global Rotation (Euler Angles definition)
  //-- This represent the composition of : first a rotation about Z axis with
  //-- angle phi, then a rotation with theta about the rotated X axis, and
  //-- finally a rotation with psi about the new Z axis.
  Double_t phi,theta,psi;
  
  //-- 2) Rotation in Ref. Frame of the Volume
  //-- Rotation is Using Local Ref. Frame axis angles
  Double_t thetaX,thetaY,thetaZ;
  

  //- Global Translation  Lab. frame.
  Double_t tx,ty,tz;
  
  
  // -----   Create R3B geometry --------------------------------------------
  //R3B Cave definition
  FairModule* cave= new R3BCave("CAVE");
  cave->SetGeometryFileName("r3b_cave.geo");
  run->AddModule(cave);
  

  //R3B Target definition
  if (fDetList.FindObject("TARGET") ) {
    R3BModule* target= new R3BTarget(Target.Data());
    target->SetGeometryFileName(((TObjString*)fDetList.GetValue("TARGET"))->GetString().Data());
    run->AddModule(target);
  }
  
  //R3B SiTracker Cooling definition
  if (fDetList.FindObject("VACVESSELCOOL") ) {
    R3BModule* vesselcool= new R3BVacVesselCool(Target.Data());
    vesselcool->SetGeometryFileName(((TObjString*)fDetList.GetValue("VACVESSELCOOL"))->GetString().Data());
    run->AddModule(vesselcool);
  }
  //R3B Magnet definition
  if (fDetList.FindObject("ALADIN") ) {
    fFieldMap = 0;
    R3BModule* mag = new R3BMagnet("AladinMagnet");
    mag->SetGeometryFileName(((TObjString*)fDetList.GetValue("ALADIN"))->GetString().Data());
    run->AddModule(mag);
  }
  
  //R3B Magnet definition
  if (fDetList.FindObject("GLAD") ) {
    fFieldMap = 1;
    R3BModule* mag = new R3BGladMagnet("GladMagnet", ((TObjString*)fDetList->GetValue("GLAD"))->GetString(), "GLAD Magnet");
    run->AddModule(mag);
  }
  
  if (fDetList.FindObject("CRYSTALBALL") ) {
    //R3B Crystal Calorimeter
    R3BDetector* xball = new R3BXBall("XBall", kTRUE);
    xball->SetGeometryFileName(((TObjString*)fDetList.GetValue("CRYSTALBALL"))->GetString().Data());
    run->AddModule(xball);
  }
  
  if (fDetList.FindObject("CALIFA") ) {
    // CALIFA Calorimeter
    R3BDetector* califa = new R3BCalifa("Califa", kTRUE);
//    ((R3BCalifa *)califa)->SelectGeometryVersion(0x438b);
    ((R3BCalifa *)califa)->SelectGeometryVersion(17);
    //Selecting the Non-uniformity of the crystals (1 means +-1% max deviation)
    ((R3BCalifa *)califa)->SetNonUniformity(.0);
    califa->SetGeometryFileName(((TObjString*)fDetList.GetValue("CALIFA"))->GetString().Data());
    run->AddModule(califa);
  }

  // Tracker
  if (fDetList.FindObject("TRACKER")  ) {
    R3BDetector* tra = new R3BTra("Tracker", kTRUE);
    tra->SetGeometryFileName(((TObjString*)fDetList.GetValue("TRACKER"))->GetString().Data());
    run->AddModule(tra);
  }
  
  // STaRTrack
  if (fDetList.FindObject("STaRTrack")  ) {
    R3BDetector* tra = new R3BSTaRTra("STaRTrack", kTRUE);
    tra->SetGeometryFileName(((TObjString*)fDetList.GetValue("STaRTrack"))->GetString().Data());
    run->AddModule(tra);
  }
  
  // DCH drift chambers
  if (fDetList.FindObject("DCH") ) {
    R3BDetector* dch = new R3BDch("Dch", kTRUE);
    dch->SetGeometryFileName(((TObjString*)fDetList.GetValue("DCH"))->GetString().Data());
    run->AddModule(dch);
  }
  
  // Tof
  if (fDetList.FindObject("TOF") ) {
    R3BDetector* tof = new R3BTof("Tof", kTRUE);
    tof->SetGeometryFileName(((TObjString*)fDetList.GetValue("TOF"))->GetString().Data());
    run->AddModule(tof);
  }
  
  // mTof
  if (fDetList.FindObject("MTOF") ) {
    R3BDetector* mTof = new R3BmTof("mTof", kTRUE);
    mTof->SetGeometryFileName(((TObjString*)fDetList.GetValue("MTOF"))->GetString().Data());
    run->AddModule(mTof);
  }

  // GFI detector
  if (fDetList.FindObject("GFI") ) {
    R3BDetector* gfi = new R3BGfi("Gfi", kTRUE);
    gfi->SetGeometryFileName(((TObjString*)fDetList.GetValue("GFI"))->GetString().Data());
    run->AddModule(gfi);
  }
  
  // Land Detector
  if (fDetList.FindObject("LAND") ) {
    R3BDetector* land = new R3BLand("Land", kTRUE);
    land->SetVerboseLevel(1);
    land->SetGeometryFileName(((TObjString*)fDetList.GetValue("LAND"))->GetString().Data());
    run->AddModule(land);
  }
  
  // NeuLand Scintillator Detector
  if(fDetList.FindObject("SCINTNEULAND")) {
    R3BDetector* land = new R3BLand("Land", kTRUE);
    land->SetVerboseLevel(1);
    land->SetGeometryFileName(((TObjString*)fDetList.GetValue("SCINTNEULAND"))->GetString().Data());
    run->AddModule(land);
  }
  
  // MFI Detector
  if(fDetList.FindObject("MFI")) {
    R3BDetector* mfi = new R3BMfi("Mfi", kTRUE);
    mfi->SetGeometryFileName(((TObjString*)fDetList.GetValue("MFI"))->GetString().Data());
    run->AddModule(mfi);
  }

  // PSP Detector
  if(fDetList.FindObject("PSP")) {
    R3BDetector* psp = new R3BPsp("Psp", kTRUE);
    psp->SetGeometryFileName(((TObjString*)fDetList.GetValue("PSP"))->GetString().Data());
    run->AddModule(psp);
  }
  
  // Luminosity detector
  if (fDetList.FindObject("LUMON") ) {
    R3BDetector* lumon = new ELILuMon("LuMon", kTRUE);
    lumon->SetGeometryFileName(((TObjString*)fDetList.GetValue("LUMON"))->GetString().Data());
    run->AddModule(lumon);
  }
  
  // -----   Create R3B  magnetic field ----------------------------------------
  Int_t typeOfMagneticField = 0;
  Int_t fieldScale = 1;
  Bool_t fVerbose = kFALSE;
  
  //NB: <D.B>
  // If the Global Position of the Magnet is changed
  // the Field Map has to be transformed accordingly
  if (fFieldMap == 0) {
    R3BAladinFieldMap* magField = new R3BAladinFieldMap("AladinMaps");
    magField->SetCurrent(fMeasCurrent);
    magField->SetScale(fieldScale);
    
    if ( fR3BMagnet == kTRUE ) {
      run->SetField(magField);
    } else {
      run->SetField(NULL);
    }
  } else if(fFieldMap == 1){
    R3BGladFieldMap* magField = new R3BGladFieldMap("R3BGladMap");
    magField->SetScale(fieldScale);
    
    if ( fR3BMagnet == kTRUE ) {
      run->SetField(magField);
    } else {
      run->SetField(NULL);
    }
  }  //! end of field map section
  
  // -----   Create PrimaryGenerator   --------------------------------------

  // 1 - Create the Main API class for the Generator
  FairPrimaryGenerator* primGen = new FairPrimaryGenerator();
  
  if (fGenerator.CompareTo("ion") == 0  ) {
          // R3B Ion Generator
          Int_t z = 30;  // Atomic number
          Int_t a = 65; // Mass number
          Int_t q = 0;   // Charge State 
          Int_t m = 1;   // Multiplicity
          Double_t px = 40./a;  // X-Momentum / per nucleon!!!!!!
          Double_t py = 600./a;  // Y-Momentum / per nucleon!!!!!!
          Double_t pz = 0.01/a;  // Z-Momentum / per nucleon!!!!!!
          R3BIonGenerator* ionGen = new R3BIonGenerator(z,a,q,m,px,py,pz);
          ionGen->SetSpotRadius(1,1,0);
          // add the ion generator
          primGen->AddGenerator(ionGen);
  }

  if (fGenerator.CompareTo("ascii") == 0  ) {
    R3BAsciiGenerator* gen = new R3BAsciiGenerator((dir+"/input/"+InFile).Data());
    primGen->AddGenerator(gen);
  }
  

  if (fGenerator.CompareTo("box") == 0  ) {
	  // 2- Define the BOX generator
	  Double_t pdgId=2212; // proton beam
	  Double_t theta1= 25.;  // polar angle distribution
	  //Double_t theta2= 7.;
	  Double_t theta2= 66.;
//	  Double_t momentum=1.09008; // 500 MeV/c
//	  Double_t momentum=0.4445834; // 100 MeV/c
          Double_t momentum1=TMath::Sqrt(energy1*energy1 + 2*energy1*0.938272046);
          Double_t momentum2=TMath::Sqrt(energy2*energy2 + 2*energy2*0.938272046);
	  FairBoxGenerator* boxGen = new FairBoxGenerator(pdgId, 1);
	  boxGen->SetThetaRange (   theta1,   theta2);
	  boxGen->SetPRange     (momentum1,momentum2);
	  boxGen->SetPhiRange   (0,360.);
	  //boxGen->SetXYZ(0.0,0.0,-1.5);
	  boxGen->SetXYZ(0.0,0.0,0.0);
          boxGen->SetDebug(kFALSE);
	  // add the box generator
	  primGen->AddGenerator(boxGen);

          //primGen->SetTarget(0.25, 0.5);
          //primGen->SmearVertexZ(kTRUE);
  } 
	
  if (fGenerator.CompareTo("gammas") == 0  ) {
        // 2- Define the CALIFA Test gamma generator
        //Double_t pdgId=22; // gamma emission
        Double_t pdgId=2212; // proton emission
        Double_t theta1= 10.;  // polar angle distribution
        Double_t theta2= 40.;
        //Double_t theta2= 90.; 
        //Double_t momentum=0.002; // 0.010 GeV/c = 10 MeV/c 
        Double_t momentumI=0.002; // 0.010 GeV/c = 10 MeV/c 
        Double_t momentumF=0.002; // 0.010 GeV/c = 10 MeV/c 
        //Double_t momentumF=0.808065; // 0.808065 GeV/c (300MeV Kin Energy for protons) 
        //Double_t momentumI=0.31016124; // 0.31016124 GeV/c (50MeV Kin Energy for protons)
        //Double_t momentum=0.4442972; // 0.4442972 GeV/c (100MeV Kin Energy for protons)
        //Double_t momentum=0.5509999; // 0.5509999 GeV/c (150MeV Kin Energy for protons)
        //Double_t momentumI=0.64405; // 0.64405 GeV/c (200MeV Kin Energy for protons) 
        Int_t multiplicity = 1;
        R3BCALIFATestGenerator* gammasGen = new R3BCALIFATestGenerator(pdgId, multiplicity);
        gammasGen->SetThetaRange (theta1,   theta2);
        gammasGen->SetCosTheta();
        gammasGen->SetPRange(momentumI,momentumF);
        gammasGen->SetPhiRange(-180.,180.);
        //gammasGen->SetXYZ(0.0,0.0,-1.5);
        //gammasGen->SetXYZ(0.0,0.0,0);
        gammasGen->SetBoxXYZ(-0.1,0.1,-0.1,0.1,-0.1,0.1);
        //gammasGen->SetLorentzBoost(0.8197505718204776); //beta=0.81975 for 700 A MeV
        // add the gamma generator
        primGen->AddGenerator(gammasGen);
  }


  if (fGenerator.CompareTo("r3b") == 0  ) {
    R3BSpecificGenerator *pR3bGen = new R3BSpecificGenerator();
    
    // R3bGen properties
    pR3bGen->SetBeamInteractionFlag("off");
    pR3bGen->SetRndmFlag("off");
    pR3bGen->SetRndmEneFlag("off");
    pR3bGen->SetBoostFlag("off");
    pR3bGen->SetReactionFlag("on");
    pR3bGen->SetGammasFlag("off");
    pR3bGen->SetDecaySchemeFlag("off");
    pR3bGen->SetDissociationFlag("off");
    pR3bGen->SetBackTrackingFlag("off");
    pR3bGen->SetSimEmittanceFlag("off");
    
    // R3bGen Parameters
    pR3bGen->SetBeamEnergy(1.); // Beam Energy in GeV
    pR3bGen->SetSigmaBeamEnergy(1.e-03); // Sigma(Ebeam) GeV
    pR3bGen->SetParticleDefinition(2212); // Use Particle Pdg Code
    pR3bGen->SetEnergyPrim(0.3); // Particle Energy in MeV
    Int_t fMultiplicity = 50;
    pR3bGen->SetNumberOfParticles(fMultiplicity); // Mult.
    
    // Reaction type
    //        1: "Elas"
    //        2: "iso"
    //        3: "Trans"
    pR3bGen->SetReactionType("Elas");
    
    // Target  type
    //        1: "LeadTarget"
    //        2: "Parafin0Deg"
    //        3: "Parafin45Deg"
    //        4: "LiH"
    
    pR3bGen->SetTargetType(Target.Data());
    Double_t thickness = (0.11/2.)/10.;  // cm
    pR3bGen->SetTargetHalfThicknessPara(thickness); // cm
    pR3bGen->SetTargetThicknessLiH(3.5); // cm
    pR3bGen->SetTargetRadius(1.); // cm
    
    pR3bGen->SetSigmaXInEmittance(1.); //cm
    pR3bGen->SetSigmaXPrimeInEmittance(0.0001); //cm
    
    // Dump the User settings
    pR3bGen->PrintParameters();
    primGen->AddGenerator(pR3bGen);
  }
  
  if (fGenerator.CompareTo("p2p") == 0  ) {
    R3Bp2pGenerator* gen = new R3Bp2pGenerator(("/lustre/nyx/fairgsi/mwinkel/r3broot/input/p2p/build/" + InFile).Data());
    primGen->AddGenerator(gen);

#if 0
    // Coincident gammas
    R3BGammaGenerator *gammaGen = new R3BGammaGenerator();
    
    gammaGen->SetEnergyLevel(0, 0.);
    gammaGen->SetEnergyLevel(1, 3E-3);
    gammaGen->SetEnergyLevel(2, 4E-3);

    gammaGen->SetBranchingRatio(2, 1, 0.5);
    gammaGen->SetBranchingRatio(2, 0, 0.5);
    gammaGen->SetBranchingRatio(1, 0, 1.);

    gammaGen->SetInitialLevel(2);

    gammaGen->SetLorentzBoost(TVector3(0, 0, 0.777792));

    primGen->AddGenerator(gammaGen);
#endif
  }

  run->SetGenerator(primGen);
  
  
  //-------Set visualisation flag to true------------------------------------
  run->SetStoreTraj(fVis);
  

  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");

 
  // ----- Initialize CalifaHitFinder task (CrystalCal to Hit) ------------------------------------
  if(fCalifaHitFinder) {
    R3BCalifaCrystalCal2Hit* califaHF = new R3BCalifaCrystalCal2Hit();
    califaHF->SetClusteringAlgorithm(1,0);
    califaHF->SetDetectionThreshold(0.000050);//50 KeV
    califaHF->SetExperimentalResolution(6.);  //percent @ 1 MeV
    //califaHF->SetComponentResolution(.25);    //sigma = 0.5 MeV
    califaHF->SetPhoswichResolution(3.,5.);   //percent @ 1 MeV for LaBr and LaCl 
    califaHF->SelectGeometryVersion(17);
    califaHF->SetAngularWindow(0.25,0.25);      //[0.25 around 14.3 degrees, 3.2 for the complete calorimeter]
    run->AddTask(califaHF);
  }

  // ----- Initialize StarTrackHitfinder task ------------------------------------
  if(fStarTrackHitFinder) {
    R3BSTaRTraHitFinder* trackHF = new R3BSTaRTraHitFinder();
    //trackHF->SetClusteringAlgorithm(1,0);
    trackHF->SetDetectionThreshold(0.000050); //50 KeV
    trackHF->SetExperimentalResolution(0.);
    //trackHF->SetAngularWindow(0.15,0.15);      //[0.25 around 14.3 degrees, 3.2 for the complete calorimeter]
    run->AddTask(trackHF);
  }
  
	
  // -----   Initialize simulation run   ------------------------------------
  run->Init();

  // ------  Increase nb of step for CALO
  Int_t nSteps = 150000;
  TVirtualMC::GetMC()->SetMaxNStep(nSteps);
  
  
  // -----   Runtime database   ---------------------------------------------
  R3BFieldPar* fieldPar = (R3BFieldPar*) rtdb->getContainer("R3BFieldPar");
      fieldPar->SetParameters(magField);
      fieldPar->setChanged();
  Bool_t kParameterMerged = kTRUE;
  FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged);
  parOut->open(ParFile.Data());
  rtdb->setOutput(parOut);
  rtdb->saveOutput();
  rtdb->print();
  
  
  // -----   Start run   ----------------------------------------------------
  if(nEvents > 0) {
    run->Run(nEvents);
  }
  
  
  // -----   Finish   -------------------------------------------------------
  timer.Stop();
  Double_t rtime = timer.RealTime();
  Double_t ctime = timer.CpuTime();
  cout << endl << endl;
  cout << "Macro finished succesfully." << endl;
  cout << "Output file is "    << OutFile << endl;
  cout << "Parameter file is " << ParFile << endl;
  cout << "Real time " << rtime << " s, CPU time " << ctime
  << "s" << endl << endl;
  // ------------------------------------------------------------------------

  cout << " Test passed" << endl;
  cout << " All ok " << endl;

}
Ejemplo n.º 18
0
TVector3 TVector3::operator - (const TVector3& other) const
{
  return TVector3(i_[0] - other.i_[0], i_[1] - other.i_[1], i_[2] - other.i_[2]);
}
Ejemplo n.º 19
0
int main() 
{

	// -- Declaring Cuba variables -- //
	int comp, nregions, neval, fail;
	cubareal integral[NCOMP], error[NCOMP], prob[NCOMP];
	
	// -- ThreeBodyDecay initialization-- // 
	muon.SetMotherMPThetaPhi(M,muon_p,muon_theta,muon_phi);
	muon.SetBitBoostBack(BitBoostBack);

	// -- Set up pointers to the momenta
	P  = muon.P;
	p1 = muon.p[0];
	p2 = muon.p[1];
	p3 = muon.p[2];

	// -- Get muon kinematics
   double P_gamma  = P->Gamma();
   double P_beta   = P->Beta();
   double P_M      = P->M();
   double P_MomMag = P->P();

	// -- Polarization vector -- //
	// -- Custom vector construction
   k0_custom = TLorentzVector(1.0, 0.0, 0.0, 1.0);
   // k0_custom = TLorentzVector(3, 2, 0.0, 1.0);
   // k0_custom = TLorentzVector(1.0, 0.0, 0.0, 1.0);
	double alpha = 1;

	// -- Phyicsal vector construction
	k0_physical[3] = 1;
	for (int i = 0; i<3; i++)
	{ k0_physical[i] = (*P)[i]/P_MomMag; }

	for (int nu = 0; nu<4; nu++)
	{ k0_physical[nu] = alpha*k0_physical[nu]/(P_M*P_gamma*(1+P_beta)); }
	
	// -- Choosing k0 auxiliary vector
	if ( k0_flag == 1)
	{ k0 = k0_custom; }

	if ( k0_flag == 2)
	{ k0 = k0_physical; }

	// Get pk0 scalar product
	double Pk0 = P->Dot(k0);

	// Custom spin polarization vector with p and k0
	if (polvec_flag == 1)
	{
		for(int nu = 0; nu<4; nu++)
		{ polvec[nu] = ( (*P)[nu]/M) - (M/Pk0)*k0[nu]; }
	}

	// Helicity spin ampltiude vector
	// Note:
	// This should be equivalent to the custom pol. vector
	// when choosing physical k0
	// Default:
	if (polvec_flag == 2)
	{

		TVector3 phat(1.0,0.0,0.0);
		phat.SetPhi(phat_phi);
		phat.SetTheta(phat_theta);

		polvec = TLorentzVector(phat,P->Beta());

		for(int nu = 0; nu<4; nu++)
		{ polvec[nu] = polvec[nu]*P_gamma; }
	}

	phat34 = TVector3(1.0,0.0,0.0);
   phat34.SetPhi(phat34_phi);
   phat34.SetTheta(phat34_theta);
	polvec34 = TLorentzVector(phat34,0);



/////////////////////////////////////////////////////////////////////////

#if 1

  printf("-------------------- Vegas test --------------------\n");

  Vegas(NDIM, NCOMP, Integrand, USERDATA, NVEC,
    EPSREL, EPSABS, VERBOSE, SEED,
    MINEVAL, MAXEVAL, NSTART, NINCREASE, NBATCH,
    GRIDNO, STATEFILE, SPIN,
    &neval, &fail, integral, error, prob);

  printf("VEGAS RESULT:\tneval %d\tfail %d\n",
    neval, fail);
  comp = 0;
    printf("VEGAS RESULT:\t%.8f +- %.8f\tp = %.3f\n",
      (double)integral[comp], (double)error[comp], (double)prob[comp]);
#endif

#if 0
  printf("\n-------------------- Suave test --------------------\n");

  Suave(NDIM, NCOMP, Integrand, USERDATA, NVEC,
    EPSREL, EPSABS, VERBOSE | LAST, SEED,
    MINEVAL, MAXEVAL, NNEW, NMIN, FLATNESS,
    STATEFILE, SPIN,
    &nregions, &neval, &fail, integral, error, prob);

  printf("SUAVE RESULT:\tnregions %d\tneval %d\tfail %d\n",
    nregions, neval, fail);
  comp = 0;
    printf("SUAVE RESULT:\t%.8f +- %.8f\tp = %.3f\n",
      (double)integral[comp], (double)error[comp], (double)prob[comp]);
#endif

#if 0
  printf("\n------------------- Divonne test -------------------\n");

  Divonne(NDIM, NCOMP, Integrand, USERDATA, NVEC,
    EPSREL, EPSABS, VERBOSE, SEED,
    MINEVAL, MAXEVAL, KEY1, KEY2, KEY3, MAXPASS,
    BORDER, MAXCHISQ, MINDEVIATION,
    NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
    STATEFILE, SPIN,
    &nregions, &neval, &fail, integral, error, prob);

  printf("DIVONNE RESULT:\tnregions %d\tneval %d\tfail %d\n",
    nregions, neval, fail);
  for( comp = 0; comp < NCOMP; ++comp )
    printf("DIVONNE RESULT:\t%.8f +- %.8f\tp = %.3f\n",
      (double)integral[comp], (double)error[comp], (double)prob[comp]);
#endif

#if 0
  printf("\n-------------------- Cuhre test --------------------\n");

  Cuhre(NDIM, NCOMP, Integrand, USERDATA, NVEC,
    EPSREL, EPSABS, VERBOSE | LAST,
    MINEVAL, MAXEVAL, KEY,
    STATEFILE, SPIN,
    &nregions, &neval, &fail, integral, error, prob);

  printf("CUHRE RESULT:\tnregions %d\tneval %d\tfail %d\n",
    nregions, neval, fail);
  for( comp = 0; comp < NCOMP; ++comp )
    printf("CUHRE RESULT:\t%.8f +- %.8f\tp = %.3f\n",
      (double)integral[comp], (double)error[comp], (double)prob[comp]);
#endif

  double result = (double)integral[comp];

  // If result is unpolarized divide by 2.0
  if ( (ampltiude == 0) || (ampltiude == 34) )
  { result = result / 2.0;}

  double PSConst = muon.GetPSConst();
  double result_wogamma = result * PSConst * G_Fermi * G_Fermi / M / 2.0  ;
  result = result * PSConst * G_Fermi * G_Fermi / P->E() / 2.0 ;

  double ratio_formula = result/gamma_formula;
  double ratio_PDG = result/gamma_PDG;

  double  tau = hbar/result;
  double ctau = tau*c;

  double  tau_wogamma = hbar/result_wogamma;
  double ctau_wogamma = tau_wogamma*c;


  // -- Displaying info -- //

  printf("\n");
  printf("###############################################\n");
  printf("### --- Muon decay lifetime calculation --- ###\n");
  printf("###############################################\n");

  printf("\n");

  printf("--------------------------\n");
  printf("--- Physical constants ---\n");
  printf("--------------------------\n");

  printf("\n");
  printf("hbar:    %12.6e [GeV s]\n", hbar);
  printf("c:       %12.6e [m/s]\n", c);
  printf("hbar*c:  %12.6e [GeV fm]\n", hbar_c);
  printf("G_Fermi: %12.6e [GeV^{-2}]\n", G_Fermi);

  printf("\n");
  printf("Muon constants:\n");
  printf("m (muon):                  %12.6f [GeV]\n", M);
  printf("c_tau:                     %12.6e  [fm]\n", c_tau_muon);
  printf("Gamma(PDG) = hbarc/c_tau = %12.6e [GeV]\n", gamma_PDG);

  printf("\n");
  printf("Other masses:\n");
  printf("m (elec):       %12.6f [GeV]\n", m1);
  printf("m (nu_e):       %12.6f [GeV]\n", m2);
  printf("m (nu_m):       %12.6f [GeV]\n", m3);

  printf("\n");
  printf("-------------------------\n");
  printf("---   Decay process   ---\n");
  printf("-------------------------\n");

  printf("\n");
  printf("(muon)- ---> (electron)- (nu_mu) (nu_electronbar)\n");
  printf("  p     --->      q        k            k' \n");
  printf("  p     --->      q        k1           k2 \n");
  printf("  P     --->     p1        p2           p3 \n");
  printf("\n");

  printf("-------------------------\n");
  printf("---   Configuration   ---\n");
  printf("-------------------------\n");

  printf("\n");
  printf("############\n");
  printf("### Muon ###\n");
  printf("############\n");
  printf("\n");
  printf("|mom|:  %12.6f [GeV/c]\n", muon_p);
  printf("theta:  %12.6f [rad]\n", muon_theta);
  printf("phi:    %12.6f [rad]\n", muon_phi);
  printf("gamma:  %12.6f \n", P->Gamma());
  printf("beta:   %12.6f \n", P->Beta());
  printf("\n");
  printf("Momentum:\n");
  displayTLorentzVector(P);
  printf("\n");

  printf("Unitvector pointing in the direction of momentum:\n");
  printf("x: %12.6f\n", (*P)[0]/P->P());
  printf("y: %12.6f\n", (*P)[1]/P->P());
  printf("z: %12.6f\n", (*P)[1]/P->P());
  printf("\n");


  printf("################################\n");
  printf("### Spin Polarization vector ###\n");
  printf("################################\n");
  printf("### - Denoted by s^{mu}         \n");
  printf("\n");


  if ( (ampltiude == -1) || (ampltiude == 0) || (ampltiude == 1) )
  {

  if ( polvec_flag == 1 )
  {

   printf("polvec_flag: %d\n", polvec_flag);
  	printf("Spin polarization defined with auxiliary vector k0:\n");
  	printf("s^{mu} = P^{mu}/M - (m/Pk0)*k0^{mu}\n");
   printf("\n");

  	printf("k0_flag: %d\n", k0_flag);
   if ( k0_flag == 1 )
	{ printf("Custom k0:\n"); }

   if ( k0_flag == 2 )
	{ 
		printf("Choice of k0, yielding helicity polarization vector.\n");
		printf("Physical k0:\n");
	}

  	displayTLorentzVector(&k0);
  	printf("\n");

  }

  if ( polvec_flag == 2 )
  {
   printf("polvec_flag: %d\n", polvec_flag);
  	printf("Spin polarization vector = helicity polarization vector\n");
 	printf("s^{mu} = ( |pvec|^2 , p0 pvec) / (m |pvec|)) = \n");
 	printf("       = gamma (beta,phat vector)\n");
   printf("\n");
  }

  printf("Spin polarization vector components:\n");
  displayTLorentzVector(&polvec);

  }

  if ( (ampltiude == 3) || (ampltiude == 4) || (ampltiude == 34) )
  {
  	 printf("Spin polarization vector defined in rest frame of the muon\n");
  	 printf("s^{mu} = (0,phat34)\n");

   printf("\n");
  	 printf("where the phat34 is pointing towards:\n");
  	 printf("phat34 theta: %12.6f\n", phat34_theta);
  	 printf("phat34 phi:   %12.6f\n", phat34_phi);

   printf("\n");
  	 printf("phat34 components:\n");
  	 printf("x: %12.6f\n", phat34[0]);
  	 printf("y: %12.6f\n", phat34[1]);
  	 printf("z: %12.6f\n", phat34[2]);

  }

  printf("\n");
  printf("--------------------------\n");
  printf("--- Consistency checks ---\n");
  printf("--------------------------\n");

  printf("\n");
  printf("- Lorentz scalar product (ps) = 0 (orthogonality check)\n");
  printf("(ps): %12.6e     (should give really small value)\n", (*P)*polvec);

  printf("\n");
  printf("- k0^{2} = 0 (massless auxuliary vector)\n");
  printf("(k0)^2: %12.6e     (should give really small value)\n", k0.M2());


  printf("\n");
  printf("------------------\n");
  printf("--- Ampltidude ---\n");
  printf("------------------\n");

  printf("\n");
  printf("Amplitude formula chosen: --->  %d  <--- \n", ampltiude);
  printf("\n");

  printf("Amplitude formula list:\n");
  printf("(No):  ---------------------- Formula ---------------------------- (polarization)\n");
  printf("- Default case:                              \n");
  printf(" (0): 128 * (p k') * (q k)                                         (unpolarized)\n");
  printf("(-1):  64 * (p k') * (q k) + 64 * M * (s k') * (q k)               (polarized)\n");
  printf("(+1):  64 * (p k') * (q k) - 64 * M * (s k') * (q k)               (polarized)\n");

  printf("- Custom:                              \n");
  printf(" (+3): 64 * gamma * ( 1 - beta ) *     (M * (k')^{0}) * (q k) -    (polarized)\n");
  printf("      -64 * gamma * ( 1 - beta ) * M *    (s k')      * (q k)                 \n");
  printf(" (+4): 64 * gamma * ( 1 + beta ) *     (M * (k')^{0}) * (q k) +    (polarized)\n");
  printf("      +64 * gamma * ( 1 + beta ) * M *    (s k')      * (q k)                 \n");
  printf("(+34): sum of (+3) and (+4)                                        (unpolarized)\n");

  printf("\n");
  printf("Notations:\n");
  printf("(muon)- ---> (electron)- (nu_mu) (nu_electronbar)\n");
  printf("  p     --->      q        k            k' \n");
  printf("  p     --->      q        k1           k2 \n");
  printf("  P     --->     p1        p2           p3 \n");
  printf("\n");

  printf("Leftover factors multiplying the result:\n");
  printf("- Coupling constant\n");
  printf("  G_Fermi^{2}\n");

  printf("- Initial particle state normalization:\n");
  printf("  1.0/(2*E) = 1.0/2*M (in the rest frame)\n");

  printf("- Spin averaging for the muon (only if unpolarized):\n");
  printf("  1.0/2.0\n");

  printf("\n");
  printf("ThreeBodyDecay class\n");
  printf("PSConstant (formula)  s23_length/pow(M_PI,3.0)/128.0\n");
  printf("PSConstant  (numval): %12.6e \n", PSConst);

  printf("\n");
  printf("---------------------------\n");
  printf("--- Other formulas used ---\n");
  printf("---------------------------\n");

  printf("\n");
  printf("Textbook result of the integration:\n");
  printf("Gamma: G_Fermi^{2}*m_mu^{5}/(192*pi^{3})\n");

  printf("\n");
  printf("tau  = hbar/Gamma\n");
  printf("ctau = c*tau\n");
  
  printf("\n");
  printf("-------------------------\n");
  printf("--- Numerical results ---\n");
  printf("-------------------------\n");

  printf("Don't forget: our result are quoted in the LAB frame, while the PDG and\n");
  printf("              the textbook formula are calculated in the muon rest frame!\n");
  printf("\n");

  printf("# Important flags:\n", ampltiude);
  printf("- k0_type:                    %d (see above at 'Spin polarization', 1 = custom, 2 = physical)\n", k0_flag);
  printf("- spin_polarization:          %d (see above at 'Spin polarization', 1 = computed with k0, 2 = helicity)\n", polvec_flag);
  printf("- Amplitude formula chosen:   %d (see above at 'Amplitude' )\n", ampltiude);
  printf("\n");
  printf("Note: Choosing (k0_type = 2) and (spin_polarization = 1) should give the same result as\n");
  printf("      choosing (spin_polarization = 2) by definition\n");
  printf("\n");

  printf("Gamma(PDG):                             %12.6e [GeV] (note: this is the total gamma!)\n", gamma_PDG);
  printf("Gamma(textbook):                        %12.6e [GeV]\n", gamma_formula);
  printf("Gamma(our result w/o gamma factor):     %12.6e [GeV]\n", result_wogamma);
  printf("Gamma(our result):                      %12.6e [GeV]\n", result);

  printf("\n");
  printf("ctau(PDG):                              %12.6e [m]\n", c_tau_muon*1e-15);
  printf("ctau(textbook):                         %12.6e [m]\n", ctau_formula*1e-15);
  printf("ctau(our result w/o gamma factor):      %12.6e [m]\n", ctau_wogamma);
  printf("ctau(our result):                       %12.6e [m]\n", ctau);
  printf("\n");
  printf("# Muon configuration\n");
  printf("beta:                                                %12.6f\n", P->Beta());
  printf("gamma:                                               %12.6f <-\n", P->Gamma());

  printf("\n");
  printf("# Ratios\n");
  printf("ratio of ctau's: (our result)/(textbook rest frame)  %12.6f <-\n", ctau/ctau_formula/1e-15);
  printf("ratio of the above two values:                       %12.6f\n", P->Gamma()/(ctau/ctau_formula/1e-15));
  printf("\n");
  printf("Note: You should compare the values of 'gamma' with the 'ratio of ctau's',\n");
  printf("      as they should be equal.\n");
  printf("      The 'ratio of the above two values' gives a measure how well they agree.\n");
  printf("      It should be close to unity, but there could be some tiny deviation as\n");
  printf("      this is after all a numerical integration.\n");

  printf("\n");
  printf("VEGAS RESULT:\t%.8f +- %.8f\tp = %.3f\n",
    (double)integral[comp], (double)error[comp], (double)prob[comp]);


  return 0;

}
Ejemplo n.º 20
0
DGLE_RESULT DGLE_API CMesh::RecalculateNormals(bool bInvert)
{
	if (!_pBuffer)
		return S_FALSE;

	TDrawDataDesc desc;
	uint stride, verts_data_size, verts_count, idxs_data_size, idxs_count;
	_CopyMeshData(desc, stride, verts_data_size, verts_count, idxs_data_size, idxs_count);

	TDrawDataDesc desc_new(desc);
	bool do_delete_new = false;

	if (desc.uiNormalOffset == -1)
	{
		do_delete_new = true;

		const uint new_verts_data_size = verts_data_size + verts_count * 3 * sizeof(float);
		desc_new.pData = new uint8[new_verts_data_size + idxs_data_size];
		memcpy(desc_new.pData, desc.pData, verts_data_size);

		desc_new.uiNormalOffset = verts_data_size;
		desc_new.uiNormalStride = 0;

		if (idxs_count != 0)
		{
			desc_new.pIndexBuffer = &desc_new.pData[new_verts_data_size];
			memcpy(&desc_new.pData[new_verts_data_size], &desc.pData[verts_data_size], idxs_data_size);
		}

		memset(&desc_new.pData[verts_data_size], 0, new_verts_data_size - verts_data_size);
	}
	else
	{
		const uint stride = desc_new.uiNormalStride == 0 ? 3 * sizeof(float) : desc_new.uiNormalStride;

		for (uint i = 0; i < verts_count; ++i)
			*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + i * stride])) = TVector3();
	}

	const uint n_stride = desc_new.uiNormalStride == 0 ? 3 * sizeof(float) : desc_new.uiNormalStride,
		v_stride = desc_new.uiVertexStride == 0 ? 3 * sizeof(float) : desc_new.uiVertexStride,
		count = idxs_count == 0 ? verts_count / 3 : idxs_count / 3;

	for(uint i = 0; i < count; ++i)
	{
		uint face[3];

		if (idxs_count == 0)
		{
			face[0] = i * 3;
			face[1] = i * 3 + 1;
			face[2] = i * 3 + 2;
		}
		else
			if (desc_new.bIndexBuffer32)
			{
				face[0] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[0];
				face[1] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[1];
				face[2] = reinterpret_cast<uint *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint)])[2];
			}
			else
			{
				face[0] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[0];
				face[1] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[1];
				face[2] = reinterpret_cast<uint16 *>(&desc_new.pIndexBuffer[i * 3 * sizeof(uint16)])[2];
			}

		const TPoint3 * const v[3] = {
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[0] * v_stride]),
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[1] * v_stride]),
			reinterpret_cast<TPoint3 *>(&desc_new.pData[face[2] * v_stride])};

		const TVector3 faset_normal = ((*v[0] - *v[1]).Cross(*v[1] - *v[2])).Normalize() * (bInvert ? -1.f : 1.f);

		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + face[0] * n_stride])) += faset_normal;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + face[1] * n_stride])) += faset_normal;
		*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + face[2] * n_stride])) += faset_normal;
	}

	for (uint i = 0; i < verts_count; ++i)
		(*(reinterpret_cast<TVector3 *>(&desc_new.pData[desc_new.uiNormalOffset + i * n_stride]))).Normalize();

	PARANOIC_CHECK_RES(_pBuffer->Reallocate(desc_new, verts_count, idxs_count, CRDM_TRIANGLES));

	if (do_delete_new)
		delete[] desc_new.pData;

	delete[] desc.pData;

	return S_OK;
}
Ejemplo n.º 21
0
void glxlut_avr(TString baseFile = "../data/lut100000.root"){
  gROOT->ProcessLine(".L ../src/GlxLutNode.cxx+");
  gInterpreter->GenerateDictionary("vector<TVector3>","TVector3.h"); 
  
  TString inFile =baseFile;
  TString outFile = baseFile.Remove(baseFile.Last('.'))+"_avr.root";

  TFile* f = new TFile(inFile);
  TTree *t=(TTree *) f->Get("glxlut") ;
  TClonesArray* fLut[48];
  for(Int_t l=0; l<48; l++){
    fLut[l] = new TClonesArray("GlxLutNode");
    t->SetBranchAddress(Form("LUT_%d",l),&fLut[l]); 
  }

 
  TFile *fFileNew = TFile::Open(outFile, "RECREATE");
  TClonesArray *fLutNew[48];

  TTree *fTreeNew = new TTree("glxlut","Look-up table for DIRC. Averaged");

  Int_t Nnodes = 20000;
  for(Int_t l=0; l<48; l++){
    fLutNew[l] = new TClonesArray("GlxLutNode");
    fTreeNew->Branch(Form("LUT_%d",l),&fLutNew[l],256000,2);
    TClonesArray &fLutaNew = *fLutNew[l];
    for (Long64_t n=0; n<Nnodes; n++) {
      new((fLutaNew)[n]) GlxLutNode(-1);
    }
  }

  // TCanvas* c = new TCanvas("c","c",0,0,800,1200); c->Divide(1,2);
  // TH1F * histNode = new TH1F("LutNode","Node vs Multiplicity",30000,0,150000);
  // TH1F * hTime = new TH1F("hTime","Time",5000,0,10);
  // TH1F * hDir = new TH1F("hDir","X component",1000,-1,1);


  std::vector<TVector3> vArray[100];
  std::vector<Double_t> tArray[100];
  std::vector<Double_t> pArray;
  
  TVector3 dir, dir2, sum;
  Double_t angle, minangle,pathid,time,sumt;
  GlxLutNode *node;

  for(Int_t l=0; l<48; l++){
    t->GetEntry(l);
    for (Int_t inode=0; inode<fLut[l]->GetEntriesFast(); inode++){
      if(inode%1000==0) cout<<"Node # "<<inode << "  L "<<l<<endl;
      node= (GlxLutNode*) fLut[l]->At(inode);
      //histNode->Fill(node->GetNodeId(),node->Entries());
      Int_t size = node->Entries();    
      if(size<1) continue;
      for(int i=0; i<size; i++){
	dir = node->GetEntry(i);
	time = node->GetTime(i);
	pathid = node->GetPathId(i);
      
	// hDir->Fill(dir.X());
	// hTime->Fill(time);

	bool newid = true;
	for(int j=0; j<pArray.size(); j++){
	  if(pathid == pArray[j]){
	    vArray[j].push_back(dir);
	    tArray[j].push_back(time);
	    newid= false;
	  }
	}
	if(newid) {
	  vArray[pArray.size()].push_back(dir);
	  tArray[pArray.size()].push_back(time);
	  pArray.push_back(pathid);
	}
      }
  
      for(int j=0; j<pArray.size(); j++){
	sum = TVector3(0,0,0);
	sumt=0;
	for(int v=0; v<vArray[j].size(); v++) {
	  sum += vArray[j][v]; 
	  sumt += tArray[j][v]; 

	  // hDir->Fill(vArray[j][v].X());
	  // hTime->Fill(tArray[j][v]);
	}
      
	// c->cd(1);
	// hTime->Draw();
	// c->cd(2);
	// hDir->Draw();
	// c->Update();  
	// c->WaitPrimitive();
	// hDir->Reset();
	// hTime->Reset();

	if(vArray[j].size()<1) continue;
	Double_t weight = 1/(Double_t)vArray[j].size(); 
	sum *= weight;
	sumt *= weight;
      
	((GlxLutNode*)(fLutNew[l]->At(inode)))->AddEntry(node->GetDetectorId(), sum,j,node->GetNRefl(0),sumt, node->GetDigiPos(),node->GetDigiPos(),vArray[j].size()/(Double_t)size); 
      }
      for(int i=0; i<100; i++) {vArray[i].clear();  tArray[i].clear();}
      pArray.clear();
    }
  }

  fTreeNew->Fill();
  fTreeNew->Write();
  //fFileNew->Write();

}
Ejemplo n.º 22
0
namespace Position
{
  /* DocDb 7560 */
  static const TVector3 Ad[8] =
    { TVector3( 363.0177, 49.1021 , -70.8146 ),
      TVector3( 359.0053, 53.5544 , -70.8107 ),
      TVector3( 4.4758  , -873.507, -67.5209 ),
      TVector3( 931.5798, -1422.41, -66.4819 ),
      TVector3( 936.294 , -1418.72, -66.4935 ),
      TVector3( 935.2752, -1427.15, -66.4933 ),
      TVector3( 0, 0, 0 ),   // unknown                                                     
      TVector3( 0, 0, 0 ),   // unknown                                                     
    };

  static const TVector3 Rct[6] =
    { TVector3( 360.6984, 410.1788, -40.2281 ),
      TVector3( 449.4947, 409.3679, -40.2367 ),
      TVector3( -321.63 , -539.583, -39.7268 ),
      TVector3( -268.767, -468.232, -39.7202 ),
      TVector3( -546.752, -952.721, -39.7959 ),
      TVector3( -493.898, -881.363, -39.7857 ),
    };
}
Ejemplo n.º 23
0
TVector3 TVector3::operator - (const Vec3f& other) const
{
  return TVector3(i_[0] - other[0], i_[1] - other[1], i_[2] - other[2]);
}
Ejemplo n.º 24
0
TVector3 Sputnik::PStar( double M, double m1, double m2, double th, double ph )
{
    double P = 0.5*sqrt((pow(M,2)-pow(m1-m2,2))*(pow(M,2)-pow(m1+m2,2)))/M;
    return TVector3( sin(th)*cos(ph)*P, sin(th)*sin(ph)*P, cos(th)*P );
}
Ejemplo n.º 25
0
DGLE_RESULT DGLE_API CBitmapFont::Draw2D(float fX, float fY, const char *pcTxt, const TColor4 &stColor, float fAngle, bool bVerticesColors)
{
	uint length = strlen(pcTxt);

	if (length == 0)
		return S_FALSE;

	bool b_need_update;

	_pRender2D->NeedToUpdateBatchData(b_need_update);

	if (!b_need_update)
	{
		_pRender2D->Draw(_pTex, TDrawDataDesc(), CRDM_TRIANGLES, length * 6, TRectF(), (E_EFFECT2D_FLAGS)((_bForceAlphaTest2D ? EF_ALPHA_TEST : EF_BLEND) | (bVerticesColors ? EF_DEFAULT : EF_COLOR_MIX)));
		return S_OK;
	}

	uint width, height;
	
	GetTextDimensions(pcTxt, width, height);
	
	float quad[] = {fX, fY, fX + (float)width, fY, fX + (float)width, fY + (float)height, fX, fY + (float)height};
	
	TMatrix4 transform;

	if (fAngle != 0.f)
	{
		TMatrix4 rot = MatrixIdentity();
		
		const float s = sinf(-fAngle * (float)M_PI/180.f), c = cosf(-fAngle * (float)M_PI/180.f);

		rot._2D[0][0] = c;
		rot._2D[0][1] = -s;
		rot._2D[1][0] = s;
		rot._2D[1][1] = c;

		transform = MatrixTranslate(TVector3(-(fX + width / 2.f), -(fY + height / 2.f), 0.f)) * rot * MatrixTranslate(TVector3(fX + width / 2.f, fY + height / 2.f, 0.f));

		float x = quad[0], y = quad[1];
		quad[0]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
		quad[1]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

		 x = quad[2]; y = quad[3];
		quad[2]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
		quad[3]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

		x = quad[4]; y = quad[5];
		quad[4]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
		quad[5]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

		x = quad[6]; y = quad[7];
		quad[6]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
		quad[7]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];
	}

	if (!_pRender2D->BBoxInScreen(quad, fAngle != 0.f))
		return S_OK;

	float xoffset = 0.f;
	uint t_w, t_h;
	
	_pTex->GetDimensions(t_w, t_h);

	TColor4 prev_color, verts_colors[4];
	
	_pRender2D->GetColorMix(prev_color);
	_pRender2D->SetColorMix(stColor);

	if (bVerticesColors)
		_pRender2D->GetVerticesColors(verts_colors[0], verts_colors[1], verts_colors[2], verts_colors[3]);

	uint size = length * 12 * 2;

	if (bVerticesColors)
		size = length * 24 * 2;

	if (_uiBufferSize < size)
	{
		_uiBufferSize = size;
		delete[] _pBuffer;
		_pBuffer = new float[_uiBufferSize];
	}

	for (uint i = 0; i < length; ++i)
	{
		const uchar ch = static_cast<const uchar>(pcTxt[i]) - 32;
		
		const int
			&curb_x = _astChars[ch].x,
			&curb_y = _astChars[ch].y,
			&curb_w = _astChars[ch].w,
			&curb_h = _astChars[ch].h;
		
		const uint idx = i * 24;

		_pBuffer[idx] = fX + xoffset; _pBuffer[idx + 1] = fY; _pBuffer[idx + 2] = (float)curb_x / (float)t_w; _pBuffer[idx + 3] = (float)curb_y / (float)t_h;
		_pBuffer[idx + 4] = fX + xoffset + (float)curb_w * _fScale; _pBuffer[idx + 5] = fY; _pBuffer[idx + 6] = (float)(curb_x + curb_w) / (float)t_w; _pBuffer[idx + 7] = (float)curb_y / (float)t_h;
		_pBuffer[idx + 8] = fX + xoffset + (float)curb_w * _fScale; _pBuffer[idx + 9] = fY + (float)curb_h * _fScale; _pBuffer[idx + 10] = (float)(curb_x + curb_w) / (float)t_w; _pBuffer[idx + 11] = (float)(curb_y + curb_h) / (float)t_h;
		_pBuffer[idx + 12] = _pBuffer[idx]; _pBuffer[idx + 13] = _pBuffer[idx + 1]; _pBuffer[idx + 14] = _pBuffer[idx + 2]; _pBuffer[idx + 15] = _pBuffer[idx + 3];
		_pBuffer[idx + 16] = _pBuffer[idx + 8]; _pBuffer[idx + 17] = _pBuffer[idx + 9]; _pBuffer[idx + 18] = _pBuffer[idx + 10]; _pBuffer[idx + 19] = _pBuffer[idx + 11];
		_pBuffer[idx + 20] = fX + xoffset; _pBuffer[idx + 21] = fY + (float)curb_h * _fScale; _pBuffer[idx + 22] = (float)curb_x / (float)t_w; _pBuffer[idx + 23] = (float)(curb_y + curb_h) / (float)t_h;

		if (fAngle != 0.f)
		{
			float x = _pBuffer[idx], y = _pBuffer[idx + 1];
			_pBuffer[idx]		= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
			_pBuffer[idx + 1]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

			 x = _pBuffer[idx + 4]; y = _pBuffer[idx + 5];
			_pBuffer[idx + 4]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
			_pBuffer[idx + 5]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

			x = _pBuffer[idx + 8]; y = _pBuffer[idx + 9];
			_pBuffer[idx + 8]	= transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
			_pBuffer[idx + 9]	= transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

			x = _pBuffer[idx + 20]; y = _pBuffer[idx + 21];
			_pBuffer[idx + 20] = transform._2D[0][0] * x + transform._2D[1][0] * y + transform._2D[3][0];
			_pBuffer[idx + 21] = transform._2D[0][1] * x + transform._2D[1][1] * y + transform._2D[3][1];

			_pBuffer[idx + 12] = _pBuffer[idx]; _pBuffer[idx + 13] = _pBuffer[idx + 1];
			_pBuffer[idx + 16] = _pBuffer[idx + 8]; _pBuffer[idx + 17] = _pBuffer[idx + 9];
		}

		if (bVerticesColors)
		{
			const uint idx = length * 24 + i * 24;
			memcpy(&_pBuffer[idx], verts_colors[0], 12 * sizeof(float));
			memcpy(&_pBuffer[idx + 12], verts_colors[0], 4 * sizeof(float));
			memcpy(&_pBuffer[idx + 16], verts_colors[2], 8 * sizeof(float));
		}

		xoffset += (float)curb_w * _fScale;
	}

	TDrawDataDesc desc;

	desc.pData = (uint8*)_pBuffer;
	desc.uiVertexStride = 4 * sizeof(float);
	desc.bVertices2D = true;
	desc.uiTextureVertexOffset = 2 * sizeof(float);
	desc.uiTextureVertexStride = desc.uiVertexStride;

	if (bVerticesColors)
		desc.uiColorOffset = length * 24 * sizeof(float);

	_pRender2D->Draw(_pTex, desc, CRDM_TRIANGLES, length*6, TRectF(), (E_EFFECT2D_FLAGS)((_bForceAlphaTest2D ? EF_ALPHA_TEST : EF_BLEND) | (bVerticesColors ? EF_DEFAULT : EF_COLOR_MIX)));

	_pRender2D->SetColorMix(prev_color);

	return S_OK;
}