void ConstraintVisualizer::RenderSpring (IVRenderInterface* pRenderer, const hkvVec3& startPos, const hkvVec3& endPos) { // Calculate the look at matrix hkvVec3 vSource(startPos.x, startPos.y, startPos.z); hkvVec3 vTarget(endPos.x, endPos.y, endPos.z); hkvMat3 lookAtMat; lookAtMat.setLookInDirectionMatrix (vTarget - vSource); // Calculate the length and thickness of the spring float fVecLen = (vTarget - vSource).getLength(); float fSpringThickness = fVecLen / 40.0f; // Render the spring hkvVec3 vOldPos; for (int i = -5; i < 105; i++) { // Calculate the position on the spring line float fPosOnLine = fVecLen * ((float) i / 100.0f); fPosOnLine = hkvMath::clamp (fPosOnLine, 0.0f, fVecLen); hkvVec3 vCurrentPos = vSource + lookAtMat.getAxis(0) * fPosOnLine; // Calculate the local offset (to visualize circles) float fAngle = ((float)(i % 10)) * 2 * hkvMath::pi () / 10.0f; float diffX = sin(fAngle); float diffY = cos(fAngle); vCurrentPos += lookAtMat.getAxis(1) * fSpringThickness * diffX; vCurrentPos += lookAtMat.getAxis(2) * fSpringThickness * diffY; // Render the next line fragment if (!vOldPos.isZero (0.0f)) { VColorRef color(255, 255, 0); pRenderer->DrawLine(vOldPos, hkvVec3(vCurrentPos.x, vCurrentPos.y, vCurrentPos.z), color, 2); } vOldPos = hkvVec3(vCurrentPos.x, vCurrentPos.y, vCurrentPos.z); } }
void CHUD::UpdateMissionObjectiveIcon(EntityId objective, int friendly, FlashOnScreenIcon iconType, bool forceNoOffset, Vec3 rotationTarget) { IEntity *pObjectiveEntity = GetISystem()->GetIEntitySystem()->GetEntity(objective); if(!pObjectiveEntity) return; AABB box; pObjectiveEntity->GetWorldBounds(box); Vec3 vWorldPos = Vec3(0,0,0); SEntitySlotInfo info; int slotCount = pObjectiveEntity->GetSlotCount(); for(int i=0; i<slotCount; ++i) { if (pObjectiveEntity->GetSlotInfo(i, info)) { if (info.pCharacter) { int16 id = info.pCharacter->GetISkeletonPose()->GetJointIDByName("objectiveicon"); if (id >= 0) { //vPos = pCharacter->GetISkeleton()->GetHelperPos(helper); vWorldPos = info.pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t; if (!vWorldPos.IsZero()) { vWorldPos = pObjectiveEntity->GetSlotWorldTM(i).TransformPoint(vWorldPos); break; } } } } } if(vWorldPos == Vec3(0,0,0)) vWorldPos = pObjectiveEntity->GetWorldPos(); if(!forceNoOffset) vWorldPos.z += 2.0f; Vec3 vEntityScreenSpace; m_pRenderer->ProjectToScreen( vWorldPos.x, vWorldPos.y, vWorldPos.z, &vEntityScreenSpace.x, &vEntityScreenSpace.y, &vEntityScreenSpace.z); Vec3 vEntityTargetSpace; bool useTarget = false; if(!rotationTarget.IsZero()) { m_pRenderer->ProjectToScreen( rotationTarget.x, rotationTarget.y, rotationTarget.z, &vEntityTargetSpace.x, &vEntityTargetSpace.y, &vEntityTargetSpace.z); useTarget = true; } CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetClientActor()); bool bBack = false; if (IMovementController *pMV = pActor->GetMovementController()) { SMovementState state; pMV->GetMovementState(state); Vec3 vLook = state.eyeDirection; Vec3 vDir = vWorldPos - pActor->GetEntity()->GetWorldPos(); float fDot = vLook.Dot(vDir); if(fDot<0.0f) bBack = true; } bool bLeft(false), bRight(false), bTop(false), bBottom(false); if(vEntityScreenSpace.z > 1.0f && bBack) { Vec2 vCenter(50.0f, 50.0f); Vec2 vTarget(-vEntityScreenSpace.x, -vEntityScreenSpace.y); Vec2 vScreenDir = vTarget - vCenter; vScreenDir = vCenter + (100.0f * vScreenDir.NormalizeSafe()); vEntityScreenSpace.y = vScreenDir.y; vEntityScreenSpace.x = vScreenDir.x; useTarget = false; } if(vEntityScreenSpace.x < 2.0f) { bLeft = true; vEntityScreenSpace.x = 2.0f; useTarget = false; } if(vEntityScreenSpace.x > 98.0f) { bRight = true; vEntityScreenSpace.x = 98.0f; useTarget = false; } if(vEntityScreenSpace.y < 2.01f) { bTop = true; vEntityScreenSpace.y = 2.0f; useTarget = false; } if(vEntityScreenSpace.y > 97.99f) { bBottom = true; vEntityScreenSpace.y = 98.0f; useTarget = false; } float fScaleX = 0.0f; float fScaleY = 0.0f; float fHalfUselessSize = 0.0f; GetProjectionScale(&m_animMissionObjective,&fScaleX,&fScaleY,&fHalfUselessSize); if(bLeft && bTop) { iconType = eOS_TopLeft; } else if(bLeft && bBottom) { iconType = eOS_BottomLeft; } else if(bRight && bTop) { iconType = eOS_TopRight; } else if(bRight && bBottom) { iconType = eOS_BottomRight; } else if(bLeft) { iconType = eOS_Left; } else if(bRight) { iconType = eOS_Right; } else if(bTop) { iconType = eOS_Top; } else if(bBottom) { iconType = eOS_Bottom; } float rotation = 0.0f; if(useTarget) { float diffX = (vEntityScreenSpace.x*fScaleX+fHalfUselessSize+16.0f) - (vEntityTargetSpace.x*fScaleX+fHalfUselessSize+16.0f); float diffY = (vEntityScreenSpace.y*fScaleY) - (vEntityTargetSpace.y*fScaleY); Vec2 dir(diffX, diffY); dir.NormalizeSafe(); float fAngle; if(dir.y < 0) { fAngle = RAD2DEG(acos_tpl(dir.x)); } else { fAngle = RAD2DEG(gf_PI2-acos_tpl(dir.x)); } rotation = fAngle - 90.0f; } int iMinDist = g_pGameCVars->hud_onScreenNearDistance; int iMaxDist = g_pGameCVars->hud_onScreenFarDistance; float fMinSize = g_pGameCVars->hud_onScreenNearSize; float fMaxSize = g_pGameCVars->hud_onScreenFarSize; CActor *pPlayerActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor()); float fDist = (vWorldPos-pPlayerActor->GetEntity()->GetWorldPos()).len(); float fSize = 1.0; if(fDist<=iMinDist) { fSize = fMinSize; } else if(fDist>=iMaxDist) { fSize = fMaxSize; } else if(iMaxDist>iMinDist) { float fA = ((float)iMaxDist - fDist); float fB = (float)(iMaxDist - iMinDist); float fC = (fMinSize - fMaxSize); fSize = ((fA / fB) * fC) + fMaxSize; } float centerX = 50.0; float centerY = 50.0; m_missionObjectiveNumEntries += FillUpMOArray(&m_missionObjectiveValues, objective, vEntityScreenSpace.x*fScaleX+fHalfUselessSize+16.0f, vEntityScreenSpace.y*fScaleY, iconType, friendly, (int)fDist, fSize*fSize, -rotation); bool nearCenter = (pow(centerX-vEntityScreenSpace.x+1.5f,2.0f)+pow(centerY-vEntityScreenSpace.y+2.5f,2.0f))<16.0f; if(nearCenter && (gEnv->bMultiplayer || m_pHUDScopes->IsBinocularsShown())) { m_objectiveNearCenter = objective; } }
static NPError _OpenURL(NPP npp, const char *szURL, const char *szTarget, void *pNotifyData, const char *pData, uint32 len, NPBool isFile) { if (!npp) { return NPERR_INVALID_INSTANCE_ERROR; } void *postData = NULL; uint32 postDataLen = 0; if (pData) { if (!isFile) { postData = (void *) pData; postDataLen = len; } else { // TODO read the file specified in the postdata param into memory } } nsPluginHostWnd *pWnd = (nsPluginHostWnd *) npp->ndata; ATLASSERT(pWnd); // Other window targets if (szTarget) { CComPtr<IWebBrowserApp> cpBrowser; pWnd->GetWebBrowserApp(&cpBrowser); if (!cpBrowser) { return NPERR_GENERIC_ERROR; } CComBSTR url(szURL); HRESULT hr; // Test if the input URL has a schema which means it's relative, // otherwise consider it to be relative to the current URL WCHAR szSchema[10]; const DWORD cbSchema = sizeof(szSchema) / sizeof(szSchema[0]); DWORD cbSchemaUsed = 0; memset(szSchema, 0, cbSchema); hr = CoInternetParseUrl(url.m_str, PARSE_SCHEMA, 0, szSchema, cbSchema, &cbSchemaUsed, 0); if (hr != S_OK || cbSchemaUsed == 0) { // Convert relative URLs to absolute, so that they can be loaded // by the Browser CComBSTR bstrCurrentURL; cpBrowser->get_LocationURL(&bstrCurrentURL); if (bstrCurrentURL.Length()) { USES_CONVERSION; DWORD cbNewURL = (url.Length() + bstrCurrentURL.Length() + 1) * sizeof(WCHAR); DWORD cbNewURLUsed = 0; WCHAR *pszNewURL = (WCHAR *) calloc(cbNewURL, 1); ATLASSERT(pszNewURL); CoInternetCombineUrl( bstrCurrentURL.m_str, url.m_str, 0, pszNewURL, cbNewURL, &cbNewURLUsed, 0); ATLASSERT(cbNewURLUsed < cbNewURL); url = pszNewURL; free(pszNewURL); } } CComVariant vFlags; CComVariant vTarget(szTarget); CComVariant vPostData; CComVariant vHeaders; // Initialise postdata if (postData) { // According to the documentation. // The post data specified by PostData is passed as a SAFEARRAY // structure. The variant should be of type VT_ARRAY and point to // a SAFEARRAY. The SAFEARRAY should be of element type VT_UI1, // dimension one, and have an element count equal to the number of // bytes of post data. SAFEARRAYBOUND saBound[1]; saBound[0].lLbound = 0; saBound[0].cElements = len; vPostData.vt = VT_ARRAY | VT_UI1; vPostData.parray = SafeArrayCreate(VT_UI1, 1, saBound); SafeArrayLock(vPostData.parray); memcpy(vPostData.parray->pvData, postData, postDataLen); SafeArrayUnlock(vPostData.parray); } cpBrowser->Navigate(url, &vFlags, &vTarget, &vPostData, &vHeaders); // TODO listen to navigation & send a URL notify to plugin when completed return NPERR_NO_ERROR; } USES_CONVERSION; HRESULT hr = pWnd->OpenURLStream(A2CT(szURL), pNotifyData, postData, postDataLen); return SUCCEEDED(hr) ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR; }