int VMobileForwardRenderLoop::GetLightInfluenceArea(VisLightSource_cl *pLight)
{
  VASSERT(pLight != NULL);

  VisRenderContext_cl *pContext = VisRenderContext_cl::GetCurrentContext();
  int iScreenWidth,iScreenHeight;
  pContext->GetSize(iScreenWidth, iScreenHeight);
  if (pLight->GetType() == VIS_LIGHT_DIRECTED)
  {
    // directional lights influence the whole screen
    return (iScreenWidth*iScreenHeight); 
  }

  hkvMat4 projMatrix = pContext->GetViewProperties()->getProjectionMatrix(hkvClipSpaceYRange::MinusOneToOne);
  hkvMat4 viewMatrix = pContext->GetCamera()->GetWorldToCameraTransformation();

  // get position/ radius of bounding sphere
  hkvVec3 vPosition;
  float fRadius = 0.0f;
  if (pLight->GetType() == VIS_LIGHT_POINT)
  {
    vPosition = pLight->GetPosition();
    fRadius = pLight->GetRadius();
  }
  else if (pLight->GetType() == VIS_LIGHT_SPOTLIGHT)
  {
    hkvAlignedBBox bBox;
    pLight->GetBoundingBox(bBox);
    vPosition = bBox.getBoundingSphere().m_vCenter;
    fRadius = bBox.getBoundingSphere().m_fRadius;
  }
  else
    VASSERT_MSG(false, "Unsupported light type"); 
  
  // get corners of bounding rectangle in view space
  hkvVec4 vPositionVS = viewMatrix*vPosition.getAsVec4(1.0f);
  hkvVec4 vCorners[4];
  vCorners[0] = vPositionVS+hkvVec4(-fRadius, -fRadius, 0.0f, 0.0f);
  vCorners[1] = vPositionVS+hkvVec4(fRadius, -fRadius, 0.0f, 0.0f);
  vCorners[2] = vPositionVS+hkvVec4(fRadius, fRadius, 0.0f, 0.0f);
  vCorners[3] = vPositionVS+hkvVec4(-fRadius, fRadius, 0.0f, 0.0f); 

  // get corners of bounding rectangle in normalized device coordinates
  for (int i=0;i<4;i++)
  {
    vCorners[i] = projMatrix*vCorners[i];
    vCorners[i] /= vCorners[i].w;
  }

  // clip corners of bounding rectangle
  hkvVec2 vMin(vCorners[0].x, vCorners[0].y); 
  vMin.clampTo(hkvVec2(-1.0f, -1.0f), hkvVec2(1.0f, 1.0f));
  hkvVec2 vMax(vCorners[2].x, vCorners[2].y); 
  vMax.clampTo(hkvVec2(-1.0f, -1.0f), hkvVec2(1.0f, 1.0f));

  // calculate influence area 
  int iWidth = (int)((vMax.x-vMin.x)*0.5f*iScreenWidth);
  int iHeight = (int)((vMax.y-vMin.y)*0.5f*iScreenHeight);
  return (iWidth*iHeight);
}
Ejemplo n.º 2
0
    void BoundingVolume::GetSplitAxis(const float *pointsPtr, unsigned int numPoints, 
		Float3 &splitAxis, float &_min, float &_max)
    {
        Float3 vMin( FLT_MAX, FLT_MAX, FLT_MAX );
        Float3 vMax( -FLT_MAX, -FLT_MAX, -FLT_MAX );

        for(unsigned int i = 0; i < numPoints; i +=3 )
            for(unsigned int j = 0; j < 3; ++j)
            {
                vMin.v[j] = min( vMin.v[j], pointsPtr[i+j] );
                vMax.v[j] = max( vMax.v[j], pointsPtr[i+j] );
            }

            unsigned int axis = 0;
            if( vMax.v[axis] - vMin.v[axis] < vMax.v[1] - vMin.v[1] )
                axis = 1;
            if( vMax.v[axis] - vMin.v[axis] < vMax.v[2] - vMin.v[2] )
                axis = 2;

            splitAxis.makeZero();
            splitAxis.v[axis] = 1.0f;

            _min = vMin.v[axis];
            _max = vMax.v[axis];
    }
Ejemplo n.º 3
0
void SetupDispBoxes( const CCoreDispInfo *pListBase, int listSize, CUtlVector<CDispBox> &out )
{
	out.SetSize( listSize );
	for ( int i=0; i < listSize; i++ )
	{
		const CCoreDispInfo *pDisp = &pListBase[i];

		// Calculate the bbox for this displacement.
		Vector vMin(  1e24,  1e24,  1e24 );
		Vector vMax( -1e24, -1e24, -1e24 );

		for ( int iVert=0; iVert < 4; iVert++ )
		{
			const Vector &vTest = pDisp->GetSurface()->GetPoint( iVert );
			VectorMin( vTest, vMin, vMin );
			VectorMax( vTest, vMax, vMax );
		}		

		// Puff the box out a little.
		static float flPuff = 0.1f;
		vMin -= Vector( flPuff, flPuff, flPuff );
		vMax += Vector( flPuff, flPuff, flPuff );

		out[i].m_Min = vMin;
		out[i].m_Max = vMax;
	}
}
Ejemplo n.º 4
0
void CPlayerCamera::Update( const FLOAT fFrameTime, BOOL bIsCurrent )
{
	VECTOR vSize = GetGameEngine()->GetView()->GetViewSize();
	vSize = vSize;

	VECTOR vMin( 999999.9f, 999999.9f );
	VECTOR vMax( -999999.9f, -999999.9f );
	VECTOR vAvgPos( 0.0f, 0.0f );
	UINT uCnt = 0;
	std::list<CActor*>::iterator it;
	for ( it = m_Actors.begin() ; it != m_Actors.end(); it++ )
	{
		if ( !(*it)->IsDead() )
		{
			VECTOR vPos = (*it)->GetPosition();
			vAvgPos += vPos;
			uCnt++;

			vMin.x = Math::Min( vMin.x, vPos.x );
			vMin.y = Math::Min( vMin.y, vPos.y );
			vMax.x = Math::Max( vMax.x, vPos.x );
			vMax.y = Math::Max( vMax.y, vPos.y );
		}
	}
	if ( uCnt > 0 )
	{
		vAvgPos = vAvgPos / (FLOAT)uCnt;

		VECTOR vBox = vMax - vMin;
		vBox *= 0.5f;
		FLOAT fScale = Math::Abs( Math::Max( vBox.x / vSize.x, vBox.y / vSize.y ) ) / 0.8f;
		if ( fScale > 1.0f )
		{
			fScale = Math::Min( fScale, MAX_ZOOM );
			m_fZoom = fScale;
		}
		else
		{
			m_fZoom = 1.0f ;
		}


	}
	else
	{
		vAvgPos = m_vLastPosition;
	}


	m_vLastPosition = vAvgPos;

	m_vScroll = vAvgPos - vSize;
	m_vScroll += m_vOffset;
}
Ejemplo n.º 5
0
IFXRESULT CIFXMesh::CalcBoundingSphere()
{
	IFXVector4 vMin(FLT_MAX, FLT_MAX, FLT_MAX, 0);
	IFXVector4 vMax(-FLT_MAX,-FLT_MAX,-FLT_MAX, 0);

	// Determine the axis aligned bounding box and the number of verticies.
	IFXVector3* vertex;
	IFXVector3Iter vIter;
	GetPositionIter(vIter);
	U32 i;
	for(  i = m_uNumVertices; i--; )
	{
		vertex = vIter.Next();
		if ( vertex->X() < vMin.R() ) vMin.R() = vertex->X();
		if ( vertex->X() > vMax.R() ) vMax.R() = vertex->X();
		if ( vertex->Y() < vMin.G() ) vMin.G() = vertex->Y();
		if ( vertex->Y() > vMax.G() ) vMax.G() = vertex->Y();
		if ( vertex->Z() < vMin.B() ) vMin.B() = vertex->Z();
		if ( vertex->Z() > vMax.B() ) vMax.B() = vertex->Z();
	}

	// If there are any verticies, find the average position as the center,
	// and the distance to the furthest point as the radius.
	if ( m_uNumVertices )
	{
		vMin.Add(vMax);
		vMin.Scale3(0.5f);
		m_vBoundingSphere = vMin;
		F32 fMaxSquaredDistance = -FLT_MAX;
		F32 fSquaredDistance;
		IFXVector3 d;
		GetPositionIter(vIter);
		U32 i;
		for(  i = m_uNumVertices; i--; )
		{
			vertex = vIter.Next();
			d.X() = vertex->X() - m_vBoundingSphere.R();
			d.Y() = vertex->Y() - m_vBoundingSphere.G();
			d.Z() = vertex->Z() - m_vBoundingSphere.B();
			fSquaredDistance = d.DotProduct(d);
			if ( fSquaredDistance > fMaxSquaredDistance )
				fMaxSquaredDistance = fSquaredDistance;
		}
		m_vBoundingSphere.A() = sqrtf( fMaxSquaredDistance );
	}
	else
		m_vBoundingSphere.Set( 0.0, 0.0, 0.0, 0.0 );

	return IFX_OK;
}
Ejemplo n.º 6
0
/////////////////////////////////////////////////////////////////////////////
// Write data files for plotting 1D distribution
/////////////////////////////////////////////////////////////////////////////
void CQLRIO::Distrib(CRegression &reg, const std::string &sPrefix)
{
 {
  std::ostringstream oss;
  oss << sPrefix << "MAP.dat";
  std::ofstream ofs(oss.str().c_str());
  CQLRIO::Plot(ofs, reg.GetPF(), reg.MAP());
 }

 {
  std::ostringstream ossRandom;
  ossRandom << sPrefix << "random.dat";
  std::ofstream ofs(ossRandom.str().c_str());

  std::ostringstream ossMax;
  ossMax << sPrefix << "max.dat";
  std::ofstream ofsMax(ossMax.str().c_str());

  CRandom<unsigned> rnd;

  const int PosteriorSamples = 50;

  for (int i = PosteriorSamples; --i >= 0;)
  {
   std::vector<double> vParam(reg.GetPF().GetParameters());
//   reg.GaussianSample(rnd, vParam);
   reg.MCMCSample(rnd, vParam, 20);

   if (reg.GetPF().GetDimensions() <= 1 || i < 5)
   {
    CQLRIO::Plot(ofs, reg.GetPF(), &vParam[0]);
    ofs << '\n';
   }

   std::vector<double> vMax(reg.GetPF().GetDimensions());
   if (reg.GetPF().GetMax(&vParam[0], &vMax[0]))
   {
    for (unsigned j = 0; j < vMax.size(); j++)
     ofsMax << std::setw(13) << vMax[j];
    ofsMax << std::setw(13) << reg.GetPF().GetValue(&vParam[0], &vMax[0]);
    ofsMax << '\n';
   }
  }
 }
}
Ejemplo n.º 7
0
VOID CCharactor::Load( WCHAR* a_pFileName )
{
	// 바운드 박스 파일에서 읽기로 수정.
	D3DXVECTOR3 vMin( 99999.0f,  99999.0f,  99999.0f);
	D3DXVECTOR3 vMax(-99999.0f, -99999.0f, -99999.0f);
	m_pBoundBox = new CBoundBox(this);
	m_pBoundBox->Create();
	m_pModel->SetCharType( m_pBoundBox );

	FILE* pFile;

	pFile = _wfopen( a_pFileName, L"r" );

	if( NULL == pFile )
	{
		MessageBox(GHWND, L"File Load Error", a_pFileName, MB_OK);
		return;
	}

	fseek( pFile, 0L, SEEK_SET );

	INT iTemp;
	WCHAR szTemp[255];
	fwscanf( pFile, L"%d", &iTemp );
	fwscanf( pFile, L"%s", szTemp );
	
	//m_pOctTree->Build( iTemp );
	FLOAT fSize = 0.5f * iTemp;
	FLOAT fBBSize[2][3];
	fBBSize[0][0] = fBBSize[0][1] = fBBSize[0][2] = 0.0f;	// MIN
	fBBSize[1][0] = fBBSize[1][1] = fBBSize[1][2] = 0.0f;	// MAX

	// 버텍스, 인덱스 버퍼 생성
	if( FAILED( m_pD3dDevice->CreateVertexBuffer( CCube::CUBEVERTEX::VertexNum * sizeof( CCube::CUBEVERTEX ),
		0, CCube::CUBEVERTEX::FVF, D3DPOOL_MANAGED, &m_pTotalVB, NULL ) ) )
	{
		MessageBox(GHWND, L"Vertex Buffer Failed", NULL, MB_OK);
	}

	if( FAILED( m_pD3dDevice->CreateIndexBuffer( CCube::CUBEINDEX::IndexNum * sizeof( CCube::CUBEINDEX ), 
		0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pTotalIB, NULL ) ) )
	{
		MessageBox(GHWND, L"Index Buffer Failed", NULL, MB_OK);
	}

	//_CleanUpLoad();
	_CreateBase( iTemp, szTemp );

	fwscanf( pFile, L"%d", &m_pObject->iCubeCount );
	INT iVectorCount=0;
	fwscanf( pFile, L"%d", &iVectorCount );
	//벡터 할당
	m_vectorCube.resize( iVectorCount );

	fwscanf( pFile, L"%d", &iTemp );

	for(INT Loop=0; Loop<EnumCharFrame::MAXFRAME; ++Loop)
	{

		fwscanf( pFile, L"%s", szTemp );
		fwscanf( pFile, L"%d", &iTemp );

		if( iTemp != -1 )
		{
			for(INT xLoop=0; xLoop<m_iBoxSize; ++xLoop)
			{
				for(INT yLoop=0; yLoop<m_iBoxSize; ++yLoop)
				{
					for(INT zLoop=0; zLoop<m_iBoxSize; ++zLoop)
					{
						DWORD dwColor;
						BOOL bVisible;
						D3DXVECTOR3 vPos;
						INT iIndex;
						INT iVectorIndex;
						INT iType;
						INT iFriendVecIndex[6];

						fwscanf( pFile, L"%d %d %d %lx %d %f %f %f %d %d %d %d %d %d",	
							&iIndex,
							&iVectorIndex,
							&iType,
							&dwColor,
							&bVisible,
							&vPos.x,
							&vPos.y,
							&vPos.z,
							&iFriendVecIndex[0],
							&iFriendVecIndex[1],
							&iFriendVecIndex[2],
							&iFriendVecIndex[3],
							&iFriendVecIndex[4],
							&iFriendVecIndex[5]

							);

						//vPos.x = xLoop;
						//vPos.y = yLoop;
						//vPos.z = zLoop;

						//if( iVectorIndex != -1 )
							//m_pOctTree->SetChildIndex(vPos, iVectorIndex );

						if( iVectorIndex != -1 )
						{
							if( Loop == EnumCharFrame::BASE )
							{
								//벡터에 생성된 새 큐브 주소 넣기
								m_vectorCube[ iVectorIndex ] = new CCharCube;
								m_vectorCube[ iVectorIndex ]->Create( m_pD3dDevice, m_pTotalVB, m_pTotalIB, /*(iVectorIndex * CCube::CUBEVERTEX::VertexNum)*/0, 0 );
								m_vectorCube[ iVectorIndex ]->InitTexture( dwColor );								
							}

							m_vectorCube[ iVectorIndex ]->Set_NumIndex( Loop, iIndex );
							m_vectorCube[ iVectorIndex ]->Set_Type( Loop, iType );
							m_vectorCube[ iVectorIndex ]->Set_Color( Loop, dwColor );
							m_vectorCube[ iVectorIndex ]->Set_Visible( Loop, bVisible);
							m_vectorCube[ iVectorIndex ]->Set_Pos( Loop, vPos );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 0, iFriendVecIndex[0] );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 1, iFriendVecIndex[1] );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 2, iFriendVecIndex[2] );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 3, iFriendVecIndex[3] );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 4, iFriendVecIndex[4] );
							m_vectorCube[ iVectorIndex ]->Set_FriendCubeVecIndex( Loop, 5, iFriendVecIndex[5] );

							m_vectorCube[iVectorIndex]->Set_ControlTranslate( 0, m_vectorCube[iVectorIndex]->Get_Pos( Loop ).x );
							m_vectorCube[iVectorIndex]->Set_ControlTranslate( 1, m_vectorCube[iVectorIndex]->Get_Pos( Loop ).y );
							m_vectorCube[iVectorIndex]->Set_ControlTranslate( 2, m_vectorCube[iVectorIndex]->Get_Pos( Loop ).z );
							m_vectorCube[iVectorIndex]->Calcul_MatWorld();
							m_vectorCube[iVectorIndex]->Set_Matrix( Loop, m_vectorCube[iVectorIndex]->Get_MatWorld() );

							// Set BoundBox Size
							if (fBBSize[0][0] > vPos.x)		fBBSize[0][0] = vPos.x;
							if (fBBSize[0][1] > vPos.y)		fBBSize[0][1] = vPos.y;
							if (fBBSize[0][2] > vPos.z)		fBBSize[0][2] = vPos.z;
							if (fBBSize[1][0] < vPos.x)		fBBSize[1][0] = vPos.x;
							if (fBBSize[1][1] < vPos.y)		fBBSize[1][1] = vPos.y;
							if (fBBSize[1][2] < vPos.z)		fBBSize[1][2] = vPos.z;
						}
					}
				}
			}
		}

		fwscanf( pFile, L"%s", szTemp );
	}

	m_pBoundBox->SetSize(0, fBBSize[0][0]);
	m_pBoundBox->SetSize(1, fBBSize[0][1]);
	m_pBoundBox->SetSize(2, fBBSize[0][2]);
	m_pBoundBox->SetSize(3, fBBSize[1][0]);
	m_pBoundBox->SetSize(4, fBBSize[1][1]);
	m_pBoundBox->SetSize(5, fBBSize[1][2]);

	fclose( pFile );

	m_iCubeVectorSize = static_cast<INT>( m_vectorCube.size() );

	// 면단위 컬링시 사용
	//for( INT Loop=0; Loop<m_iCubeVectorSize; ++Loop )
	//{
	//	// 인터페이스에서 컬링이 온이라면
	//	if( m_vectorCube[Loop] != NULL && m_vectorCube[Loop]->Get_Visible( EnumCharFrame::BASE ) == TRUE )
	//	{
	//		for(INT LoopCell=0; LoopCell<6; ++LoopCell)
	//		{
	//			if( -1 != m_vectorCube[Loop]->Get_FriendCubeVecIndex( m_iSelectedFrameNum, LoopCell ) )
	//			{
	//				m_vectorCube[Loop]->Set_FaceVisible( LoopCell, FALSE );
	//			}
	//			//else
	//			//{
	//			//	m_vectorCube[Loop]->Set_FaceVisible( LoopCell, TRUE );
	//			//}
	//		}
	//	}
	//}

	//MessageBox(GHWND, L"Load OK", a_pFileName, MB_OK);
}
Ejemplo n.º 8
0
//given an animation and a keyframe, this will find the dims that encompass the
//model
bool CDimensionsDlg::FindAnimDims(Model* pModel, uint32 nAnim, uint32 nKeyFrame, LTVector& vDims)
{
    //clear out the dims to start out with in case we fail
    vDims.Init();

    AnimTracker tracker, *pTracker;
    tracker.m_TimeRef.Init(pModel, nAnim, nKeyFrame, nAnim, nKeyFrame, 0.0f);

    AnimInfo *pAnim = &pModel->m_Anims[nAnim];

    pTracker = &tracker;//pAnim->m_pAnim;

    static CMoArray<TVert> tVerts;

    // Use the model code to setup the vertices.

    int nTrackers = 1;
    nTrackers = DMIN(nTrackers, MAX_GVP_ANIMS);

    GVPStruct gvp;

    gvp.m_nAnims = 0;
    for(int i = 0; i < nTrackers; i++)
    {
        gvp.m_Anims[i] = pTracker[i].m_TimeRef;
        gvp.m_nAnims++;
    }

    LTMatrix m;
    m.Identity();

    int nWantedVerts = pModel->GetTotalNumVerts() * 2;
    if(tVerts.GetSize() < nWantedVerts)
    {
        if(!tVerts.SetSize(nWantedVerts))
            return false;
    }

    gvp.m_VertexStride = sizeof(TVert);
    gvp.m_Vertices = tVerts.GetArray();
    gvp.m_BaseTransform = m;
    gvp.m_CurrentLODDist = 0;

    if (AlternateGetVertexPositions(pModel, &gvp, true, false, false, false))
    {
        LTVector vMax(0, 0, 0);

        for (i = 0; i < pModel->GetTotalNumVerts(); i ++)
        {
            TVert v = tVerts[i];

            if (fabs(v.m_vPos.x) > vMax.x) vMax.x = (float)fabs(v.m_vPos.x);
            if (fabs(v.m_vPos.y) > vMax.y) vMax.y = (float)fabs(v.m_vPos.y);
            if (fabs(v.m_vPos.z) > vMax.z) vMax.z = (float)fabs(v.m_vPos.z);
        }

        // Setup the new dims....

        //round max up to the .1 decimal place
        vMax.x = (float)(ceil(vMax.x * 10.0) / 10.0);
        vMax.y = (float)(ceil(vMax.y * 10.0) / 10.0);
        vMax.z = (float)(ceil(vMax.z * 10.0) / 10.0);

        vDims = vMax;

        return true;
    }

    //failure
    return false;
}
Ejemplo n.º 9
0
/*------------------------------
doThreshAnalysis
description: do the threshold analysis using the specified channel, and using the
    sample blocks as the "trigger"
input: int chNum- the channel in the signal to use
output: basicStats - the stats for this channel
*/
basicStats analysis::doThreshAnalysis(int chNum)
{
	vector<double> tDiff;
	basicStats tmpStat;
	tmpStat.mean = -1;
	tmpStat.std = -1;
	tmpStat.min = -1;
	tmpStat.max = -1;

	if (chNum >= nChannels || chNum < 0)
		return tmpStat;

    //normalize the data by subtracting the minimum value, and dividing by the max
    //giving us values between 0 and 1
	double sMin = getMin(signal[chNum], nSamples);
	double *sigTmp = new double[nSamples];
	for (int i = 0; i < nSamples; i++)
		sigTmp[i] = signal[chNum][i] - sMin;

	//now normalize the data
	double sMax = getMax(sigTmp, nSamples);
    if (sMax == 0)
		return tmpStat;

	for (int i = 0; i < nSamples; i++)
		sigTmp[i] /= sMax;

	//get the time differences
    int sigPos = 0;
    for (int sample = blockSize; sample < nSamples-blockSize; sample += blockSize)
    {
        //record the starting sample
        sigPos = sample;

        //first check that the signal already is not above threshold,
        //and if it is, just continue
        if (sigTmp[sigPos] > thresh && sigTmp[sigPos-1] >= thresh)
            continue;

        //go through the signal, and increment the signal position until it
        //crosses the threshold
        while ((sigTmp[sigPos] < thresh) && ((sigPos-sample) < blockSize))
            sigPos++;

        //the signal has crossed the threshold, so record the time difference
        //from the first sample in the block to when this occurred,
        //converted to ms, and add it to the tDiff vector
        if (sigPos >= sample)
            tDiff.push_back(((float)sigPos-(float)sample)/sampleRate*1000);
    }

	if (tDiff.size() == 0)
		return tmpStat;

    //find the mean, std, etc
    tmpStat.mean = vMean(&tDiff);
    tmpStat.std = vStd(&tDiff);
    tmpStat.min = vMin(&tDiff);
    tmpStat.max = vMax(&tDiff);
    tmpStat.vals = tDiff;

    stringstream str;
    str << "Ch " << chNum <<" v. blocks";
    tmpStat.desc = str.str();

    return tmpStat;
}
Ejemplo n.º 10
0
Archivo: pivot.c Proyecto: cran/WGCNA
double pivot(double * v, size_t len, double target)
{
  // Rprintf("Entering pivot with len=%d and target=%f\n   ", len, target);
  // RprintV(v, len);

  if (len > 2)
  {
    // pick the pivot, say as the median of the first, middle and last
    size_t i1 = 0, i2 = len-1, i3 = (len-1)/2, ip;
    if (v[i1] <= v[i2])
    {
      if (v[i2] <= v[i3])
        ip = i2;
      else if (v[i3] >= v[i1])
         ip = i3;
      else 
         ip = i1;
    } else {
      if (v[i1] <= v[i3])
        ip = i1;
      else if (v[i2] <= v[i3])
        ip = i3;
      else
        ip = i2;
    }

    // put ip at the end
    double vp = v[ip];
    v[ip] = v[len-1];
    v[len-1] = vp;

    // Rprintf("   pivot value: %5.3f, index: %d\n", vp, ip);

    // pivot everything else
    size_t bound = 0;
    for (size_t i=0; i<len; i++) if (v[i] < vp)
    {
      double x = v[bound];
      v[bound] = v[i];
      v[i] = x;
      bound++;
    }

    v[len-1] = v[bound];
    v[bound] = vp;

    // Rprintf("   After pivoting: bound:%d and vector: ", bound); // RprintV(v, len);

    // Did we find the target?
    
    double crit = target - bound;
    // Rprintf("   crit: %5.3f\n", crit);
    if (fabs(crit) > 1.0)
    {
      if (crit < 0)
        return pivot(v, bound, target);
      else
        return pivot(v+bound+1, len-bound-1, target-bound-1);
    }
    // Rprintf("vMax(v, bound): %5.3f, vMin(v+bound+1, len-bound-1): %5.3f, vp: %5.3f\n", vMax(v, bound),
                // vMin(v+bound+1, len-bound-1), vp);
    if (crit < 0)
    {
       double v1 = vMax(v, bound);
       return (v1 *(-crit) + vp * (1+crit));
    } // else
    double v2 = vMin(v+bound+1, len-bound-1);
    return (vp * (1-crit) + v2 * crit);
  } 
  else if (len==2)
  {
      // Rprintf("  Short v, returning a direct value.\n"); 
      double v1 = vMin(v, 2);
      double v2 = vMax(v, 2);
      if (target < 0) return v1;
      else if (target > 1) return v2;
      else return (target * v2 + (1-target) * v1);
  }
  else 
  {
     // Rprintf("  length 1 v, returning a direct value.\n"); 
     return v[0];
  }
}
Ejemplo n.º 11
0
/**
* CParticleEffect::initParticle
* @date Modified June 01, 2006
*/
void CParticleEffect::initParticle(CParticleManager::SParticle* pParticle, D3DXMATRIX* mOffset)
{
	D3DXMATRIX mPosOffset, mOrientation = *mOffset;
	D3DXMatrixIdentity(&mPosOffset);
	mPosOffset._41 = mOffset->_41;
	mPosOffset._42 = mOffset->_42;
	mPosOffset._43 = mOffset->_43;
	mOrientation._41 = mOrientation._42 = mOrientation._43 = 0.0f;
	mOrientation._44 = 1.0f;

	float fMinVel, fMaxVel;
	D3DXVec3Normalize(&fMinVel, &m_vMinVelocity, &m_vMinVelocity);
	D3DXVec3Normalize(&fMaxVel, &m_vMaxVelocity, &m_vMaxVelocity);

	D3DXVec3TransformCoord(&m_vMinVelocityTrans, &m_vMinVelocity, &mOrientation);
	D3DXVec3TransformCoord(&m_vMaxVelocityTrans, &m_vMaxVelocity, &mOrientation);

	m_vMinVelocity *= fMinVel;
	m_vMaxVelocity *= fMaxVel;

	// Update attributes
	BYTE cR = GET_RED(pParticle->Color), 
		 cG = GET_GREEN(pParticle->Color), 
		 cB = GET_BLUE(pParticle->Color), 
		 cA = GET_ALPHA(pParticle->Color);
	for(size_t j = 0; j < m_vAttributes.size(); ++j)
	{
		float fScale = m_vAttributes[j]->getValue(0.0f);
		switch(m_vAttributes[j]->getType())
		{
		case CParticleAttribute::ATR_COLORRED: cR = (BYTE)(fScale * 255.0f); break;
		case CParticleAttribute::ATR_COLORGREEN: cG = (BYTE)(fScale * 255.0f); break;
		case CParticleAttribute::ATR_COLORBLUE: cB = (BYTE)(fScale * 255.0f); break;
		case CParticleAttribute::ATR_COLORALPHA: cA = (BYTE)(fScale * 255.0f); break;
		case CParticleAttribute::ATR_SIZE: pParticle->Size = fScale; break;
		case CParticleAttribute::ATR_ROTATION: pParticle->Rotation = degreesToRadians(fScale); break;
		case CParticleAttribute::ATR_ACCELX: pParticle->Acceleration.x = fScale; break;
		case CParticleAttribute::ATR_ACCELY: pParticle->Acceleration.y = fScale; break;
		case CParticleAttribute::ATR_ACCELZ: pParticle->Acceleration.z = fScale; break;
		}
	}
	pParticle->Color = D3DCOLOR_ARGB(cA, cR, cG, cB);
	getRandomVector(&pParticle->Velocity, &m_vMinVelocityTrans, &m_vMaxVelocityTrans);
	pParticle->Velocity *= getRandomFloat(fMinVel, fMaxVel);
	m_vMinVelocityTrans *= fMinVel;
	m_vMaxVelocityTrans *= fMaxVel;
	
	D3DXVECTOR3 vMin(0.0f, 0.0f, 0.0f), vMax(0.0f, 0.0f, 0.0f);
	switch(m_eSpawnShape)
	{
	case SH_CUBE:
		vMin.x = -m_vSpawnRadius.x;
		vMin.y = -m_vSpawnRadius.y;
		vMin.z = -m_vSpawnRadius.z;
		getRandomVector(&pParticle->Position, &vMin, &m_vSpawnRadius);
		break;
	case SH_SQUARE:
		vMin.x = -m_vSpawnRadius.x;
		vMin.z = -m_vSpawnRadius.z;
		vMax.x = m_vSpawnRadius.x;
		vMax.z = m_vSpawnRadius.z;
		getRandomVector(&pParticle->Position, &vMin, &vMax);
		break;
	case SH_SPHERE:
		getRandomVector(&vMin, -1.0f, 1.0f);
		D3DXVec3Normalize(&vMin, &vMin);
		pParticle->Position.x = vMin.x * m_vSpawnRadius.x;
		pParticle->Position.y = vMin.y * m_vSpawnRadius.x;
		pParticle->Position.z = vMin.z * m_vSpawnRadius.x;
		break;
	case SH_CIRCLE:
		getRandomVector(&vMin, -1.0f, 1.0f);
		D3DXVec3Normalize(&vMin, &vMin);
		pParticle->Position.x = vMin.x * m_vSpawnRadius.x;
		pParticle->Position.y = 0.0f;
		pParticle->Position.z = vMin.z * m_vSpawnRadius.x;
		break;
	}
	
	D3DXVec3TransformCoord(&pParticle->Position, &pParticle->Position, &mPosOffset);
}
/*
 * Prepare for projecting.
 */
void CPerspectiveProjection3D::Prepare(void)
{
  FLOATmatrix3D t3dObjectStretch;   // matrix for object stretch
  FLOATmatrix3D t3dObjectRotation;  // matrix for object angles

  // calc. matrices for viewer and object angles and stretch
  MakeRotationMatrixFast(
    t3dObjectRotation, pr_ObjectPlacement.pl_OrientationAngle);
  MakeInverseRotationMatrixFast(
    pr_ViewerRotationMatrix, pr_ViewerPlacement.pl_OrientationAngle);
  t3dObjectStretch.Diagonal(pr_ObjectStretch);
  pr_vViewerPosition = pr_ViewerPlacement.pl_PositionVector;
  BOOL bXInverted = pr_ObjectStretch(1)<0;
  BOOL bYInverted = pr_ObjectStretch(2)<0;
  BOOL bZInverted = pr_ObjectStretch(3)<0;

  pr_bInverted = (bXInverted != bYInverted) != bZInverted;

  // if the projection is mirrored
  if (pr_bMirror) {
    // reflect viewer
    ReflectPositionVectorByPlane(pr_plMirror, pr_vViewerPosition);
    ReflectRotationMatrixByPlane_rows(pr_plMirror, pr_ViewerRotationMatrix);
    // get mirror plane in view space
    pr_plMirrorView = pr_plMirror;
    pr_plMirrorView -= pr_vViewerPosition;
    pr_plMirrorView *= pr_ViewerRotationMatrix;
    // invert inversion
    pr_bInverted = !pr_bInverted;
  } else if (pr_bWarp) {
    // get mirror plane in view space
    pr_plMirrorView = pr_plMirror;
  }

  // if the object is face-forward
  if (pr_bFaceForward) {
    // if it turns only heading
    if (pr_bHalfFaceForward) {
      // get the y-axis vector of object rotation
      FLOAT3D vY(t3dObjectRotation(1,2), t3dObjectRotation(2,2), t3dObjectRotation(3,2));
      // find z axis of viewer
      FLOAT3D vViewerZ(
        pr_ViewerRotationMatrix(3,1),
        pr_ViewerRotationMatrix(3,2),
        pr_ViewerRotationMatrix(3,3));
      // calculate x and z axis vectors to make object head towards viewer
      FLOAT3D vX = (-vViewerZ)*vY;
      vX.Normalize();
      FLOAT3D vZ = vY*vX;
      // compose the rotation matrix back from those angles
      t3dObjectRotation(1,1) = vX(1); t3dObjectRotation(1,2) = vY(1); t3dObjectRotation(1,3) = vZ(1);
      t3dObjectRotation(2,1) = vX(2); t3dObjectRotation(2,2) = vY(2); t3dObjectRotation(2,3) = vZ(2);
      t3dObjectRotation(3,1) = vX(3); t3dObjectRotation(3,2) = vY(3); t3dObjectRotation(3,3) = vZ(3);

      // first apply object stretch then object rotation and then viewer rotation
      pr_mDirectionRotation = pr_ViewerRotationMatrix*t3dObjectRotation;
      pr_RotationMatrix = pr_mDirectionRotation*t3dObjectStretch;
    // if it is fully face forward
    } else {
      // apply object stretch and banking only
      FLOATmatrix3D mBanking;
      MakeRotationMatrixFast(
        mBanking, ANGLE3D(0,0, pr_ObjectPlacement.pl_OrientationAngle(3)));
      pr_mDirectionRotation = mBanking;
      pr_RotationMatrix = mBanking*t3dObjectStretch;
    }
  } else {
    // first apply object stretch then object rotation and then viewer rotation
    pr_mDirectionRotation = pr_ViewerRotationMatrix*t3dObjectRotation;
    pr_RotationMatrix = pr_mDirectionRotation*t3dObjectStretch;
  }

  // calc. offset of object from viewer
  pr_TranslationVector = pr_ObjectPlacement.pl_PositionVector - pr_vViewerPosition;
  // rotate offset only by viewer angles
  pr_TranslationVector = pr_TranslationVector*pr_ViewerRotationMatrix;
  // transform handle from object space to viewer space and add it to the offset
  pr_TranslationVector -= pr_vObjectHandle*pr_RotationMatrix;

  FLOAT2D vMin, vMax;
  // if using a shadow projection
  if (ppr_fMetersPerPixel>0) {
    // caclulate factors
    FLOAT fFactor = ppr_fViewerDistance/ppr_fMetersPerPixel;
    ppr_PerspectiveRatios(1) = -fFactor;
    ppr_PerspectiveRatios(2) = -fFactor;
    pr_ScreenCenter = -pr_ScreenBBox.Min();

    vMin = pr_ScreenBBox.Min();
    vMax = pr_ScreenBBox.Max();
  // if using normal projection
  } else if (ppr_boxSubScreen.IsEmpty()) {
    // calculate perspective constants
    FLOAT2D v2dScreenSize = pr_ScreenBBox.Size();
    pr_ScreenCenter = pr_ScreenBBox.Center();
    /* calculate FOVHeight from FOVWidth by formula:
       halfanglej = atan( tan(halfanglei)*jsize*aspect/isize ) */
    ANGLE aHalfI = ppr_FOVWidth/2;
    ANGLE aHalfJ = ATan(TanFast(aHalfI)*v2dScreenSize(2)*pr_AspectRatio/v2dScreenSize(1));

    /* calc. perspective ratios by formulae:
       xratio = isize/(2*tan(anglei/2))
       yratio = jsize/(2*tan(anglej/2))
      sign is negative since viewer is looking down the -z axis
    */
    ppr_PerspectiveRatios(1) = -v2dScreenSize(1)/(2.0f*TanFast(aHalfI))*pr_fViewStretch;
    ppr_PerspectiveRatios(2) = -v2dScreenSize(2)/(2.0f*TanFast(aHalfJ))*pr_fViewStretch;

    vMin = pr_ScreenBBox.Min()-pr_ScreenCenter;
    vMax = pr_ScreenBBox.Max()-pr_ScreenCenter;
  // if using sub-drawport projection
  } else {
    // calculate perspective constants
    FLOAT2D v2dScreenSize = pr_ScreenBBox.Size();
    pr_ScreenCenter = pr_ScreenBBox.Center();
    /* calculate FOVHeight from FOVWidth by formula:
       halfanglej = atan( tan(halfanglei)*jsize*aspect/isize ) */
    ANGLE aHalfI = ppr_FOVWidth/2;
    ANGLE aHalfJ = ATan(TanFast(aHalfI)*v2dScreenSize(2)*pr_AspectRatio/v2dScreenSize(1));

    /* calc. perspective ratios by formulae:
       xratio = isize/(2*tan(anglei/2))
       yratio = jsize/(2*tan(anglej/2))
      sign is negative since viewer is looking down the -z axis
    */
    ppr_PerspectiveRatios(1) = -v2dScreenSize(1)/(2.0f*TanFast(aHalfI))*pr_fViewStretch;
    ppr_PerspectiveRatios(2) = -v2dScreenSize(2)/(2.0f*TanFast(aHalfJ))*pr_fViewStretch;

    vMin = ppr_boxSubScreen.Min()-pr_ScreenCenter;
    vMax = ppr_boxSubScreen.Max()-pr_ScreenCenter;

    pr_ScreenCenter -= ppr_boxSubScreen.Min();
  }
  // find factors for left, right, up and down clipping

  FLOAT fMinI = vMin(1); FLOAT fMinJ = vMin(2);
  FLOAT fMaxI = vMax(1); FLOAT fMaxJ = vMax(2);
  FLOAT fRatioX = ppr_PerspectiveRatios(1);
  FLOAT fRatioY = ppr_PerspectiveRatios(2);

#define MySgn(x) ((x)>=0?1:-1)

  FLOAT fDZ = -1.0f;
  FLOAT fDXL = fDZ*fMinI/fRatioX;
  FLOAT fDXR = fDZ*fMaxI/fRatioX;
  FLOAT fDYU = -fDZ*fMinJ/fRatioY;
  FLOAT fDYD = -fDZ*fMaxJ/fRatioY;

  FLOAT fNLX = -fDZ;
  FLOAT fNLZ = +fDXL;
  FLOAT fOoNL = 1.0f/(FLOAT)sqrt(fNLX*fNLX+fNLZ*fNLZ);
  fNLX*=fOoNL; fNLZ*=fOoNL;

  FLOAT fNRX = +fDZ;
  FLOAT fNRZ = -fDXR;
  FLOAT fOoNR = 1.0f/(FLOAT)sqrt(fNRX*fNRX+fNRZ*fNRZ);
  fNRX*=fOoNR; fNRZ*=fOoNR;

  FLOAT fNDY = -fDZ;
  FLOAT fNDZ = +fDYD;
  FLOAT fOoND = 1.0f/(FLOAT)sqrt(fNDY*fNDY+fNDZ*fNDZ);
  fNDY*=fOoND; fNDZ*=fOoND;

  FLOAT fNUY = +fDZ;
  FLOAT fNUZ = -fDYU;
  FLOAT fOoNU = 1.0f/(FLOAT)sqrt(fNUY*fNUY+fNUZ*fNUZ);
  fNUY*=fOoNU; fNUZ*=fOoNU;

  // make clip planes
  pr_plClipU = FLOATplane3D(FLOAT3D(   0,fNUY,fNUZ), 0.0f);
  pr_plClipD = FLOATplane3D(FLOAT3D(   0,fNDY,fNDZ), 0.0f);
  pr_plClipL = FLOATplane3D(FLOAT3D(fNLX,   0,fNLZ), 0.0f);
  pr_plClipR = FLOATplane3D(FLOAT3D(fNRX,   0,fNRZ), 0.0f);

  // mark as prepared
  pr_Prepared = TRUE;

  // calculate constant value used for calculating z-buffer k-value from vertex's z coordinate
  pr_fDepthBufferFactor = -pr_NearClipDistance;
  pr_fDepthBufferMul = pr_fDepthBufferFar-pr_fDepthBufferNear;
  pr_fDepthBufferAdd = pr_fDepthBufferNear;

  // calculate ratio for mip factor calculation
  ppr_fMipRatio = pr_ScreenBBox.Size()(1)/(ppr_PerspectiveRatios(1)*640.0f);
}
Ejemplo n.º 13
0
/**
 * Parses a navPoly / waypoint section 
 *
 * @param pSection  the DataSection to parse.
 * @param pChunk  if not NULL this flags that we are parsing a navPoly not a
 * waypoint section as well as providing the chunk from which to get the 
 * transform information to go from local -> global coords.
 */
void ChunkView::parseNavPoly( DataSectionPtr pSection, int set, Chunk * pChunk )
{
	DataSection::iterator it;
	PolygonDef polyDef;
	int id;
	float height;

	id = pSection->asInt();
	height = pSection->readFloat("height");
	polyDef.minHeight = pSection->readFloat("minHeight",height);
	polyDef.maxHeight = pSection->readFloat("maxHeight",height);
	polyDef.set = set;

	// If chunk provided, we want to convert heights from local -> global coords.
	if (pChunk)
	{
		Vector3 vMin( pChunk->centre().x, polyDef.minHeight, pChunk->centre().z );
		Vector3 vMax( pChunk->centre().x, polyDef.maxHeight, pChunk->centre().z );

		Vector3 vMinT = pChunk->transform().applyPoint( vMin );
		Vector3 vMaxT = pChunk->transform().applyPoint( vMax );

		polyDef.minHeight = vMinT.y;
		polyDef.maxHeight = vMaxT.y;
	}

	// If there is a gap in IDs, add blank polys to fill it up.
	while (nextID_ <= id)
	{
		PolygonDef blankPoly;
		blankPoly.minHeight = 0.0f;
		blankPoly.maxHeight = 0.0f;
		blankPoly.set = 0;
		polygons_.push_back(blankPoly);
		nextID_++;
	}

	// Read all this navPoly's vertices
	for(it = pSection->begin(); it != pSection->end(); it++)
	{
		if((*it)->sectionName() == "vertex")
		{
			DataSectionPtr pVertex = *it;
			VertexDef vertexDef;
			Vector3 vinfo = pVertex->asVector3();
			vertexDef.position.x = vinfo.x;
			vertexDef.position.y = vinfo.y;
			vertexDef.adjacentID = int( vinfo.z );

			// if pChunk provided, want to convert vertex to golbal coords.
			if (pChunk)
			{
				Vector3 v( vinfo.x, polyDef.maxHeight, vinfo.y );
				Vector3 vT = pChunk->transform().applyPoint( v );

				vertexDef.position.x = vT.x;
				vertexDef.position.y = vT.z;
			}

			std::string notFound( "__NOT_FOUND__" );
			std::string adjacentChunk = pVertex->readString("adjacentChunk",notFound);
			// if there is an adjacentChunk tag
			// note: only ever occurs within legacy waypoint tags.
			if ( adjacentChunk != notFound ) 
			{
				if (vertexDef.adjacentID != 0) 
				{
					WARNING_MSG( "ChunkView::parseNavPoly: adjacentChunk tag"
						" found but edge adjacency not 0.\n" );
				}
				vertexDef.adjacentID = CHUNK_ADJACENT_CONSTANT;
			}

			// if adjacent to another chunk, flag this in vertexDef.
			// also make (navPoly) adjacentID more sensible.
			vertexDef.adjToAnotherChunk = false;
			if (vertexDef.adjacentID == CHUNK_ADJACENT_CONSTANT) 
			{
				vertexDef.adjacentID = 0;
				vertexDef.adjToAnotherChunk = true;
			}

			polyDef.vertices.push_back( vertexDef );

			if(!minMaxValid_)
			{
				gridMin_.x = vertexDef.position.x;
				gridMin_.z = vertexDef.position.y;
				gridMin_.y = -1000.0f;
				gridMax_.x = vertexDef.position.x;
				gridMax_.z = vertexDef.position.y;
				gridMax_.y = 1000.0f;
				minMaxValid_ = true;
			}
			else
			{
				if(vertexDef.position.x < gridMin_.x)
					gridMin_.x = vertexDef.position.x;
				if(vertexDef.position.y < gridMin_.z)
					gridMin_.z = vertexDef.position.y;
				if(vertexDef.position.x > gridMax_.x)
					gridMax_.x = vertexDef.position.x;
				if(vertexDef.position.y > gridMax_.z)
					gridMax_.z = vertexDef.position.y;
			}
		}
	}

	polygons_[id-1] = polyDef;
}
Ejemplo n.º 14
0
// Calculate the quantization factors
void CIFXPointSetEncoder::CalculateQuantizationFactorsX()
{
	U32 uQualityFactor = 1000;

	m_pPointSetResource->GetQualityFactorX(uQualityFactor,IFXAuthorPointSetResource::POSITION_QUALITY);
	if(1000 == uQualityFactor) {
		m_fQuantPosition = (F32) pow(2.0,18.0);
	} else {
		m_fQuantPosition = (F32) pow(1.0076537604105041221998506395494,uQualityFactor+545.0);
	}

	// Scale m_fQuantPosition by the radius of the bounding sphere
	IFXASSERT(m_pAuthorPointSet);
	// get the Point set description
	const IFXAuthorPointSetDesc* pPointSetDescription = m_pAuthorPointSet->GetMaxPointSetDesc();
	IFXASSERT(pPointSetDescription);
	IFXASSERT(pPointSetDescription->m_numPositions > 0);

	IFXVector3* pPosition = NULL;
	IFXCHECKX(m_pAuthorPointSet->GetPositions(&pPosition));

	// Calculate the center of the bounding sphere
	IFXVector3 vMin(pPosition[0]), vMax(pPosition[0]);
	U32 i = 0;
	U32 uNumPositions = pPointSetDescription->m_numPositions;
	for(i = 1; i < uNumPositions ; i++) {
		vMin.X() += (pPosition[i].X() - vMin.X()) * (pPosition[i].X() < vMin.X());
		vMin.Y() += (pPosition[i].Y() - vMin.Y()) * (pPosition[i].Y() < vMin.Y());
		vMin.Z() += (pPosition[i].Z() - vMin.Z()) * (pPosition[i].Z() < vMin.Z());
		vMax.X() += (pPosition[i].X() - vMax.X()) * (pPosition[i].X() > vMax.X());
		vMax.Y() += (pPosition[i].Y() - vMax.Y()) * (pPosition[i].Y() > vMax.Y());
		vMax.Z() += (pPosition[i].Z() - vMax.Z()) * (pPosition[i].Z() > vMax.Z());
	}
	IFXVector3 vCenter(vMin);
	vCenter.Add(vMax);
	vCenter.Scale(0.5f);

	// Calculate the radius of the bounding sphere
	F32 fRadiusSquared = 0.0f;
	F32 fDistanceSquared = 0.0f;
	for(i=0; i < uNumPositions; i++) {
		fDistanceSquared = vCenter.CalcDistanceSquaredFrom(pPosition[i]);
		fRadiusSquared += (fDistanceSquared - fRadiusSquared) * (fDistanceSquared > fRadiusSquared);
	}

	// Scale the position quantization factor by the radius of the bounding sphere
	if(fRadiusSquared > 0.0f) {
		m_fQuantPosition /= sqrtf(fRadiusSquared);
	}

	// Limit quantization factor to fit quantized results in 32 bit unsigned integer
	{
		// Find position coordinate farthest from the origin
		F32 fMaxPositionCoordinate;
		fMaxPositionCoordinate = IFXMAX(fabs(vMax.X()),fabs(vMax.Y()));
		fMaxPositionCoordinate = IFXMAX(fMaxPositionCoordinate,fabs(vMax.Z()));
		fMaxPositionCoordinate = IFXMAX(fMaxPositionCoordinate,fabs(vMin.X()));
		fMaxPositionCoordinate = IFXMAX(fMaxPositionCoordinate,fabs(vMin.Y()));
		fMaxPositionCoordinate = IFXMAX(fMaxPositionCoordinate,fabs(vMin.Z()));

		F32 fLimit = (F32) (0xFFFFFE00); // (F32) (0xFFFFFE00)
		F32 fMaxQuantPosition = fLimit / fMaxPositionCoordinate;

		// Clamp position quantization factor
		m_fQuantPosition = IFXMIN(m_fQuantPosition,fMaxQuantPosition);
	}

	m_pPointSetResource->GetQualityFactorX(uQualityFactor,IFXAuthorPointSetResource::NORMAL_QUALITY);
	if(1000 == uQualityFactor) {
		m_fQuantNormal = (F32) pow(2.0,14.0);
	} else {
		m_fQuantNormal = (F32) pow(1.0048638204237854409678879459798,uQualityFactor+857.0);
	}

	m_pPointSetResource->GetQualityFactorX(uQualityFactor,IFXAuthorPointSetResource::TEXCOORD_QUALITY);
	if(1000 == uQualityFactor) {
		m_fQuantTexCoord = (F32) pow(2.0,14.0);
	} else {
		m_fQuantTexCoord = (F32) pow(1.0048638204237854409678879459798,uQualityFactor+857.0);
	}

	m_pPointSetResource->GetQualityFactorX(uQualityFactor,IFXAuthorPointSetResource::DIFFUSE_QUALITY);
	if(1000 == uQualityFactor) {
		m_fQuantDiffuseColor = (F32) pow(2.0,14.0);
	} else {
		m_fQuantDiffuseColor = (F32) pow(1.0022294514890519310704865897552,uQualityFactor+1741.0);
	}

	m_pPointSetResource->GetQualityFactorX(uQualityFactor,IFXAuthorPointSetResource::SPECULAR_QUALITY);
	if(1000 == uQualityFactor) {
		m_fQuantSpecularColor = (F32) pow(2.0,14.0);
	} else {
		m_fQuantSpecularColor = (F32) pow(1.0022294514890519310704865897552,uQualityFactor+1741.0);
	}

	m_fInverseQuantPosition = (F32) 1.0 / m_fQuantPosition;
	m_fInverseQuantNormal = (F32) 1.0 / m_fQuantNormal;
	m_fInverseQuantTexCoord = (F32) 1.0 / m_fQuantTexCoord;
	m_fInverseQuantDiffuseColor = (F32) 1.0 /m_fQuantDiffuseColor;
	m_fInverseQuantSpecularColor = (F32) 1.0 /m_fQuantSpecularColor;
}
Ejemplo n.º 15
0
/*------------------------------
doThreshAnalysis
description: this version of the analysis uses a specified recorded channel,
    and triggers off of a state when that state changes to a given value
input: int chNum - the channel to use in the analysis
        string stateName - the state name to use for triggering
        int stateVal - the value that the state must change to to trigger
            (0 triggers ANY positive state change)
output: basicStats - the results of the analysis
*/
basicStats analysis::doThreshAnalysis(int chNum, string stateName, int stateVal)
{
	vector<double> tDiff;
	basicStats tmpStat;
	tmpStat.mean = -1;
	tmpStat.std = -1;
	tmpStat.min = -1;
	tmpStat.max = -1;

    //normalize the data by subtracting the minimum value, and dividing by the max
    //giving us values between 0 and 1
	if (chNum >= nChannels || chNum < 0)
		return tmpStat;

	map<string, double*>::iterator itr = states.find(stateName);
	if (itr == states.end())
		return tmpStat;

    double sMin = getMin(signal[chNum], nSamples);
    double *sigTmp = new double[nSamples];
    for (int i = 0; i < nSamples; i++)
        sigTmp[i] = signal[chNum][i] - sMin;

    //now normalize the data
	double sMax = getMax(sigTmp, nSamples);
	if (sMax == 0)
		return tmpStat;
    for (int i = 0; i < nSamples; i++)
        sigTmp[i] /= sMax;

    //get the time differences
    //this finds both EACH state transition and COMBINED state transitions
    map<int, vector<double> > stateTDiffs;

    int sigPos = 0;
    int dState;
	for (int sample = 1; sample < nSamples-blockSize; sample += 1)
    {
		//get the transition value
		dState = (states[stateName][sample]-states[stateName][sample-1]);
        //we are only looking for positive CHANGES in the state
        if (dState <= 0)
            continue;

        sigPos = sample;
        //first check that the signal already is not above threshold,
        //and if it is, just continue
        if (sigTmp[sigPos] > thresh && sigTmp[sigPos-1] > thresh)
            continue;

        //look for the sample in the signal where it crosses the threshold
        while (sigTmp[sigPos] < thresh  && sigPos < nSamples)
            sigPos++;

        //calculate the time difference
		float D = ((float)sigPos-(float)sample)/sampleRate*1000;

		if (sigPos > sample && sigPos < nSamples)
		{
            //store the time difference if the state change value is 0 or equal to what we specified

			if (stateVal == 0 || (stateVal == dState))
				tDiff.push_back(D);
            else if (stateVal == -1)
			{
                //if we set state val to -1, we record all differences, and keep track of
                //the times for each dState value
				tDiff.push_back(D);
				stateTDiffs[dState].push_back(D);
			}
        }
    }

	if (tDiff.size() == 0)
		return tmpStat;

    //calculate the stats on the tDiff vector
    tmpStat.mean = vMean(&tDiff);
    tmpStat.std = vStd(&tDiff);
    tmpStat.min = vMin(&tDiff);
    tmpStat.max = vMax(&tDiff);
    //tmpStat.vals = tDiff;
    stringstream str;
    str << "Ch " << chNum <<" v. " << stateName;
    if (stateVal > 0)
        str <<"("<<stateVal<<")";

    tmpStat.desc = str.str();

    if (stateVal >= 0)
        return tmpStat;

    //now compare all of the states if stateVal == -1
    //we keep the state with the smallest overall mean and return its
    map<int, vector<double> >::iterator it;
    it = stateTDiffs.begin();

    double minMean = tmpStat.mean;
    for (it = stateTDiffs.begin(); it != stateTDiffs.end(); it++)
    {
        double tmpMean = vMean(&it->second);
        if (tmpMean < minMean)
        {
                minMean = tmpMean;
                tmpStat.mean = vMean(&it->second);
                tmpStat.std = vStd(&it->second);
                tmpStat.min = vMin(&it->second);
                tmpStat.max = vMax(&it->second);
                tmpStat.vals = it->second;

                stringstream str;
                str << "Ch " << chNum <<" v. " << stateName << "("<<it->first<<")";
                tmpStat.desc = str.str();
        }
    }

    return tmpStat;
}
Ejemplo n.º 16
0
bool ModelImport::ImportObj(const std::string& srcFilename, std::string& dstFilename)
{
	const AssetLib::AssetDef& rAssetDef = AssetLib::Model::GetAssetDef();

	std::ifstream srcFile(srcFilename);
	assert(srcFile.is_open());

	std::ofstream dstFile(dstFilename, std::ios::binary);
	assert(dstFile.is_open());

	// Write header
	AssetLib::BinFileHeader header;
	header.binUID = AssetLib::BinFileHeader::kUID;
	header.assetUID = rAssetDef.GetAssetUID();
	header.version = rAssetDef.GetBinVersion();
	header.srcHash = Hashing::SHA1();
	dstFile.write((char*)&header, sizeof(header));

	// Build and write the main geo data
	GeoData geo;
	ObjData obj;

	char line[1024];
	int lineNum = 0; // for debugging

	while (srcFile.getline(line, 1024))
	{
		++lineNum;

		char* context = nullptr;
		char* tok = strtok_s(line, " ", &context);

		if (strcmp(tok, "v") == 0)
		{
			// Position
			Vec3 pos;
			pos.x = (float)atof(strtok_s(nullptr, " ", &context));
			pos.y = (float)atof(strtok_s(nullptr, " ", &context));
			pos.z = (float)atof(strtok_s(nullptr, " ", &context));
			obj.positions.push_back(pos);
		}
		else if (strcmp(tok, "vn") == 0)
		{
			// Normal
			Vec3 norm;
			norm.x = (float)atof(strtok_s(nullptr, " ", &context));
			norm.y = (float)atof(strtok_s(nullptr, " ", &context));
			norm.z = (float)atof(strtok_s(nullptr, " ", &context));
			obj.normals.push_back(norm);
		}
		else if (strcmp(tok, "vt") == 0)
		{
			// Tex coord
			Vec2 uv;
			uv.x = (float)atof(strtok_s(nullptr, " ", &context));
			uv.y = (float)atof(strtok_s(nullptr, " ", &context));
			obj.texcoords.push_back(uv);
		}
		else if (strcmp(tok, "f") == 0)
		{
			// Face
			for (int i = 0; i < 3; ++i)
			{
				ObjVertex objVert;
				objVert.iPos = atoi(strtok_s(nullptr, "/ ", &context)) - 1;
				objVert.iUv = atoi(strtok_s(nullptr, "/ ", &context)) - 1;
				objVert.iNorm = atoi(strtok_s(nullptr, "/ ", &context)) - 1;

				// Find matching vert to re-use.
				int reuseIndex = -1;
				for (int v = (int)obj.verts.size() - 1; v >= 0; --v)
				{
					const ObjVertex& otherVert = obj.verts[v];
					if (otherVert.iPos == objVert.iPos && otherVert.iUv == objVert.iUv && otherVert.iNorm == objVert.iNorm)
					{
						reuseIndex = v;
						break;
					}
				}

				if (reuseIndex >= 0)
				{
					geo.indices.push_back((uint16)reuseIndex);
				}
				else
				{
					geo.indices.push_back((uint16)geo.positions.size());

					Color color = { 1.f, 1.f, 1.f, 1.f };
					geo.positions.push_back(obj.positions[objVert.iPos]);
					geo.texcoords.push_back(obj.texcoords[objVert.iUv]);
					geo.normals.push_back(obj.normals[objVert.iNorm]);
					geo.colors.push_back(color);

					obj.verts.push_back(objVert);
				}
			}
		}
		else if (strcmp(tok, "usemtl") == 0)
		{
			std::string material = strtok_s(nullptr, " ", &context);
			obj.materials.push_back(material);

			obj.subobjectStartIndices.push_back((uint)geo.indices.size());
		}
	}

	obj.subobjectStartIndices.push_back((uint)geo.indices.size());
	geo.tangents.resize(geo.positions.size());
	geo.bitangents.resize(geo.positions.size());

	// TODO: Tangents/bitangents for shared verts
	for (uint i = 0; i < geo.indices.size(); i += 3)
	{
		uint v0 = geo.indices[i + 0];
		uint v1 = geo.indices[i + 1];
		uint v2 = geo.indices[i + 2];
		const Vec3& pos0 = geo.positions[v0];
		const Vec3& pos1 = geo.positions[v1];
		const Vec3& pos2 = geo.positions[v2];
		const Vec2& uv0 = geo.texcoords[v0];
		const Vec2& uv1 = geo.texcoords[v1];
		const Vec2& uv2 = geo.texcoords[v2];

		Vec3 edge1 = pos1 - pos0;
		Vec3 edge2 = pos2 - pos0;

		Vec2 uvEdge1 = uv1 - uv0;
		Vec2 uvEdge2 = uv2 - uv0;

		float r = 1.f / (uvEdge1.y * uvEdge2.x - uvEdge1.x * uvEdge2.y);

		Vec3 tangent = (edge1 * -uvEdge2.y + edge2 * uvEdge1.y) * r;
		Vec3 bitangent = (edge1 * -uvEdge2.x + edge2 * uvEdge1.x) * r;

		tangent = Vec3Normalize(tangent);
		bitangent = Vec3Normalize(bitangent);

		geo.tangents[v0] = geo.tangents[v1] = geo.tangents[v2] = tangent;
		geo.bitangents[v0] = geo.bitangents[v1] = geo.bitangents[v2] = bitangent;
	}

	// Calc radius
	Vec3 vMin(FLT_MAX, FLT_MAX, FLT_MAX);
	Vec3 vMax(-FLT_MIN, -FLT_MIN, -FLT_MIN);
	for (int i = (int)geo.positions.size() - 1; i >= 0; --i)
	{
		vMin.x = std::min(geo.positions[i].x, vMin.x);
		vMax.x = std::max(geo.positions[i].x, vMax.x);
		vMin.y = std::min(geo.positions[i].y, vMin.y);
		vMax.y = std::max(geo.positions[i].y, vMax.y);
		vMin.z = std::min(geo.positions[i].z, vMin.z);
		vMax.z = std::max(geo.positions[i].z, vMax.z);
	}

	Vec3 modelBoundsMin(FLT_MAX, FLT_MAX, FLT_MAX);
	Vec3 modelBoundsMax(-FLT_MIN, -FLT_MIN, -FLT_MIN);
	uint totalVertCount = 0;
	for (int i = 0; i < obj.subobjectStartIndices.size() - 1; ++i)
	{
		AssetLib::Model::SubObject subobj;

		strcpy_s(subobj.materialName, obj.materials[i].c_str());
		subobj.indexCount = obj.subobjectStartIndices[i + 1] - obj.subobjectStartIndices[i];

		uint16 vertMin = -1;
		uint16 vertMax = 0;
		subobj.boundsMin = Vec3(FLT_MAX, FLT_MAX, FLT_MAX);
		subobj.boundsMax = Vec3(-FLT_MIN, -FLT_MIN, -FLT_MIN);
		for (uint tri = obj.subobjectStartIndices[i]; tri < obj.subobjectStartIndices[i + 1]; ++tri)
		{
			uint16 iVert = geo.indices[tri];
			vertMin = std::min(iVert, vertMin);
			vertMax = std::max(iVert, vertMax);

			subobj.boundsMin.x = std::min(geo.positions[iVert].x, subobj.boundsMin.x);
			subobj.boundsMax.x = std::max(geo.positions[iVert].x, subobj.boundsMax.x);
			subobj.boundsMin.y = std::min(geo.positions[iVert].y, subobj.boundsMin.y);
			subobj.boundsMax.y = std::max(geo.positions[iVert].y, subobj.boundsMax.y);
			subobj.boundsMin.z = std::min(geo.positions[iVert].z, subobj.boundsMin.z);
			subobj.boundsMax.z = std::max(geo.positions[iVert].z, subobj.boundsMax.z);
		}

		subobj.vertCount = (vertMax - vertMin) + 1;
		totalVertCount += subobj.vertCount;

		modelBoundsMin = Vec3Min(modelBoundsMin, subobj.boundsMin);
		modelBoundsMax = Vec3Max(modelBoundsMax, subobj.boundsMax);

		geo.subobjects.push_back(subobj);
	}

	assert(totalVertCount == (uint)geo.positions.size());

	AssetLib::Model modelBin;
	modelBin.totalVertCount = totalVertCount;
	modelBin.totalIndexCount = (uint)geo.indices.size();
	modelBin.boundsMin = modelBoundsMin;
	modelBin.boundsMax = modelBoundsMax;
	modelBin.subObjectCount = (uint)geo.subobjects.size();
	modelBin.subobjects.offset = 0;
	modelBin.positions.offset = modelBin.subobjects.offset + modelBin.subobjects.CalcSize(modelBin.subObjectCount);
	modelBin.texcoords.offset = modelBin.positions.offset + modelBin.positions.CalcSize(totalVertCount);
	modelBin.normals.offset = modelBin.texcoords.offset + modelBin.texcoords.CalcSize(totalVertCount);
	modelBin.colors.offset = modelBin.normals.offset + modelBin.normals.CalcSize(totalVertCount);
	modelBin.tangents.offset = modelBin.colors.offset + modelBin.colors.CalcSize(totalVertCount);
	modelBin.bitangents.offset = modelBin.tangents.offset + modelBin.tangents.CalcSize(totalVertCount);
	modelBin.indices.offset = modelBin.bitangents.offset + modelBin.bitangents.CalcSize(totalVertCount);

	dstFile.write((char*)&modelBin, sizeof(AssetLib::Model));
	dstFile.write((char*)geo.subobjects.data(), sizeof(geo.subobjects[0]) * geo.subobjects.size());
	dstFile.write((char*)geo.positions.data(), sizeof(geo.positions[0]) * geo.positions.size());
	dstFile.write((char*)geo.texcoords.data(), sizeof(geo.texcoords[0]) * geo.texcoords.size());
	dstFile.write((char*)geo.normals.data(), sizeof(geo.normals[0]) * geo.normals.size());
	dstFile.write((char*)geo.colors.data(), sizeof(geo.colors[0]) * geo.colors.size());
	dstFile.write((char*)geo.tangents.data(), sizeof(geo.tangents[0]) * geo.tangents.size());
	dstFile.write((char*)geo.bitangents.data(), sizeof(geo.bitangents[0]) * geo.bitangents.size());
	dstFile.write((char*)geo.indices.data(), sizeof(geo.indices[0]) * geo.indices.size());

	return true;
}
Ejemplo n.º 17
0
Archivo: pivot.c Proyecto: cran/WGCNA
double pivot_weighted(double * v, size_t from, size_t to, double target,
                      double * w, double * csw)
{
  // Rprintf("Entering pivot with len=%d and target=%f\n   ", len, target);
  // RprintV(v, len);

  size_t len = to-from;
  if (len > 2)
  {
    // pick the pivot, say as the median of the first, middle and last
    size_t i1 = from, i2 = to-1, i3 = (from + to)/2, ip;
    if (v[i1] <= v[i2])
    {
      if (v[i2] <= v[i3])
        ip = i2;
      else if (v[i3] >= v[i1])
         ip = i3;
      else 
         ip = i1;
    } else {
      if (v[i1] <= v[i3])
        ip = i1;
      else if (v[i2] <= v[i3])
        ip = i3;
      else
        ip = i2;
    }

    // put v[ip] at the end
    double vp, wp;
    swap(v[ip], v[to-1], vp);
    swap(w[ip], w[to-1], wp);

    // Rprintf("   pivot value: %5.3f, index: %d\n", vp, ip);

    // pivot everything else
    size_t bound = from;
    for (size_t i=from; i<to; i++) if (v[i] < vp)
    {
      double temp;
      swap(v[bound], v[i], temp);
      swap(w[bound], w[i], temp)
      bound++;
    }

    v[len-1] = v[bound]; v[bound] = vp;
    w[len-1] = w[bound]; w[bound] = wp;

    // Update the cumulative sums

    double sum = from > 0 ? csw[from-1] : 0;
    for (size_t i=from; i<to; i++)
    {
       sum = sum + w[i];
       csw[i] = sum;
    }

    // Rprintf("   After pivoting: bound:%d and vector: ", bound); // RprintV(v, len);

    // Did we find the target?
    
    double crit = target - bound;
    // Rprintf("   crit: %5.3f\n", crit);
    if (fabs(crit) > 1.0)
    {
      if (crit < 0)
        return pivot(v, bound, target);
      else
        return pivot(v+bound+1, len-bound-1, target-bound-1);
    }
    // Rprintf("vMax(v, bound): %5.3f, vMin(v+bound+1, len-bound-1): %5.3f, vp: %5.3f\n", vMax(v, bound),
                // vMin(v+bound+1, len-bound-1), vp);
    if (crit < 0)
    {
       double v1 = vMax(v, bound);
       return (v1 *(-crit) + vp * (1+crit));
    } // else
    double v2 = vMin(v+bound+1, len-bound-1);
    return (vp * (1-crit) + v2 * crit);
  } 
  else if (len==2)
  {
      // Rprintf("  Short v, returning a direct value.\n"); 
      double v1 = vMin(v, 2);
      double v2 = vMax(v, 2);
      if (target < 0) return v1;
      else if (target > 1) return v2;
      else return (target * v2 + (1-target) * v1);
  }
  else 
  {
     // Rprintf("  length 1 v, returning a direct value.\n"); 
     return v[0];
  }
}
Ejemplo n.º 18
0
HRESULT CCubeCol::CreateBuffer(void)
{
	//여기
	HRESULT hr = E_FAIL;
	m_iVertexStrides = sizeof(VTXCOL);
	m_iVertexOffsets = 0;

	D3DXVECTOR3 vMin(-1.f, -1.f, -1.f);
	D3DXVECTOR3 vMax(1.f, 1.f, 1.f);


	VTXCOL Vertex[] =
	{
		{ D3DXVECTOR3(vMin.x, vMax.y, vMin.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMax.x, vMax.y, vMin.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMax.x, vMin.y, vMin.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMin.x, vMin.y, vMin.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMin.x, vMax.y, vMax.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMax.x, vMax.y, vMax.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMax.x, vMin.y, vMax.z), D3DXCOLOR(1,0,0,1) },
		{ D3DXVECTOR3(vMin.x, vMin.y, vMax.z), D3DXCOLOR(1,0,0,1) },
	};

	D3D11_BUFFER_DESC vbd; // 버퍼 디스크 = 버퍼의 용도와 크기와 접근권한
	ZeroMemory(&vbd, sizeof(vbd));
	vbd.Usage = D3D11_USAGE_DEFAULT; // 버퍼는 연산을 위해 필요한 것인대 하드웨어에서 연산이 가능한 객체는 2개가있음 CPU, GPU
	vbd.ByteWidth = sizeof(VTXCOL) * 8; // 크기
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // 용도 = 버퍼는 3개가 있음. 버텍스, 인덱스, 콘스턴트 
	vbd.CPUAccessFlags = 0;
	vbd.MiscFlags = 0;
	vbd.StructureByteStride = 0;

	D3D11_SUBRESOURCE_DATA vBufferData; // 서브리소스는 데이터인대 = 실질적인 값을 의미함
	ZeroMemory(&vBufferData, sizeof(D3D11_SUBRESOURCE_DATA));
	vBufferData.pSysMem = Vertex;
	hr = CDevice::GetInstance()->m_pDevice->CreateBuffer(&vbd, &vBufferData, &m_VertexBuffer);

	if (FAILED(hr))
		return E_FAIL;


	UINT Index[] =
	{
		//+x
		1, 5, 6,
		1, 6, 2,
		//-x
		4, 0, 3,
		4, 3, 7,
		//+y
		4, 5, 1,
		4, 3, 7,
		//-y
		3, 2, 6,
		3, 6, 7,
		//+z
		7, 6, 5,
		7, 5, 4,
		//-z
		0, 1, 2,
		0, 2, 3,
	};

	m_iIndex = 36;

	D3D11_BUFFER_DESC ibd; // 권한/크기/용도
	ibd.Usage = D3D11_USAGE_DEFAULT; // 권한
	ibd.ByteWidth = sizeof(UINT) * m_iIndex; // 크기
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; // 용도
	ibd.CPUAccessFlags = 0; // CPU접근권한 설정
	ibd.MiscFlags = 0;
	ibd.StructureByteStride = 0;
	D3D11_SUBRESOURCE_DATA iinitData; // 실제 데이터
	iinitData.pSysMem = Index;
	hr = CDevice::GetInstance()->m_pDevice->CreateBuffer(&ibd, &iinitData, &m_IndexBuffer);

	if (FAILED(hr))
		return E_FAIL;


	//다이렉트9 != 다이렉트11
	//다이렉트9 = 컨스턴트 테이블이 존재 수 많은 글로벌 변수가 값은 채워지지 않고 할당만 되어있었음 = 메모리 낭비
	//다이렉트11 = 상수는 약속을함 상수 버퍼가 채워지지 않으면 셰이더가 작동하지않음 = 메모리 최적화

	D3D11_BUFFER_DESC cbd; // 접근권한 / 용도/ 크기
	cbd.Usage = D3D11_USAGE_DEFAULT;
	cbd.ByteWidth = sizeof(ConstantBuffer);
	cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cbd.CPUAccessFlags = 0;
	cbd.MiscFlags = 0;
	cbd.StructureByteStride = 0;
	hr = CDevice::GetInstance()->m_pDevice->CreateBuffer(&cbd, NULL, &m_ConstantBuffer);

	/*D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DYNAMIC; // CPU에게 읽기를 할수있는 권한을 주심
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // 라이트의 권한을 주었지 ㅇㅋ?
	CDevice::GetInstance()->m_pDevice->CreateBuffer(&bd, NULL, &m_ConstantBuffer);*/


	if (FAILED(hr))
	{
		MessageBox(NULL, L"System Message", L"Constant Buffer Error", MB_OK);
		return hr;

	}

	return S_OK;
}
Ejemplo n.º 19
0
static bool RecursivelyBuildBSP(CLightBSPNode** ppNode, PrePolyArray& PolyList, CLightBSPPoly** ppBSPPolyList)
{
	//sanity check
	ASSERT(ppNode);
	ASSERT(PolyList.GetSize() > 0);

	//number of polies that lie on the plane
	uint32 nNumLieOn, nFront, nBack;

	//first off, find the best splitting plane
	uint32 nSplitPlane = FindBestSplitPlane(PolyList, nNumLieOn, nFront, nBack);

	//allocate the new node
	*ppNode = AllocateBSPNode(nNumLieOn);

	//check for memory failure
	if(*ppNode == NULL)
		return false;

	//setup the node
	(*ppNode)->m_vPlaneNorm = PolyList[nSplitPlane]->Normal();
	(*ppNode)->m_fPlaneDist = PolyList[nSplitPlane]->Dist();

	//create the front, back, and on arrays
	PrePolyArray	Front, Back, On;
	Front.SetSize(nFront);
	Back.SetSize(nBack);
	On.SetSize(nNumLieOn);

	//now fill up all the lists
	PVector vNormal = PolyList[nSplitPlane]->Normal();
	float	fDist	= PolyList[nSplitPlane]->Dist();

	//index to the coplanar poly offset
	uint32 nPolyIndex = 0;

	//indices for the lists
	uint32 nFrontIndex	= 0;
	uint32 nBackIndex	= 0;
	uint32 nOnIndex		= 0;

	uint32 nType;

	//now need to count up the split information
	for(uint32 nTestPoly = 0; nTestPoly < PolyList.GetSize(); nTestPoly++)
	{
		if(nTestPoly == nSplitPlane)
		{
			On[nOnIndex++] = PolyList[nTestPoly];
			(*ppNode)->m_pPolyList[nPolyIndex++] = ppBSPPolyList[PolyList[nTestPoly]->m_Index];
			continue;
		}

		nType = ClassifyPoly(vNormal, fDist, PolyList[nTestPoly]);

		if(nType & PLANE_FRONT)
			Front[nFrontIndex++] = PolyList[nTestPoly];
		if(nType & PLANE_BACK)
			Back[nBackIndex++] = PolyList[nTestPoly];
		if(nType == PLANE_ON)
		{
			On[nOnIndex++] = PolyList[nTestPoly];
			(*ppNode)->m_pPolyList[nPolyIndex++] = ppBSPPolyList[PolyList[nTestPoly]->m_Index];
		}
	}

	//sanity check
	ASSERT(nPolyIndex == (*ppNode)->m_nNumPolies);
	ASSERT(nFrontIndex == nFront);
	ASSERT(nBackIndex == nBack);
	ASSERT(nOnIndex == nNumLieOn);

	//build up the child lists
	bool bSuccess = true;

	if(Front.GetSize() > 0)
	{
		bSuccess = RecursivelyBuildBSP(&(*ppNode)->m_pFront, Front, ppBSPPolyList);
	}
	if(bSuccess && (Back.GetSize() > 0))
	{
		bSuccess = RecursivelyBuildBSP(&(*ppNode)->m_pBack, Back, ppBSPPolyList);
	}

	//see if we need to clean up
	if(!bSuccess)
	{
		FreeBSPNode(*ppNode);
		*ppNode = NULL;
		return false;
	}

	//we need to update the node's bounding sphere. This is done by running through all
	//the polygons on the plane and generating a bounding box, finding its center, and then
	//the maximum distance to the points
	PVector vMin((PReal)MAX_CREAL, (PReal)MAX_CREAL, (PReal)MAX_CREAL);
	PVector vMax(-vMin);

	uint32 nCurrPoly;
	for(nCurrPoly = 0; nCurrPoly < nNumLieOn; nCurrPoly++)
	{
		CPrePoly* pPoly = On[nCurrPoly];
		for(uint32 nCurrVert = 0; nCurrVert < pPoly->NumVerts(); nCurrVert++)
		{
			VEC_MIN(vMin, vMin, pPoly->Pt(nCurrVert));
			VEC_MAX(vMax, vMax, pPoly->Pt(nCurrVert));
		}
	}

	//found the center
	(*ppNode)->m_vBSphereCenter = ((vMin + vMax) / 2);

	//now update the radius
	(*ppNode)->m_fBSphereRadSqr = 0;

	PReal fDistSqr;

	for(nCurrPoly = 0; nCurrPoly < nNumLieOn; nCurrPoly++)
	{
		CPrePoly* pPoly = On[nCurrPoly];
		for(uint32 nCurrVert = 0; nCurrVert < pPoly->NumVerts(); nCurrVert++)
		{
			fDistSqr = (pPoly->Pt(nCurrVert) - (*ppNode)->m_vBSphereCenter).MagSqr();

			if(fDistSqr > (*ppNode)->m_fBSphereRadSqr)
			{
				(*ppNode)->m_fBSphereRadSqr = fDistSqr;
			}
		}
	}
	
	//add some padding to the radius to compensate for inaccuracy
	(*ppNode)->m_fBSphereRadSqr += NODE_RADIUS_PADDING;

	return bSuccess;	
}
Ejemplo n.º 20
0
/*-------------------------------------
doThreshAnalysis
description: this is the main analysis function. It does some of the analysis,
    and delegates some responsibility to more specific doThreshAnalysis function
input: TaskType &taskType - the struct that tells the function which analyses to
    perform for this task
output: vector<basicStats> - an array of statistics structures for each analyses
    (e.g., video, audio, etc)
*/
bool analysis::doThreshAnalysis()
{
    //reset the latencyStats vector
    latencyStats.clear();

    //if for some reason the file has not been read, return
    if (!mIsOpen)
        return false;

    //do the amp latency analysis
    //the task type struct has a flag for each possible analysis, which tells if
    //we should perform the analysis
    basicStats ampStats;
    if (thisTask.amp.flag)
    {
        //the amp analysis does not depend on any specific state, so just do the
        //analysis on the specified channel based on the latency from the block start
        ampStats = doThreshAnalysis(thisTask.amp.ch);
        ampStats.taskName = "Amp     ";
        // add the stats to the stats vector
        latencyStats.push_back(ampStats);

        //check for dropped samples on this channel
        checkDroppedSamples(thisTask.amp.ch);
    }

    //do the analysis on each state for the video
    basicStats vidSystemStats;
    if (thisTask.vid.flag)
    {
        //do the video analysis on the channel and state specified
        vidSystemStats = doThreshAnalysis(thisTask.vid.ch, thisTask.vid.state, thisTask.vid.stateVal);
        vidSystemStats.taskName = "VidSys  ";
        latencyStats.push_back(vidSystemStats);

        checkDroppedSamples(thisTask.vid.ch);
    }

    //do the analysis on each state for the audio
    basicStats audSystemStats;
    if (thisTask.aud.flag)
    {
        audSystemStats = doThreshAnalysis(thisTask.aud.ch, thisTask.aud.state, thisTask.aud.stateVal);
        audSystemStats.taskName = "AudSys  ";
        latencyStats.push_back(audSystemStats);

        checkDroppedSamples(thisTask.aud.ch);
    }

	//do the processing latency and metronome
    //first, get the "metronome" stats, the difference in time between each block source time
    map<string, double*>::iterator it; //an iterator for the states map

    //declare double vectors for the metronome and processing latencies
    vector<double> metronomeDiff;
    vector<double> procLat;

    //declare variables to track previous values of the stim and source times
	double stimT, oldStimT, sourceT, oldSourceT, prevSourceT;

    //get the first values for stim/source times
	oldStimT =  states["StimulusTime"][0];
	oldSourceT = prevSourceT = states["SourceTime"][0];
	float nMod1 = 0, nMod2 = 0;
    //loop through the states, starting at the 2nd block, and increase
    //by the block size
	for (int i = blockSize; i < nSamples; i += blockSize)
	{
		stimT = states["StimulusTime"][i];
        sourceT = states["SourceTime"][i];

        //nMod1 and nMod2 track the times, which are short (16bit) integers
        //if the new stim is less than the oldStim, we have wrapped around
        //and so we must correct for this
        if (stimT-oldStimT < 0)
            nMod1++;
        if (sourceT-oldSourceT < 0)
            nMod2++;

        //the processing latency is the difference between the stimulus time and
        //source time; if we have wrapped the times, the nModX variable corrects this
		double procDT = ((stimT+nMod1*65535) - (sourceT+nMod2*65535));

        //the jitter/metronome is the difference between the current sourceTime
        //minus the previous source time
        //additionally, we are putting this in relation to the "theoretical" value,
        //which is the blockSize, and converting this to ms
		double jitter = abs(((sourceT+nMod2*65535)-prevSourceT) - blockSize/sampleRate*1000);

        //add the jitter and processing latencies to their respective arrays
		metronomeDiff.push_back(jitter);
        procLat.push_back(procDT);

        //update stim and source times
        oldStimT = stimT;
        oldSourceT = sourceT;
        prevSourceT = (sourceT+nMod2*65535);
    }

    //calculate the stats for the processing latency using our vector helper functions
	basicStats procStats;
	procStats.mean = vMean(&procLat);
	procStats.std = vStd(&procLat);
	procStats.min = vMin(&procLat);
	procStats.max = vMax(&procLat);
	//procStats.vals = procLat;
    procStats.taskName = "ProcLat ";
    procStats.desc = "StimulusTime - SourceTime";

    //...now do the same for the metronome
    basicStats metronome;
	metronome.mean = vMean(&metronomeDiff);
	metronome.max = vMax(&metronomeDiff);
	metronome.min = vMin(&metronomeDiff);
	metronome.std = vStd(&metronomeDiff);
    metronome.taskName = "Jitter  ";
    metronome.desc = "SourceTime[t+1] - SourceTime[t]";

    //add these to the task stats array
    latencyStats.push_back(metronome);
    latencyStats.push_back(procStats);

    //if we did the amp and video latencies, then we can also calculate the
    //video system latency (actually, the video latency calculate above is the
    //video system latency, so we use that to find the output latency as:
    // vidOut = vidSys - amp - procLat)
    if (thisTask.amp.flag && thisTask.vid.flag)
    {
        basicStats vidOutputStats;
        vidOutputStats.mean = vidSystemStats.mean - ampStats.mean - procStats.mean;
		vidOutputStats.std = sqrt(pow(vidSystemStats.std,2) + pow(ampStats.std,2) + pow(procStats.std,2));
        vidOutputStats.min = vidSystemStats.min - ampStats.min - procStats.min;
        vidOutputStats.max = vidSystemStats.max - ampStats.max - procStats.max;
        vidOutputStats.taskName = "VidOut  ";
        vidOutputStats.desc = "Video output latency";
        latencyStats.push_back(vidOutputStats);
    }

    //same as the video stats above
    if (thisTask.amp.flag && thisTask.aud.flag)
    {
        basicStats audOutputStats;
        audOutputStats.mean = audSystemStats.mean - ampStats.mean - procStats.mean;
		audOutputStats.std = sqrt(pow(audSystemStats.std,2) + pow(ampStats.std,2) + pow(procStats.std,2));
        audOutputStats.min = audSystemStats.min - ampStats.min - procStats.min;
        audOutputStats.max = audSystemStats.max - ampStats.max - procStats.max;
        audOutputStats.taskName = "AudOut  ";
        audOutputStats.desc = "Audio output latency";
        latencyStats.push_back(audOutputStats);
    }

    //return our stats
    return true;
}