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); }
hkvVec4 BitmapInfo_t::GetColorAt(int iX, int iY) const { VASSERT(iX>=0 && iX<m_iSize[0]); VASSERT(iY>=0 && iY<m_iSize[1]); float *pAsFloats; UBYTE *pAsBytes; VColorRef *pAsCRef; hkvVec4* pAsVector; switch (m_eComponentType) { case ByteLuminance: pAsBytes = (UBYTE *)m_pData; pAsBytes += m_iStride*iY + iX; return hkvVec4 (pAsBytes[0]*(1.f/255.f),pAsBytes[0]*(1.f/255.f),pAsBytes[0]*(1.f/255.f),1.f); case FloatLuminance: pAsFloats = (float *)m_pData; pAsFloats += m_iStride*iY + iX; return hkvVec4 (pAsFloats[0],pAsFloats[1],pAsFloats[2],1.f); case ByteRGBA: pAsCRef = (VColorRef *)m_pData; pAsCRef += m_iStride*iY + iX; return hkvVec4 (pAsCRef->r*(1.f/255.f),pAsCRef->g*(1.f/255.f),pAsCRef->b*(1.f/255.f),pAsCRef->a*(1.f/255.f)); case FloatRGBA: pAsVector = (hkvVec4*) m_pData; return pAsVector[m_iStride*iY + iX]; default: VASSERT(!"Unsupported component type"); } return hkvVec4(); }
void RPG_GuiManager_VisionGUI::AddMinimapToParentDialog() { InitializeMinimapDefinitions(); const RPG_LevelInfo* levelInfo = RPG_GameManager::s_instance.GetLevelInfo(); if (levelInfo) { // add minimap VASSERT(m_minimapTexture && m_minimapFrameTexture && m_minimapMaskTexture); { // Add minimap VASSERT(!m_minimap); m_minimap = new RPG_GuiMinimap_VisionGUI(); VASSERT(m_minimap); m_minimap->SetMaskTexture(m_minimapMaskTexture); m_minimap->SetFadeColor(hkvVec4(1.f, 1.f, 1.f, 1.f)); m_minimap->SetTransform(hkvVec4(m_minimapZoomFactor, m_minimapZoomFactor, 0.f, 0.f)); m_minimap->Image().SetTexture(m_minimapTexture); m_minimap->Image().SetTransparency(VIS_TRANSP_ALPHA); m_minimap->SetPosition(m_minimapPosition.x, m_minimapPosition.y); m_minimap->SetSize(m_minimapSize.x, m_minimapSize.y); m_minimap->SetVisible(true); m_parentDialog->AddControl(m_minimap); m_minimap->OnActivate(); // Add minimap frame VASSERT(!m_minimapFrame); m_minimapFrame = new VImageControl(); VASSERT(m_minimapFrame); m_minimapFrame->Image().SetTexture(m_minimapFrameTexture); m_minimapFrame->Image().SetTransparency(VIS_TRANSP_ALPHA); m_minimapFrame->SetPosition(m_minimapPosition.x, m_minimapPosition.y); m_minimapFrame->SetSize(m_minimapSize.x, m_minimapSize.y); m_minimapFrame->SetVisible(true); m_parentDialog->AddControl(m_minimapFrame); // Add minimap player icon VASSERT(!m_minimapPlayer); m_minimapPlayer = new VImageControl(); VASSERT(m_minimapPlayer); m_minimapPlayer->Image().SetTexture(m_minimapPlayerTexture); m_minimapPlayer->Image().SetTransparency(VIS_TRANSP_ALPHA); m_minimapPlayer->Image().SetTextureRange(VRectanglef(-0.5f,-0.5f, 0.5f, 0.5f)); m_minimapPlayer->SetPosition(m_minimapPosition.x + m_minimapSize.x / 2.f - 16.f, m_minimapPosition.y + m_minimapSize.y / 2.f - 16.f); m_minimapPlayer->SetSize(32.f, 32.f); m_minimapPlayer->SetVisible(true); m_parentDialog->AddControl(m_minimapPlayer); } } }
// multiplicative blending hkvVec4 VISION_FASTCALL BlittingHelpers::CombineModulate(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { return hkvVec4( dstColor.x*srcColor.x*auxColor.x, dstColor.y*srcColor.y*auxColor.y, dstColor.z*srcColor.z*auxColor.z, dstColor.w*srcColor.w*auxColor.w); }
// additive blending hkvVec4 VISION_FASTCALL BlittingHelpers::CombineAdditive(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { return hkvVec4( dstColor.x+srcColor.x*auxColor.x, dstColor.y+srcColor.y*auxColor.y, dstColor.z+srcColor.z*auxColor.z, dstColor.w+srcColor.w*auxColor.w); }
// boolean mask hkvVec4 VISION_FASTCALL BlittingHelpers::BooleanMask(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { return hkvVec4( srcColor.x>0.5f ? auxColor.x : dstColor.x, srcColor.y>0.5f ? auxColor.y : dstColor.y, srcColor.z>0.5f ? auxColor.z : dstColor.z, srcColor.w>0.5f ? auxColor.w : dstColor.w); }
// replace (no blending) hkvVec4 VISION_FASTCALL BlittingHelpers::CombineReplace(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { return hkvVec4( srcColor.x*auxColor.x, srcColor.y*auxColor.y, srcColor.z*auxColor.z, srcColor.w*auxColor.w); }
// add source luminance hkvVec4 VISION_FASTCALL BlittingHelpers::CombineAddSrcLuminance(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { float lum = (srcColor.r+srcColor.g+srcColor.b) * (1.f/3.f); return hkvVec4( dstColor.x+lum*auxColor.x, dstColor.y+lum*auxColor.y, dstColor.z+lum*auxColor.z, dstColor.w+lum*auxColor.w); }
// blending using source luminance hkvVec4 VISION_FASTCALL BlittingHelpers::CombineSrcLuminance(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { float a0 = ClampFloat((srcColor.r+srcColor.g+srcColor.b) * (1.f/3.f) * auxColor.a,0,1); float a1 = 1.f-a0; return hkvVec4( dstColor.x*a1+srcColor.x*auxColor.x*a0, dstColor.y*a1+srcColor.y*auxColor.y*a0, dstColor.z*a1+srcColor.z*auxColor.z*a0, dstColor.w*a1+srcColor.w*auxColor.w*a0); }
// alpha blending hkvVec4 VISION_FASTCALL BlittingHelpers::CombineSrcAlpha(const hkvVec4& srcColor, const hkvVec4& dstColor, const hkvVec4& auxColor) { float a0 = ClampFloat(srcColor.a * auxColor.a,0,1); float a1 = 1.f-a0; return hkvVec4( dstColor.x*a1+srcColor.x*auxColor.x*a0, dstColor.y*a1+srcColor.y*auxColor.y*a0, dstColor.z*a1+srcColor.z*auxColor.z*a0, dstColor.w*a1+srcColor.w*auxColor.w*a0); }
void RPG_GuiManager_VisionGUI::UpdateMinimap(const RPG_Character* characterEntity, const float deltaTime) { if (m_minimap) { hkvVec2 pos = hkvVec2(characterEntity->GetPosition().x, characterEntity->GetPosition().y); float relX = m_minimapRelativeOrigin.x + (pos.x * m_minimapScaleFactor); float relY = m_minimapRelativeOrigin.y - (pos.y * m_minimapScaleFactor); m_minimap->SetTransform(hkvVec4(m_minimapZoomFactor, m_minimapZoomFactor, relX, relY)); m_minimapPlayer->Image().m_States->CreateTransformation(m_minimapPlayerRotation, hkvVec2(0.5f, 0.5f), characterEntity->GetOrientation().x - 90.f); m_minimapPlayer->Image().SetTransformation(m_minimapPlayerRotation.getPointer(), NULL); } }
/// \brief /// Sets the shadow color. The default color is gray inline void SetColor(VColorRef iColor) {ShadowColor=iColor;m_vBlendColor = hkvVec4(1.f-(float)iColor.r/255.f,1.f-(float)iColor.g/255.f,1.f-(float)iColor.b/255.f, 1.f);}
hkRefNew<hkpShape> vHavokShapeFactory::CreateShapeFromStaticMeshInstances(const VisStaticMeshInstCollection &meshInstances, int iCreationFlags, const char **szShapeCacheId) { int iCount = meshInstances.GetLength(); VVERIFY_OR_RET_VAL(iCount>0 && szShapeCacheId!=NULL, NULL); // Actual mesh scale, which is only used for caching. hkvVec3 vScale(hkvNoInitialization); ExtractScaling(meshInstances[0]->GetTransform(), vScale); char szShapeId[512]; const bool bAllowStaticMeshCaching = vHavokPhysicsModule_GetDefaultWorldRuntimeSettings().m_bEnableShapeCaching==TRUE; const vHavokPhysicsModule *pModule = vHavokPhysicsModule::GetInstance(); VASSERT(pModule != NULL); const bool bForceHktShapeCaching = pModule->IsHktShapeCachingEnforced(); // For single mesh instances the per instance welding type is used. For merged mesh instances the global merged welding type is used. VisWeldingType_e eWeldingType = (iCount==1) ? meshInstances[0]->GetWeldingType() : (VisWeldingType_e)vHavokPhysicsModule_GetWorldSetupSettings().m_iMergedStaticWeldingType; const bool bAllowPerTriCollisionInfo = iCreationFlags & VShapeCreationFlags_ALLOW_PERTRICOLINFO; const bool bShrinkByCvxRadius = iCreationFlags & VShapeCreationFlags_SHRINK; // Check whether shape has been already cached for this mesh with the respective scaling. // We are just caching single static mesh instances and no static mesh collections. hkpShape *pCachedShape = HK_NULL; if (iCount == 1) { // first, find the convex version GetIDStringForConvexShape(szShapeId, meshInstances[0]->GetMesh()->GetFilename(), vScale, bShrinkByCvxRadius); pCachedShape = FindShape(szShapeId, szShapeCacheId); if (!pCachedShape) { // then find the mesh version GetIDStringForMeshShape(szShapeId, meshInstances[0]->GetMesh()->GetFilename(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType); pCachedShape = FindShape(szShapeId, szShapeCacheId); } if (pCachedShape) { pCachedShape->addReference(); return pCachedShape; } if (bAllowStaticMeshCaching) { // first, find the convex version pCachedShape = vHavokCachedShape::LoadConvexShape(meshInstances[0]->GetMesh(), vScale, bShrinkByCvxRadius); if (pCachedShape) { *szShapeCacheId = AddShape(szShapeId, pCachedShape); #ifdef HK_DEBUG_SLOW const hkClass* loadedClassType = hkVtableClassRegistry::getInstance().getClassFromVirtualInstance(pCachedShape); HK_ASSERT2(0x5432c902, loadedClassType && (hkString::strCmp( loadedClassType->getName(), "hkvConvexVerticesShape" ) == 0), "Serialized in a unexpected cached Havok shape type!"); #endif return pCachedShape; } else { // then find the mesh version pCachedShape = vHavokCachedShape::LoadMeshShape(meshInstances[0]->GetMesh(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType); } if (pCachedShape ) { *szShapeCacheId = AddShape(szShapeId, pCachedShape); #ifdef HK_DEBUG_SLOW const hkClass* loadedClassType = hkVtableClassRegistry::getInstance().getClassFromVirtualInstance(pCachedShape); HK_ASSERT2(0x5432c902, loadedClassType && (hkString::strCmp( loadedClassType->getName(), "hkvBvCompressedMeshShape" ) == 0), "Serialized in a unexpected cached Havok shape type!"); #endif hkvBvCompressedMeshShape *pCompressedMeshShape = reinterpret_cast<hkvBvCompressedMeshShape*>(pCachedShape); pCompressedMeshShape->SetupMaterials(); return pCachedShape; } else if(!Vision::Editor.IsInEditor() && !bForceHktShapeCaching) { Vision::Error.Warning("Cached HKT file for %s is missing. Please generate HKT file (see documentation for details).", meshInstances[0]->GetMesh()->GetFilename()); } } } // Get the reference transformation. We use the first static mesh as reference // transformation, and thus as the position of the corresponding rigid body. hkvMat4 referenceTransform = meshInstances[0]->GetTransform(); // Remove any scaling from the reference matrix. This one has to be applied to // the Havok shapes, and thus needs to be part of the mesh transforms. referenceTransform.setScalingFactors(hkvVec3 (1)); // We need the inverse referenceTransform to transform each instance into reference space referenceTransform.invert(); referenceTransform.setRow (3, hkvVec4 (0, 0, 0, 1)); // Determine collision type from first static mesh instance. const VisStaticMeshInstance_cl *pMeshInstance = meshInstances[0]; VisStaticMesh_cl *pMesh = pMeshInstance->GetMesh(); IVCollisionMesh *pColMesh = pMesh->GetCollisionMesh(true, true); const bool bIsConvex = pColMesh->GetType()==VIS_COLMESH_GEOTYPE_CONVEXHULL; // Only create a convex shape if a single mesh instance is used, since otherwise merging multiple mesh instances in one single convex hull // will provide in most cases not the desired behavior. Moreover we can only create either a convex hull or a concave mesh shape, therefore // mesh instances with different collision type can't be merged into one shape. hkpShape *pShape = (bIsConvex && iCount==1) ? CreateConvexShapeFromStaticMeshInstances(meshInstances, referenceTransform, bShrinkByCvxRadius) : CreateMeshShapeFromStaticMeshInstances(meshInstances, referenceTransform, bAllowPerTriCollisionInfo, eWeldingType); // We are just caching single static mesh instances and no static mesh collections. if (iCount == 1) { *szShapeCacheId = AddShape(szShapeId, pShape); // Only cache shape to HKT file when inside vForge or when enforced. if ((Vision::Editor.IsInEditor() && bAllowStaticMeshCaching) || bForceHktShapeCaching) { if (bIsConvex) vHavokCachedShape::SaveConvexShape(meshInstances[0]->GetMesh(), vScale, bShrinkByCvxRadius, (hkvConvexVerticesShape*)pShape); else vHavokCachedShape::SaveMeshShape(meshInstances[0]->GetMesh(), vScale, meshInstances[0]->GetCollisionBehavior(), eWeldingType, (hkvBvCompressedMeshShape*)pShape); } } return pShape; }