bool CObjectViewer::loadMesh(const std::string &meshFileName, const std::string &skelFileName) { CPath::addSearchPath(CFile::getPath(meshFileName), false, false); // create instance of the mesh character UInstance Entity = _Scene->createInstance(meshFileName); USkeleton Skeleton = _Scene->createSkeleton(skelFileName); // if we can't create entity, skip it if (Entity.empty()) return false; // create a new entity EIT eit = (_Entities.insert (make_pair (CFile::getFilenameWithoutExtension(meshFileName), CEntity()))).first; CEntity &entity = (*eit).second; // set the entity up entity._Name = CFile::getFilenameWithoutExtension(meshFileName); entity._Instance = Entity; if (!Skeleton.empty()) { entity._Skeleton = Skeleton; entity._Skeleton.bindSkin (entity._Instance); } entity._AnimationSet = _Driver->createAnimationSet(false); entity._PlayList = _PlayListManager->createPlayList(entity._AnimationSet); return true; }
bool USkeleton::bindSkin(UInstance mi) { NL3D_HAUTO_UI_SKELETON; if(mi.empty()) { nlerror("USkeleton::bindSkin(): mi is NULL"); return false; } CTransform *trans= dynamic_cast<CTransform*>(mi.getObjectPtr()); CMeshBaseInstance *meshi= dynamic_cast<CMeshBaseInstance*>(trans); if(meshi==NULL) { nlerror("USkeleton::bindSkin(): mi is not a MeshInstance or MeshMRMInstance"); return false; } CSkeletonModel *object = getObjectPtr(); return object->bindSkin(meshi); }
//----------------------------------------------- // updateParticlesNoActor : // //----------------------------------------------- void CSceneParser::updateParticlesNoActor(float difTime, CParticle &particle, UAnimation &animation) { // Animate all instances. for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i ) { std::string iName = particle.IGPtr->getInstanceName(i); UInstance instance = particle.IGPtr->getByName(iName); if(!instance) continue; instance->setTransformMode(UTransformable::RotQuat); // If the animation has no track of position. UTrack* trackPos = animation.getTrackByName("PathPos"); if(!trackPos) trackPos = animation.getTrackByName(string(iName + "." + "PathPos").c_str()); if(trackPos) { CVector pos; trackPos->interpolate(difTime, pos); instance->setPos(pos); } // If the animation has no track of rotation. UTrack* trackRot = animation.getTrackByName("PathRotQuat"); if(!trackRot) trackRot = animation.getTrackByName(string(iName + "." + "PathRotQuat").c_str()); if(trackRot) { CQuat rot; if(trackRot->interpolate(difTime, rot)) instance->setRotQuat(rot); else nlwarning("CSceneParser::updateParticles : Not a Quat!"); } } }// updateParticlesNoActor //
void updateCamera() { if (StereoHMD) { NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); NLMISC::CMatrix camMatrix = Camera.getMatrix(); NLMISC::CMatrix hmdMatrix; hmdMatrix.setRot(hmdOrient); NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future posMatrix.translate(StereoHMD->getEyePosition()); Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix); } // Set the new position of the snow emitter CMatrix mat = CMatrix::Identity; mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/); Snow.setMatrix(mat); }
void initCamera() { if (ConfigFile->getVar("HMDEnable").asBool()) { std::vector<NL3D::CStereoDeviceInfo> devices; IStereoDisplay::listDevices(devices); for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; nlinfo("Stereo Display: %s", name.str().c_str()); } CStereoDeviceInfo *deviceInfo = NULL; std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString(); if (hmdDeviceCfg == std::string("Auto") && devices.begin() != devices.end()) { for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { if (it->AllowAuto) { deviceInfo = &devices[0]; } } } else { std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString(); for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; if (name.str() == hmdDeviceCfg) deviceInfo = &(*it); if (hmdDeviceId == it->Serial) break; } } if (deviceInfo) { nlinfo("Create VR stereo display device"); StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); if (StereoDisplay) { if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) { nlinfo("Stereo display device is a HMD"); StereoHMD = static_cast<IStereoHMD *>(StereoDisplay); StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter } StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation StereoDisplay->attachToDisplay(); } } } IStereoDisplay::releaseUnusedLibraries(); // Set up directly the camera Camera = Scene->getCam(); Camera.setTransformMode (UTransformable::DirectMatrix); Camera.setPerspective((float)Pi/2.f, ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(), 0.1f, 1000.f); Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0), ConfigFile->getVar("StartPoint").asFloat(1), ConfigFile->getVar("StartPoint").asFloat(2)), CVectorD (0,0,0)); CamCollisionEntity = VisualCollisionManager->createEntity(); CamCollisionEntity->setCeilMode(true); // Create the snowing particle system Snow = Scene->createInstance("snow.ps"); // And setup it Snow.setTransformMode (UTransformable::DirectMatrix); // // Setup the sky scene // // -- -- not sure what the sky has to do with the camera SkyScene = Driver->createScene(false); SkyCamera = SkyScene->getCam (); SkyCamera.setTransformMode (UTransformable::DirectMatrix); // Set the very same frustum as the main camera SkyCamera.setFrustum (Camera.getFrustum ()); Sky = SkyScene->createInstance("sky.shape"); Sky.setTransformMode (UTransformable::DirectMatrix); Sky.setMatrix(CMatrix::Identity); }
namespace SBCLIENT { // // Variables // // The camera for the whole scene UCamera Camera = NULL; // The collision entity use to snap the camera on the ground UVisualCollisionEntity *CamCollisionEntity = NULL; // The particle system for the snowing effect static UInstance Snow = NULL; // The sky 3D objects UScene *SkyScene = NULL; UCamera SkyCamera = NULL; static UInstance Sky = NULL; static UCloudScape *Clouds = NULL; IStereoDisplay *StereoDisplay = NULL; IStereoHMD *StereoHMD = NULL; // // Functions // void initCamera() { if (ConfigFile->getVar("HMDEnable").asBool()) { std::vector<NL3D::CStereoDeviceInfo> devices; IStereoDisplay::listDevices(devices); for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; nlinfo("Stereo Display: %s", name.str().c_str()); } CStereoDeviceInfo *deviceInfo = NULL; std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString(); if (hmdDeviceCfg == std::string("Auto") && devices.begin() != devices.end()) { for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { if (it->AllowAuto) { deviceInfo = &devices[0]; } } } else { std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString(); for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; if (name.str() == hmdDeviceCfg) deviceInfo = &(*it); if (hmdDeviceId == it->Serial) break; } } if (deviceInfo) { nlinfo("Create VR stereo display device"); StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); if (StereoDisplay) { if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) { nlinfo("Stereo display device is a HMD"); StereoHMD = static_cast<IStereoHMD *>(StereoDisplay); StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter } StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation StereoDisplay->attachToDisplay(); } } } IStereoDisplay::releaseUnusedLibraries(); // Set up directly the camera Camera = Scene->getCam(); Camera.setTransformMode (UTransformable::DirectMatrix); Camera.setPerspective((float)Pi/2.f, ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(), 0.1f, 1000.f); Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0), ConfigFile->getVar("StartPoint").asFloat(1), ConfigFile->getVar("StartPoint").asFloat(2)), CVectorD (0,0,0)); CamCollisionEntity = VisualCollisionManager->createEntity(); CamCollisionEntity->setCeilMode(true); // Create the snowing particle system Snow = Scene->createInstance("snow.ps"); // And setup it Snow.setTransformMode (UTransformable::DirectMatrix); // // Setup the sky scene // // -- -- not sure what the sky has to do with the camera SkyScene = Driver->createScene(false); SkyCamera = SkyScene->getCam (); SkyCamera.setTransformMode (UTransformable::DirectMatrix); // Set the very same frustum as the main camera SkyCamera.setFrustum (Camera.getFrustum ()); Sky = SkyScene->createInstance("sky.shape"); Sky.setTransformMode (UTransformable::DirectMatrix); Sky.setMatrix(CMatrix::Identity); } void releaseCamera() { SkyScene->deleteInstance(Sky); Driver->deleteScene(SkyScene); Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); if (StereoHMD) { delete StereoHMD; StereoHMD = NULL; StereoDisplay = NULL; } delete StereoDisplay; StereoDisplay = NULL; IStereoDisplay::releaseAllLibraries(); } void updateCamera() { if (StereoHMD) { NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); NLMISC::CMatrix camMatrix = Camera.getMatrix(); NLMISC::CMatrix hmdMatrix; hmdMatrix.setRot(hmdOrient); NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future posMatrix.translate(StereoHMD->getEyePosition()); Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix); } // Set the new position of the snow emitter CMatrix mat = CMatrix::Identity; mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/); Snow.setMatrix(mat); } void initSky() { // -- -- or what the clouds have to do with the sky SCloudScapeSetup css; Clouds = Scene->createCloudScape (); Clouds->init (&css); Clouds->setQuality (160); Clouds->setNbCloudToUpdateIn80ms (1); } void releaseSky() { Scene->deleteCloudScape(Clouds); } // -- -- random note: update and render makes more sense than animate and update void animateSky(double dt) { if (!StereoHMD) Clouds->anim(dt); SkyScene->animate(AnimationTime); } // this is actually render void updateSky() { CMatrix skyCameraMatrix; skyCameraMatrix.identity(); // skyCameraMatrix= Camera.getMatrix(); skyCameraMatrix.setPos(CVector::Null); SkyCamera.setMatrix(skyCameraMatrix); SkyScene->render(); // Must clear ZBuffer For incoming rendering. Driver->clearZBuffer(); if (!StereoHMD) // Cloudscape not supported (fix Viewport please) Clouds->render(); } } /* namespace SBCLIENT */
// ************************************************************************************************* void CSky::init(UDriver *drv, const CSkySheet &sheet, bool forceFallbackVersion /*= false*/, float numHourInDay /*= 24.f*/, std::vector<std::string> *unsupportedObjects /*= NULL*/) { release(); if(!drv) return; _Driver = drv; // create a new scene for the sky _Scene = _Driver->createScene(true); _Scene->setupTransparencySorting(99, 1); // only sort by priority (99 of them) _AnimLengthInSeconds = sheet.AnimLengthInSeconds; // create animation set if (!sheet.AnimationName.empty()) { _PlayListManager = _Scene->createPlayListManager(); if (_PlayListManager) { _AnimationSet = _Driver->createAnimationSet(); _PlayList = _PlayListManager->createPlayList(_AnimationSet); if (_AnimationSet && _PlayList) { uint animationID = _AnimationSet->addAnimation(sheet.AnimationName.c_str(), sheet.AnimationName.c_str()); if (animationID != UAnimationSet::NotFound) { _AnimationSet->build(); _PlayList->setAnimation(0, animationID); _PlayList->setTimeOrigin(0, 0); _PlayList->setWrapMode(0, UPlayList::Repeat); } else { // no animation loaded _PlayListManager->deletePlayList(_PlayList); _Scene->deletePlayListManager(_PlayListManager); _Driver->deleteAnimationSet(_AnimationSet); _PlayListManager = NULL; _PlayList = NULL; _AnimationSet = NULL; } } } } // load instance group of sky _IG = UInstanceGroup::createInstanceGroup(sheet.InstanceGroupName); if (!_IG) { nlwarning("Couldn't load sky ig : %s", sheet.InstanceGroupName.c_str()); release(); return; } _IG->addToScene(*_Scene, drv); _Objects.reserve(sheet.Objects.size()); // dump name of objects in the scene //nlinfo("Sky scene objects : "); for(uint k = 0; k < _IG->getNumInstance(); ++k) { //nlinfo(_IG->getInstanceName(k).c_str()); UInstance i = _IG->getInstance(k); // hide all instances by default if (!i.empty()) i.hide(); } if (unsupportedObjects) unsupportedObjects->clear(); // map name of a bitmap to the actual bitmap (for reuse of bitmaps) std::map<std::string, CBitmap *> buildShareBitmapByName; // for(uint k = 0; k < sheet.Objects.size(); ++k) { UInstance instance; instance = _IG->getByName(sheet.Objects[k].Std.ShapeName); // should main instance if driver supports its rendering // hide all the instance at start if (!instance.empty() && !instance.supportMaterialRendering(*drv, forceFallbackVersion)) { if (unsupportedObjects) { unsupportedObjects->push_back(sheet.Objects[k].Std.ShapeName); } instance.hide(); // build fallbacks for(uint l = 0; l < 2; ++l) { UInstance fallbackInstance = _IG->getByName(sheet.Objects[k].FallbackPass[l].ShapeName); if (!fallbackInstance.empty()) { fallbackInstance.hide(); CSkyObject so; so.init(sheet.Objects[k].FallbackPass[l], fallbackInstance, buildShareBitmapByName, _Bitmaps, sheet.Objects[k].VisibleInMainScene, sheet.Objects[k].VisibleInEnvMap); _Objects.push_back(so); if (_PlayList) { _PlayList->registerTransform(fallbackInstance, (sheet.Objects[k].FallbackPass[l].ShapeName + ".").c_str()); } } } } else if (!instance.empty()) { instance.hide(); // uses main instance and hides fallback instances CSkyObject so; so.init(sheet.Objects[k].Std, instance, buildShareBitmapByName, _Bitmaps, sheet.Objects[k].VisibleInMainScene, sheet.Objects[k].VisibleInEnvMap); _Objects.push_back(so); for(uint l = 0; l < 2; ++l) { UInstance fallbackInstance = _IG->getByName(sheet.Objects[k].FallbackPass[l].ShapeName); if (!fallbackInstance.empty()) fallbackInstance.hide(); } if (_PlayList) { _PlayList->registerTransform(instance, (sheet.Objects[k].Std.ShapeName + ".").c_str()); } } else { nlwarning("Object not found in scene : %s", sheet.Objects[k].Std.ShapeName.c_str()); } } // get gradient that gives sun light color bool alreadyBuilt; _AmbientSunLight = buildSharedBitmap(sheet.AmbientSunLightBitmap, buildShareBitmapByName, _Bitmaps, alreadyBuilt); _DiffuseSunLight = buildSharedBitmap(sheet.DiffuseSunLightBitmap, buildShareBitmapByName, _Bitmaps, alreadyBuilt); // _FogColor = buildSharedBitmap(sheet.FogColorBitmap, buildShareBitmapByName, _Bitmaps, alreadyBuilt); // _NumHourInDay = numHourInDay; _WaterEnvMapCameraHeight = sheet.WaterEnvMapCameraHeight; _WaterEnvMapAlpha= sheet.WaterEnvMapAlpha; }
// ------------------------------------------------------------------------------------------------ void CCharacter3D::createInstance (TChar3DPart i, const SCharacter3DSetup::SCharacterPart &part) { if (_Scene == NULL) { nlwarning ("CCharacter3D::createInstance : no scene setup."); return; } if (!_Instances[i].empty()) _Scene->deleteInstance (_Instances[i]); if ((!part.Name.empty()) && (part.Name != "none.shape")) _Instances[i] = _Scene->createInstance (part.Name); // if cannot create output some errors if (_Instances[i].empty()) { if ((i != Char3DPart_HandRightItem) && (i != Char3DPart_HandLeftItem)) nlwarning ("CCharacter3D::createInstance : cannot create the instance : %s.", part.Name.c_str()); return; } // FX Management // Advantage Fx if (!_InstancesFx[i].AdvantageFx.empty()) _Scene->deleteInstance (_InstancesFx[i].AdvantageFx); if ((!part.AdvFx.empty()) && (part.AdvFx != "none.shape")) { _InstancesFx[i].AdvantageFx = _Scene->createInstance (part.AdvFx); if (_InstancesFx[i].AdvantageFx.empty()) { nlwarning ("CCharacter3D::createInstance : cannot create the fx : %s.", part.AdvFx.c_str()); } else { CMatrix mat = _Instances[i].getMatrix(); mat.invert(); mat *= _InstancesFx[i].AdvantageFx.getMatrix(); _InstancesFx[i].AdvantageFx.setTransformMode(UTransformable::DirectMatrix); _InstancesFx[i].AdvantageFx.setMatrix(mat); _InstancesFx[i].AdvantageFx.parent(_Instances[i]); } } // Static Fx uint32 fx; for (fx = 0; fx < _InstancesFx[i].StaticFx.size(); ++fx) if (!_InstancesFx[i].StaticFx[fx].empty()) _Scene->deleteInstance(_InstancesFx[i].StaticFx[fx]); _InstancesFx[i].StaticFx.clear(); for (fx = 0; fx < part.StatFxNames.size(); ++fx) if ((!part.StatFxNames[fx].empty()) && (part.StatFxNames[fx] != "none.shape") && (!part.StatFxBones[fx].empty()) && (part.StatFxBones[fx] != "none.shape")) { sint boneID = _Skeleton.getBoneIdByName(part.StatFxBones[fx]); if (boneID != -1) { UInstance instance = _Scene->createInstance(part.StatFxNames[fx]); if (!instance.empty()) { instance.setTransformMode(UTransform::DirectMatrix); CMatrix mat; mat.setPos(part.StatFxOffss[fx]); instance.setMatrix(mat); _Skeleton.stickObject(instance, boneID); _InstancesFx[i].StaticFx.push_back(instance); } else { nlwarning("Can't create static fx %s sticked on bone %s", part.StatFxNames[fx].c_str(), part.StatFxBones[fx].c_str()); } } else { nlwarning("Can't find bone %s for static fx %s", part.StatFxBones[fx].c_str(), part.StatFxNames[fx].c_str()); } } }
// ************************************************************************************************* void makeInstanceTransparent(UInstance &inst, uint8 opacity, bool disableZWrite) { UShape shape= inst.getShape(); if(shape.empty()) return; uint numMats= shape.getNumMaterials(); if(numMats==0) return; if(numMats!=inst.getNumMaterials()) return; // instance transparent or not? if (opacity == 255) { // reset default shape opacity / transparency inst.setOpacity(shape.getDefaultOpacity()); inst.setTransparency(shape.getDefaultTransparency()); inst.setBypassLODOpacityFlag(false); } else { // Will have some blend material => sure not to be rendered in Opaque pass inst.setOpacity(false); inst.setTransparency(true); inst.setBypassLODOpacityFlag(true); // these flags prevails over the current lods flags for multi-lod objects } // set all materials for (uint32 j = 0; j < numMats; ++j) { NL3D::UInstanceMaterial matInst = inst.getMaterial(j); NL3D::UMaterial matShape= shape.getMaterial(j); // disalbe zwrite? if(disableZWrite) matInst.setZWrite(false); else matInst.setZWrite(matShape.getZWrite()); // if no more transparent if (opacity == 255) { // reset to default matInst.setBlend(matShape.getBlend()); matInst.setBlendFunc((NL3D::UInstanceMaterial::TBlend)matShape.getSrcBlend(), (NL3D::UInstanceMaterial::TBlend)matShape.getDstBlend()); // if orginal material is opaque or additif and has no alpha test, then ensure restore last tex env if needed CMaterial *destInternalMat = matInst.getObjectPtr(); if (!matShape.getBlend() && !matShape.getAlphaTest()) { if (destInternalMat->getShader() == CMaterial::Normal) { CMaterial *srcInternalMat = matShape.getObjectPtr(); uint numTex = 0; for (;numTex < 4 && srcInternalMat->getTexture(numTex) != NULL; ++numTex) {} if (numTex > 0) { if (srcInternalMat->getTexEnvMode(numTex - 1) != destInternalMat->getTexEnvMode(numTex - 1)) { destInternalMat->setTexEnvMode(numTex - 1, srcInternalMat->getTexEnvMode(numTex - 1)); } } } } if (destInternalMat->getShader() == CMaterial::Normal) { // if !lighted, restore color if (!destInternalMat->isLighted()) { CMaterial *srcInternalMat = matShape.getObjectPtr(); // restore alpha in color CRGBA color = destInternalMat->getColor(); color.A = srcInternalMat->getColor().A; destInternalMat->setColor(color); } } } else { // Enable blend matInst.setBlend(true); // If default is ???/one or , then use a srcalpha/one (eg: for Diamond-like weapons) if(matShape.getBlend() && (sint32)matShape.getDstBlend()==(sint32)NL3D::UInstanceMaterial::one) matInst.setBlendFunc(NL3D::UInstanceMaterial::srcalpha, NL3D::UInstanceMaterial::one); // else use a standard srcalpha/invsrcalpha else matInst.setBlendFunc(NL3D::UInstanceMaterial::srcalpha, NL3D::UInstanceMaterial::invsrcalpha); // if orginal material is opaque or additif and has no alpha test, then ensure that the alpha output is 'diffuse' CMaterial *internalMat = matInst.getObjectPtr(); if (!matShape.getBlend() && !matShape.getAlphaTest()) { if (internalMat->getShader() == CMaterial::Normal) { uint numTex = 0; for (;numTex < 4 && internalMat->getTexture(numTex) != NULL; ++numTex) {} if (numTex > 0) { internalMat->texEnvOpAlpha(numTex - 1, CMaterial::Replace); // if material is unlighted, then use the constant at this stage to set the alpha internalMat->texEnvArg0Alpha(numTex - 1, CMaterial::Diffuse, CMaterial::SrcAlpha); } } } if (internalMat->getShader() == CMaterial::Normal) { if (!internalMat->isLighted()) { // replace alpha in color CRGBA color = internalMat->getColor(); color.A = opacity; internalMat->setColor(color); } } } // suppose that default opacity is always 255 if (matInst.isLighted()) { matInst.setOpacity(opacity); } matInst.setAlphaTestThreshold(matShape.getAlphaTestThreshold()*((float)opacity)/255.0f); } }
void CPlayerR2CL::updateVisualPropertyVpc(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop) { if(skeleton()) { // Get the property. SPropVisualC visualC = *(SPropVisualC *)(&prop); // EYES _EyesColor = visualC.PropertySubData.EyesColor; UInstance inst; // must recreate the face asynchronously (because of color change / makeup change) inst= _Face.createLoadingFromCurrent(); // if exist if (!inst.empty()) { // change eyes color only applyColorSlot(_Face, _Face.ACSkin, _Face.ACUser, _Face.ACHair, visualC.PropertySubData.EyesColor); // Tattoo makeUp(inst, visualC.PropertySubData.Tattoo); // Morph static const char *baseName = "visage_00"; float MTmin, MTmax; CGenderInfo *pGI = getGenderInfo(); if (pGI == NULL) return; MTmin = pGI->BlendShapeMin[0]; MTmax = pGI->BlendShapeMax[0]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(0), (float)(visualC.PropertySubData.MorphTarget1) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[1]; MTmax = pGI->BlendShapeMax[1]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(1), (float)(visualC.PropertySubData.MorphTarget2) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[2]; MTmax = pGI->BlendShapeMax[2]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(2), (float)(visualC.PropertySubData.MorphTarget3) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[3]; MTmax = pGI->BlendShapeMax[3]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(3), (float)(visualC.PropertySubData.MorphTarget4) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[4]; MTmax = pGI->BlendShapeMax[4]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(4), (float)(visualC.PropertySubData.MorphTarget5) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[5]; MTmax = pGI->BlendShapeMax[5]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(5), (float)(visualC.PropertySubData.MorphTarget6) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[6]; MTmax = pGI->BlendShapeMax[6]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(6), (float)(visualC.PropertySubData.MorphTarget7) / 7.f * (MTmax-MTmin) + MTmin, true); MTmin = pGI->BlendShapeMin[7]; MTmax = pGI->BlendShapeMax[7]; if (!ClientCfg.BlendShapePatched) { MTmin = 0.0f; MTmax = 100.0f; } inst.setBlendShapeFactor(baseName + toString(7), (float)(visualC.PropertySubData.MorphTarget8) / 7.f * (MTmax-MTmin) + MTmin, true); } // Set the Gabarit float characterHeight = (float)((sint8)(visualC.PropertySubData.CharacterHeight)-7)/7.f; float torsoWidth = (float)((sint8)(visualC.PropertySubData.TorsoWidth)-7)/7.f; float armsWidth = (float)((sint8)(visualC.PropertySubData.ArmsWidth)-7)/7.f; float legsWidth = (float)((sint8)(visualC.PropertySubData.LegsWidth)-7)/7.f; float breastSize = (float)((sint8)(visualC.PropertySubData.BreastSize)-7)/7.f; float heightScale, baseHeightScale; // TODO : manage breast size GabaritSet.applyGabarit(*skeleton(), _Gender, people(), characterHeight, torsoWidth, armsWidth, legsWidth, breastSize, &heightScale); baseHeightScale = GabaritSet.getRefHeightScale(_Gender, people()); if(baseHeightScale != 0.f) _CustomScalePos = heightScale/baseHeightScale; else { _CustomScalePos = 1.f; nlwarning("PL::updateVPVpc:'%d': baseHeight == 0.", _Slot); } } else nlinfo("PL:updateVPVpc:'%d': Prop Vpc received before prop Vpa.", _Slot); }// updateVisualPropertyVpc //
//----------------------------------------------- // equip : // Compute the equipmenent worn. //----------------------------------------------- void CPlayerR2CL::equip(SLOTTYPE::EVisualSlot slot, uint index, uint color) { // Get the sheet according to the visual slot _Items[slot].Sheet = SheetMngr.getItem(slot, index); if(_Items[slot].Sheet) { const CItemSheet *item = _Items[slot].Sheet; // If the gender is a female get the right shape. if(_Gender == GSGENDER::female) equip(slot, item->getShapeFemale(), item); // Else get the default shape. else equip(slot, item->getShape(), item); // Check there is a shape. UInstance pInst = _Instances[slot].createLoadingFromCurrent(); if(!pInst.empty()) { // Set the right texture variation (quality). pInst.selectTextureSet((uint)item->MapVariant); _Instances[slot].TextureSet = item->MapVariant; // If Hair, color is for the head slot. if(slot == SLOTTYPE::HEAD_SLOT && item->Family != ITEMFAMILY::ARMOR) applyColorSlot(_Instances[slot], skin(), 0, color, _EyesColor); else { // Set the User Color. if(item->Color == -1) applyColorSlot(_Instances[slot], skin(), color, _HairColor, _EyesColor); // Set the Item Color. else if(item->Color != -2) applyColorSlot(_Instances[slot], skin(), item->Color, _HairColor, _EyesColor); // Else let the default color. else applyColorSlot(_Instances[slot], skin(), 0, _HairColor, _EyesColor); } } } // Default equipment. else { nlwarning("PL:equip(2):%d: VS '%d' default equipement used.", _Slot, slot); //sint idx = SheetMngr.getVSIndex(_PlayerSheet->GenderInfos[_Gender].Items[slot], slot); sint idx = SheetMngr.getVSIndex(getGenderInfo()->Items[slot], slot); if(idx != -1) { if(SheetMngr.getItem(slot, (uint)idx)) { // If the gender is a female get the right shape. if(_Gender == GSGENDER::female) equip(slot, SheetMngr.getItem(slot, (uint)idx)->getShapeFemale()); // Else get the default shape. else equip(slot, SheetMngr.getItem(slot, (uint)idx)->getShape()); } } } }// equip //
//----------------------------------------------- // updateParticlesActor : // //----------------------------------------------- void CSceneParser::updateParticlesActor(float difTime, CParticle &particle, UAnimation &animation) { // Get the entity pointer. CEntityCL *entity = getEntity(Sid(Sid::npc, (uint64)particle.Actor)); if(!entity) { nlwarning("CSceneParser::updateParticlesActor : cannot get the actor %d.", (uint64)particle.Actor); return; } // If the entity has no skeleton -> Next particle. if(!entity->skeleton()) { nlwarning("The particle follow an entity %d without a skeleton.", (uint64)particle.Actor); return; } // Matrix 90° CMatrix m90; m90.identity(); m90.rotateZ((float)(Pi/2.0)); // Matrix of the entity. CMatrix mChar = entity->skeleton()->getMatrix(); mChar.setPos(entity->pos()); // Animate all instances. for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i ) { std::string iName = particle.IGPtr->getInstanceName(i); UInstance instance = particle.IGPtr->getByName(iName); if(!instance) continue; instance->setTransformMode(UTransformable::RotQuat); CMatrix mAnim; mAnim.identity(); // If the animation has no track of position. UTrack* trackPos = animation.getTrackByName("PathPos"); if(!trackPos) trackPos = animation.getTrackByName(string(iName + "." + "PathPos").c_str()); if(trackPos) { CVector pos; trackPos->interpolate(difTime, pos); mAnim.setPos(pos); } // If the animation has no track of rotation. UTrack* trackRot = animation.getTrackByName("PathRotQuat"); if(!trackRot) trackRot = animation.getTrackByName(string(iName + "." + "PathRotQuat").c_str()); if(trackRot) { CQuat rot; trackPos->interpolate(difTime, rot); mAnim.setRot(rot); } CMatrix mFinal = mChar * m90 * mAnim; instance->setPos(mFinal.getPos()); instance->setRotQuat(mFinal.getRot()); } }// updateParticlesActor //