Esempio n. 1
0
	INT32 GUIInputTool::getCharIdxAtPos(const Vector2I& pos) const
	{
		Vector2 vecPos((float)pos.x, (float)pos.y);

		UINT32 lineStartChar = 0;
		UINT32 lineEndChar = 0;
		UINT32 numNewlineChars = 0;
		UINT32 lineIdx = 0;
		for(auto& line : mLineDescs)
		{
			INT32 lineStart = line.getLineYStart() + getTextOffset().y;
			if(pos.y >= lineStart && pos.y < (lineStart + (INT32)line.getLineHeight()))
			{
				lineStartChar = line.getStartChar();
				lineEndChar = line.getEndChar(false);
				break;
			}

			// Newline chars count in the startChar/endChar variables, but don't actually exist in the buffers
			// so we need to filter them out
			numNewlineChars += (line.hasNewlineChar() ? 1 : 0); 

			lineIdx++;
		}

		UINT32 lineStartQuad = lineStartChar - numNewlineChars;
		UINT32 lineEndQuad = lineEndChar - numNewlineChars;

		float nearestDist = std::numeric_limits<float>::max();
		UINT32 nearestChar = 0;
		bool foundChar = false;

		Vector2I textOffset = getTextOffset();
		for(UINT32 i = lineStartQuad; i < lineEndQuad; i++)
		{
			UINT32 curVert = i * 4;

			float centerX = mQuads[curVert + 0].x + mQuads[curVert + 1].x;
			centerX *= 0.5f;
			centerX += textOffset.x;

			float dist = Math::abs(centerX - vecPos.x);
			if(dist < nearestDist)
			{
				nearestChar = i + numNewlineChars;
				nearestDist = dist;
				foundChar = true;
			}
		}

		if(!foundChar)
			return -1;

		return nearestChar;
	}
Esempio n. 2
0
	bool GUIWidget::inBounds(const Vector2I& position) const
	{
		Viewport* target = getTarget();
		if (target == nullptr)
			return false;

		// Technically GUI widget bounds can be larger than the viewport, so make sure we clip to viewport first
		if(!target->getArea().contains(position))
			return false;

		Vector3 vecPos((float)position.x, (float)position.y, 0.0f);
		vecPos = mTransform.inverse().multiplyAffine(vecPos);

		Vector2I localPos(Math::roundToInt(vecPos.x), Math::roundToInt(vecPos.y));
		return mBounds.contains(localPos);
	}
void CWndChangeSex::OnDraw( C2DRender* p2DRender ) 
{ 
	if( g_pPlayer == NULL  )
		return;

	LPDIRECT3DDEVICE9 pd3dDevice = p2DRender->m_pd3dDevice;

	pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
	pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );

	pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
	pd3dDevice->SetSamplerState ( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
	pd3dDevice->SetSamplerState ( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

	pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );

	pd3dDevice->SetRenderState( D3DRS_AMBIENT,  D3DCOLOR_ARGB( 255, 255,255,255) );
	
	CRect rect = GetClientRect();

	// 뷰포트 세팅 
	D3DVIEWPORT9 viewport;

	// 월드 
	D3DXMATRIXA16 matWorld;
	D3DXMATRIXA16 matScale;
	D3DXMATRIXA16 matRot;
	D3DXMATRIXA16 matTrans;

	// 카메라 
	D3DXMATRIX  matView;
	D3DXVECTOR3 vecLookAt( 0.0f, 0.0f, 3.0f );
	D3DXVECTOR3 vecPos(  0.0f, 0.7f, -3.5f );
	
	D3DXMatrixLookAtLH( &matView, &vecPos, &vecLookAt, &D3DXVECTOR3(0.0f,1.0f,0.0f) );
	
	pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
	
	// 왼쪽 원본 모델 랜더링
	{
		LPWNDCTRL lpFace = GetWndCtrl( WIDC_STATIC1 );

		viewport.X      = p2DRender->m_ptOrigin.x + lpFace->rect.left;//2;
		viewport.X     -= 6;
		viewport.Y      = p2DRender->m_ptOrigin.y + lpFace->rect.top;//5;
		viewport.Width  = lpFace->rect.Width();//p2DRender->m_clipRect.Width();
		viewport.Height = lpFace->rect.Height();// - 10;//p2DRender->m_clipRect.Height();

		viewport.MinZ   = 0.0f;
		viewport.MaxZ   = 1.0f;
		pd3dDevice->SetViewport(&viewport);
		pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0xffa08080, 1.0f, 0 ) ;

		D3DXMATRIX matProj;
		D3DXMatrixIdentity( &matProj );
		FLOAT fAspect = ((FLOAT)viewport.Width) / (FLOAT)viewport.Height;
/*		
		D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4.0f, fAspect, CWorld::m_fNearPlane - 0.01f, CWorld::m_fFarPlane );
		pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
*/		
		FLOAT fov = D3DX_PI/4.0f;//796.0f;
		FLOAT h = cos(fov/2) / sin(fov/2);
		FLOAT w = h * fAspect;
		D3DXMatrixOrthoLH( &matProj, w, h, CWorld::m_fNearPlane - 0.01f, CWorld::m_fFarPlane );
		pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
		
	    D3DXMatrixIdentity(&matScale);
		D3DXMatrixIdentity(&matTrans);
		D3DXMatrixIdentity(&matWorld);
		
		D3DXMatrixScaling(&matScale, 4.5f, 4.5f, 4.5f);
		
		if( g_pPlayer->GetSex() == SEX_MALE )
			D3DXMatrixTranslation(&matTrans,0.0f,-5.6f,0.0f);
		else
			D3DXMatrixTranslation(&matTrans,0.0f,-5.8f,0.0f);

		D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);
		D3DXMatrixMultiply(&matWorld, &matWorld, &matTrans );
		pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

		// 랜더링 
		pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
		pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );//m_bViewLight );
		
		::SetLight( FALSE );
		::SetFog( FALSE );
		SetDiffuse( 1.0f, 1.0f, 1.0f );
		SetAmbient( 1.0f, 1.0f, 1.0f );
/*
		m_pModel->GetObject3D(PARTS_HAIR)->m_fAmbient[0] = 0.5f;
		m_pModel->GetObject3D(PARTS_HAIR)->m_fAmbient[1] = 0.5f;
		m_pModel->GetObject3D(PARTS_HAIR)->m_fAmbient[2] = 0.5f;
*/		
		D3DXVECTOR4 vConst( 1.0f, 1.0f, 1.0f, 1.0f );
#ifdef __YENV
		D3DXVECTOR3 vDir( 0.0f, 0.0f, 1.0f );
		SetLightVec( vDir );
		
		g_Neuz.m_pEffect->SetVector( g_Neuz.m_hvFog, &vConst );
#else //__YENV						
		pd3dDevice->SetVertexShaderConstantF( 95, (float*)&vConst, 1 );
#endif //__YENV
		::SetTransformView( matView );
		::SetTransformProj( matProj );
				
		m_pModel->Render( p2DRender->m_pd3dDevice, &matWorld );
	}
} 
Esempio n. 4
0
// 初期化
IZ_BOOL CMyAppl::Init(
	HINSTANCE hInst,
	HWND hDeviceWindow,
	HWND hFocusWindow)
{
	static const IZ_UINT MEM_SIZE = 16 * 1024 * 1024;	// 16MB
	static IZ_UINT8 MEM_BUF[MEM_SIZE];

	// システム初期化
	IZ_BOOL ret = CMySystem::GetInstance().Init(MEM_SIZE, MEM_BUF);
	VRETURN(ret);

	// グラフィックスデバイス設定
	izanagi::SGraphicsDeviceInitParams sParams;
	{
		sParams.hFocusWindow = hFocusWindow;
		sParams.hDeviceWindow = hDeviceWindow;
		
		sParams.Windowed = IZ_TRUE;						// 画面モード(ウインドウモード)

		sParams.BackBufferWidth = SCREEN_WIDTH;			// バックバッファの幅
		sParams.BackBufferHeight = SCREEN_HEIGHT;		// バックバッファの高さ

		sParams.MultiSampleType = D3DMULTISAMPLE_NONE;	// マルチ・サンプリングの種類

		sParams.Adapter = D3DADAPTER_DEFAULT;
		sParams.DeviceType = D3DDEVTYPE_HAL;
		sParams.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;

		sParams.DepthStencilFormat = D3DFMT_D24S8;

		sParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
	}

	// デバイスリセット
	ret = CMySystem::GetInstance().GetGraphicsDevice()->Reset(sParams);
	VRETURN(ret);

	// デバッグフォント初期化
	ret = CMySystem::GetInstance().InitDebugFont();
	VRETURN(ret);

	// リセット用コールバックセット
	//CMySystem::GetInstance().GetGraphicsDevice()->SetResetCallBack(_ResetResource);

	// ステート初期化
	ret = CStateManager::GetInstance().Init();
	VRETURN(ret);

	// カメラ初期化
	{
		izanagi::math::CVector vecPos(0.0f, 0.0f, 20.0f, 1.0f);
		izanagi::math::CVector vecRef(0.0f, 0.0f, 0.0f, 1.0f);
		izanagi::math::CVector vecUp(0.0f, 1.0f, 0.0f, 1.0f);

		CMyCamera::GetInstance().Init(
			vecPos, vecRef, vecUp,
			1.0f, 1000.0f,
			izanagi::math::CMath::Deg2Rad(90.0f),
			(IZ_FLOAT)SCREEN_WIDTH / SCREEN_HEIGHT);
	}

#if 1
	// パッド初期化
	{
		D_INPUT* pInput = NULL;
		HRESULT hr = DirectInput8Create(
						hInst,
						DIRECTINPUT_VERSION,
						IID_IDirectInput8,
						(void**)&pInput,
						NULL);
		IZ_ASSERT(SUCCEEDED(hr));
		
		ret = CMySystem::GetInstance().InitKeyboard();
		if (ret) {
			izanagi::SInputDeviceInitParam sInitParam(pInput, hDeviceWindow);
			CMySystem::GetInstance().GetKeyboard()->Init(&sInitParam);
		}

		pInput->Release();

		//VRETURN(ret);
	}
#endif

	return IZ_TRUE;
}
Esempio n. 5
0
bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint32 timerDelta) {
	if (!particle) {
		return STATUS_FAILED;
	}
	if (_sprites.size() == 0) {
		return STATUS_FAILED;
	}

	int posX = BaseUtils::randomInt(_posX, _posX + _width);
	int posY = BaseUtils::randomInt(_posY, _posY + _height);
	float posZ = BaseUtils::randomFloat(0.0f, 100.0f);

	float velocity;
	if (_velocityZBased) {
		velocity = _velocity1 + posZ * (_velocity2 - _velocity1) / 100;
	} else {
		velocity = BaseUtils::randomFloat(_velocity1, _velocity2);
	}

	float scale;
	if (_scaleZBased) {
		scale = _scale1 + posZ * (_scale2 - _scale1) / 100;
	} else {
		scale = BaseUtils::randomFloat(_scale1, _scale2);
	}

	int lifeTime;
	if (_lifeTimeZBased) {
		lifeTime = (int)(_lifeTime2 - posZ * (_lifeTime2 - _lifeTime1) / 100);
	} else {
		lifeTime = BaseUtils::randomInt(_lifeTime1, _lifeTime2);
	}

	float angle = BaseUtils::randomAngle(_angle1, _angle2);
	int spriteIndex = BaseUtils::randomInt(0, _sprites.size() - 1);

	float rotation = BaseUtils::randomAngle(_rotation1, _rotation2);
	float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2);
	float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2);

	if (!BasePlatform::isRectEmpty(&_border)) {
		int thicknessLeft   = (int)(_borderThicknessLeft   - (float)_borderThicknessLeft   * posZ / 100.0f);
		int thicknessRight  = (int)(_borderThicknessRight  - (float)_borderThicknessRight  * posZ / 100.0f);
		int thicknessTop    = (int)(_borderThicknessTop    - (float)_borderThicknessTop    * posZ / 100.0f);
		int thicknessBottom = (int)(_borderThicknessBottom - (float)_borderThicknessBottom * posZ / 100.0f);

		particle->_border = _border;
		particle->_border.left += thicknessLeft;
		particle->_border.right -= thicknessRight;
		particle->_border.top += thicknessTop;
		particle->_border.bottom -= thicknessBottom;
	}

	Vector2 vecPos((float)posX, (float)posY);
	Vector2 vecVel(0, velocity);

	Matrix4 matRot;
	matRot.rotationZ(Common::deg2rad(BaseUtils::normalizeAngle(angle - 180)));
	matRot.transformVector2(vecVel);

	if (_alphaTimeBased) {
		particle->_alpha1 = _alpha1;
		particle->_alpha2 = _alpha2;
	} else {
		int alpha = BaseUtils::randomInt(_alpha1, _alpha2);
		particle->_alpha1 = alpha;
		particle->_alpha2 = alpha;
	}

	particle->_creationTime = currentTime;
	particle->_pos = vecPos;
	particle->_posZ = posZ;
	particle->_velocity = vecVel;
	particle->_scale = scale;
	particle->_lifeTime = lifeTime;
	particle->_rotation = rotation;
	particle->_angVelocity = angVelocity;
	particle->_growthRate = growthRate;
	particle->_exponentialGrowth = _exponentialGrowth;
	particle->_isDead = DID_FAIL(particle->setSprite(_sprites[spriteIndex]));
	particle->fadeIn(currentTime, _fadeInTime);


	if (particle->_isDead) {
		return STATUS_FAILED;
	} else {
		return STATUS_OK;
	}
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// Name: FrameMove
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
    HRESULT hr;

    //
    // Process keyboard input
    //

    D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);

    if(m_bKey[VK_NUMPAD1] || m_bKey[VK_LEFT])  vecT.x -= 1.0f; // Slide Left
    if(m_bKey[VK_NUMPAD3] || m_bKey[VK_RIGHT]) vecT.x += 1.0f; // Slide Right
    if(m_bKey[VK_DOWN])                        vecT.y -= 1.0f; // Slide Down
    if(m_bKey[VK_UP])                          vecT.y += 1.0f; // Slide Up
    if(m_bKey['W'])                            vecT.z -= 2.0f; // Move Forward
    if(m_bKey['S'])                            vecT.z += 2.0f; // Move Backward
    if(m_bKey['A'] || m_bKey[VK_NUMPAD8])      vecR.x -= 1.0f; // Pitch Down
    if(m_bKey['Z'] || m_bKey[VK_NUMPAD2])      vecR.x += 1.0f; // Pitch Up
    if(m_bKey['E'] || m_bKey[VK_NUMPAD6])      vecR.y -= 1.0f; // Turn Right
    if(m_bKey['Q'] || m_bKey[VK_NUMPAD4])      vecR.y += 1.0f; // Turn Left
    if(m_bKey[VK_NUMPAD9])                     vecR.z -= 2.0f; // Roll CW
    if(m_bKey[VK_NUMPAD7])                     vecR.z += 2.0f; // Roll CCW

    m_vecVelocity = m_vecVelocity * 0.9f + vecT * 0.1f;
    m_vecAngularVelocity = m_vecAngularVelocity * 0.9f + vecR * 0.1f;



    //
    // Update position and view matricies
    //

    D3DXMATRIX matT, matR;
    D3DXQUATERNION qR;

    vecT = m_vecVelocity * m_fElapsedTime * m_fSpeed;
    vecR = m_vecAngularVelocity * m_fElapsedTime * m_fAngularSpeed;

    D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
    D3DXMatrixMultiply(&m_matPosition, &matT, &m_matPosition);

    D3DXQuaternionRotationYawPitchRoll(&qR, vecR.y, vecR.x, vecR.z);
    D3DXMatrixRotationQuaternion(&matR, &qR);

    D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
    D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);


    //
    // Update simulation
    //

    if(!m_bPause && m_bDrawWater)
    {
        BOOL bCaustics = m_bDrawCaustics && m_pEffect->IsParameterUsed("tCAU");
        D3DXVECTOR3 vecPos(m_matPosition._41, m_matPosition._42, m_matPosition._43);
        D3DXVECTOR3 vecLight(0.0f, 1.0f, 0.0f);

        m_Water.Update(vecPos, vecLight, bCaustics);
        m_fTime += m_fSecsPerFrame;

        if(bCaustics)
        {
            if(SUCCEEDED(m_pRenderToSurface->BeginScene(m_pCausticSurf, NULL)))
            {
                D3DXMATRIX matProj;
                D3DXMATRIX matView;

                D3DXMatrixOrthoRH(&matProj, 63.0f, 63.0f, 1.0f, 100.0f);
                D3DXMatrixRotationX(&matView, 0.5f * D3DX_PI);
                matView._43 = -50.0f;

                m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
                m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

                m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);

                m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
                m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
                m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

                m_Water.DrawCaustics();

                m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
                m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
                m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

                m_pRenderToSurface->EndScene();
            }
            else
            {
                m_bDrawCaustics = FALSE;
                m_pEffect->SetTexture("tCAU", NULL);

                if(FAILED(hr = GetNextTechnique(0, FALSE)))
                    return hr;
            }
        }
    }

    return S_OK;
}
    i32 CreatePlane(Resources::CMesh* pMesh, const IInputLayout* pIL, const SPlaneOptions& Opts)
    {
        bool bIsNormal = pIL->IsNormal();
        u16 ulVVertCount = (u16)Opts.vecVertexCount.x;
        u16 ulHVertCount = (u16)Opts.vecVertexCount.y;
        ul32 ulVertCount = ulVVertCount * ulHVertCount;
        //ul32 ulIndexCount = 36;
        VertexBufferPtr pVB = pMesh->CreateVertexBuffer();
        pVB->SetInputLayout( pIL );
        
        pVB->SetTopologyType( TopologyTypes::TRIANGLE_STRIP );
        pVB->SetUsage( BufferUsages::DEFAULT );
        pVB->SetVertexCount( ulVertCount );
        pVB->SetInputLayout( pIL );

        pVB->Lock();

        CVertexData& Data = pVB->GetVertexData();

        cf32 fUnit = 1.0f;
        ul32 vs = pIL->GetVertexSize();
        Vec2 vecTC( Vec2::ZERO );
        Vec3 vecTmpPos;

        if( pIL->IsPosition() )
        {
            ul32 ulVertId = 0;
            Vec2 vecVertDist( Opts.vecSize.x / ( Opts.vecVertexCount.x - 1 ), Opts.vecSize.y / ( Opts.vecVertexCount.y - 1 ) );
            Vec2 vecPos( Vec2::ZERO );

            for(ul32 y = 0; y < ulVVertCount; ++y, vecPos.y += vecVertDist.y)
            {
                for(ul32 x = 0; x < ulHVertCount; ++x, vecPos.x += vecVertDist.x)
                {
                    vecTmpPos = Vec3( vecPos.x, 0, vecPos.y );
                    Data.SetPosition( ulVertId, vecTmpPos );
                    if( pIL->IsTexCoord0() )
                    {
                        vecTC.x = vecTmpPos.x / Opts.vecSize.x;
                        vecTC.y = vecTmpPos.z / Opts.vecSize.y;
                        Data.SetTexCoord0( ulVertId, vecTC );
                    }

                    ++ulVertId;
                }

                vecPos.x = 0.0f;
            }
        }

        if( pIL->IsColor() )
        {
            f32 fc = 0.05f;
            for(ul32 i = 0; i < ulVertCount; ++i)
            {
                Data.SetColor( i, XST::CColor::Random().ToVector4() + Vec4( 0.2f, 0.2f, 0.2f, 0.0f ) ); 
            }
        }

        if( bIsNormal )
        {
            for(u32 i = 0; i < ulVertCount; ++i)
            {
                Data.SetNormal( i, Opts.vecNormal );
            }
        }

        pVB->Unlock();
        pVB->Create();


        IndexBufferPtr pIB = pMesh->CreateIndexBuffer();
        pIB->SetUsage( BufferUsages::DEFAULT );
        u16 ulIndexCount = ( ulHVertCount * 2 ) * ( ulVVertCount - 1 ) + ( ulVVertCount - 2 );
        pIB->SetIndexCount( ulIndexCount );
        pIB->Lock();

        CIndexData& IndexData = pIB->GetIndexData();

        ul32 ulIndex = 0;
        for(u16 z = 0; z < ulVVertCount - 1; ++z)
        {
            if( z % 2 == 0 )
            {
                i16 x;
                for(x = 0; x < ulHVertCount; ++x )
                {
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) );
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) + ulHVertCount );
                }

                if( z != ulVVertCount - 2 )
                {
                    IndexData.SetIndex( ulIndex++, --x + ( z * ulHVertCount ) );
                }
            }
            else
            {
                i16 x;
                for(x = ulHVertCount - 1; x >= 0; --x )
                {
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) );
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) + ulHVertCount );
                }

                if( z != ulVVertCount - 2 )
                {
                    IndexData.SetIndex( ulIndex++, ++x + ( z * ulHVertCount ) );
                }
            }
        }

        pIB->Unlock();
        pIB->Create();

        return XST_OK;
    }
Esempio n. 8
0
bool cNoradBase::FinalPosition(double incl, double  omega, 
                               double    e, double      a,
                               double   xl, double  xnode, 
                               double   xn, double tsince, 
                               cEci &eci)
{
   if ((e * e) > 1.0)
   {
      // error in satellite data
      return false;  
   }

   double beta = sqrt(1.0 - e * e);

   // Long period periodics 
   double axn  = e * cos(omega);
   double temp = 1.0 / (a * beta * beta);
   double xll  = temp * m_xlcof * axn;
   double aynl = temp * m_aycof;
   double xlt  = xl + xll;
   double ayn  = e * sin(omega) + aynl;

   // Solve Kepler's Equation 

   double capu   = Fmod2p(xlt - xnode);
   double temp2  = capu;
   double temp3  = 0.0;
   double temp4  = 0.0;
   double temp5  = 0.0;
   double temp6  = 0.0;
   double sinepw = 0.0;
   double cosepw = 0.0;
   bool   fDone  = false;

   for (int i = 1; (i <= 10) && !fDone; i++)
   {
      sinepw = sin(temp2);
      cosepw = cos(temp2);
      temp3 = axn * sinepw;
      temp4 = ayn * cosepw;
      temp5 = axn * cosepw;
      temp6 = ayn * sinepw;

      double epw = (capu - temp4 + temp3 - temp2) / 
                   (1.0 - temp5 - temp6) + temp2;

      if (fabs(epw - temp2) <= E6A)
         fDone = true;
      else
         temp2 = epw;
   }

   // Short period preliminary quantities 
   double ecose = temp5 + temp6;
   double esine = temp3 - temp4;
   double elsq  = axn * axn + ayn * ayn;
   temp  = 1.0 - elsq;
   double pl = a * temp;
   double r  = a * (1.0 - ecose);
   double temp1 = 1.0 / r;
   double rdot  = XKE * sqrt(a) * esine * temp1;
   double rfdot = XKE * sqrt(pl) * temp1;
   temp2 = a * temp1;
   double betal = sqrt(temp);
   temp3 = 1.0 / (1.0 + betal);
   double cosu  = temp2 * (cosepw - axn + ayn * esine * temp3);
   double sinu  = temp2 * (sinepw - ayn - axn * esine * temp3);
   double u     = AcTan(sinu, cosu);
   double sin2u = 2.0 * sinu * cosu;
   double cos2u = 2.0 * cosu * cosu - 1.0;

   temp  = 1.0 / pl;
   temp1 = CK2 * temp;
   temp2 = temp1 * temp;

   // Update for short periodics 
   double rk = r * (1.0 - 1.5 * temp2 * betal * m_x3thm1) + 
               0.5 * temp1 * m_x1mth2 * cos2u;
   double uk = u - 0.25 * temp2 * m_x7thm1 * sin2u;
   double xnodek = xnode + 1.5 * temp2 * m_cosio * sin2u;
   double xinck  = incl + 1.5 * temp2 * m_cosio * m_sinio * cos2u;
   double rdotk  = rdot - xn * temp1 * m_x1mth2 * sin2u;
   double rfdotk = rfdot + xn * temp1 * (m_x1mth2 * cos2u + 1.5 * m_x3thm1);

   // Orientation vectors 
   double sinuk  = sin(uk);
   double cosuk  = cos(uk);
   double sinik  = sin(xinck);
   double cosik  = cos(xinck);
   double sinnok = sin(xnodek);
   double cosnok = cos(xnodek);
   double xmx = -sinnok * cosik;
   double xmy = cosnok * cosik;
   double ux  = xmx * sinuk + cosnok * cosuk;
   double uy  = xmy * sinuk + sinnok * cosuk;
   double uz  = sinik * sinuk;
   double vx  = xmx * cosuk - cosnok * sinuk;
   double vy  = xmy * cosuk - sinnok * sinuk;
   double vz  = sinik * cosuk;

   // Position
   double x = rk * ux;
   double y = rk * uy;
   double z = rk * uz;

   cVector vecPos(x, y, z);

   // Validate on altitude
   double altKm = (vecPos.Magnitude() * (XKMPER_WGS72 / AE));

   if ((altKm < XKMPER_WGS72) || (altKm > (2 * GEOSYNC_ALT)))
      return false;
   
   // Velocity
   double xdot = rdotk * ux + rfdotk * vx;
   double ydot = rdotk * uy + rfdotk * vy;
   double zdot = rdotk * uz + rfdotk * vz;

   cVector vecVel(xdot, ydot, zdot);

   cJulian gmt = m_Orbit.Epoch();
   gmt.addMin(tsince);

   eci = cEci(vecPos, vecVel, gmt);

   return true;
}