SceneObject* parseNode(KFbxNode *node, int level = 0) { KString s = node->GetName(); KFbxNodeAttribute::EAttributeType attributeType; stringstream ss; for (int i=0;i<level;i++){ ss<<" "; } SceneObject* sceneObject = NULL; MeshComponent* ga = NULL; if (node->GetNodeAttribute() == NULL){ ss<<"No node attribute"<<endl; } else { attributeType = node->GetNodeAttribute()->GetAttributeType(); switch (attributeType) { case KFbxNodeAttribute::eMARKER: ss<<"eMarker"<<endl; break; case KFbxNodeAttribute::eSKELETON: ss<<"eSkeleton"<<endl; break; case KFbxNodeAttribute::eMESH: { KFbxMesh *fbxMesh = node->GetMesh(); KFbxVector4 *controlPoints = fbxMesh->GetControlPoints(); int polygonCount = fbxMesh->GetPolygonCount(); vector<glm::vec3> vertices; vector<glm::vec3> normals; vector<glm::vec2> texCords; vector<int> polycount; assert(fbxMesh->GetLayerCount(KFbxLayerElement::eNORMAL)==1); // assume only one normal layer KFbxLayer *normalLayer = fbxMesh->GetLayer(0, KFbxLayerElement::eNORMAL); KFbxLayerElementNormal *normalElement = normalLayer->GetNormals(); KFbxLayerElementArrayTemplate<KFbxVector4> *normalArray = &(normalElement->GetDirectArray()); int normalCount = normalArray->GetCount(); vector<int> indices; assert(fbxMesh->GetControlPointsCount() <= USHRT_MAX); for (int i=0;i<fbxMesh->GetControlPointsCount();i++){ glm::vec3 v = toVector(controlPoints[i]); vertices.push_back(v); v = toVector(normalArray->GetAt(i)); normals.push_back(v); } for (int i=0;i<polygonCount;i++){ int polygonSize = fbxMesh->GetPolygonSize(i); polycount.push_back(polygonSize); for (int j=0;j<polygonSize;j++){ if (j>2){ // if polygon size > 2 then add first and last index // this triangulates the mesh int first = fbxMesh->GetPolygonVertex(i,0); int last = fbxMesh->GetPolygonVertex(i,j-1); indices.push_back(first); indices.push_back(last); } int polygonIndex = fbxMesh->GetPolygonVertex(i,j); indices.push_back(polygonIndex); /*KFbxVector4 vectorSrc = controlPoints[polygonIndex]; Vector3 vectorDst = toVector(vectorSrc); vertices.push_back(vectorDst); texCords.push_back(Vector2(0,0)); KFbxVector4 normalSrc = normalArray->GetAt(polygonIndex); Vector3 normalDst = toVector(normalSrc); normals.push_back(normalDst);*/ } } Mesh mesh; ss<<"Creating mesh: vertices "<<vertices.size()<<" normals "<<normals.size()<<" indices "<<indices.size()<<endl; mesh.SetVertices(vertices); mesh.SetNormals(normals); mesh.SetIndices(indices); sceneObject = new SceneObject(); ga = new MeshComponent(); ga->SetMesh(&mesh); sceneObject->AddCompnent(ga); // Set translate fbxDouble3 v3 = node->LclTranslation.Get(); glm::vec3 translate = toVector(v3); sceneObject->GetTransform()->SetPosition(translate); // Set rotation v3 = node->LclRotation.Get(); glm::vec3 rotation = toVector(v3)*Mathf::DEGREE_TO_RADIAN; sceneObject->GetTransform()->SetRotation(rotation); // Set scale v3 = node->LclScaling.Get(); glm::vec3 scale = toVector(v3); sceneObject->GetTransform()->SetScale(scale); } break; case KFbxNodeAttribute::eCAMERA: ss<<"eCAMERA"<<endl; break; case KFbxNodeAttribute::eLIGHT: ss<<"eLIGHT"<<endl; break; case KFbxNodeAttribute::eBOUNDARY: ss<<"eBOUNDARY"<<endl; break; default: ss<<s<<endl; } } if (node->GetChildCount()>0){ for (int i=0;i<node->GetChildCount();i++){ SceneObject *res = parseNode(node->GetChild(i),level+1); if (res!=NULL){ if (sceneObject == NULL){ sceneObject = new SceneObject(); } sceneObject->AddChild(res); } } } DEBUG(ss.str()); return sceneObject; }
void buildTable(gmtl::Vec3f floorDimensions) { float legHeight = 20.0f, legY = (floorDimensions[1] * 2.0f) + legHeight, //Y tableWidth = 25.0f, //X tableLength = 25.0f; //Z SceneObject* tableTop = new SceneObject("OBJs/cube.obj", tableWidth, floorDimensions[1], tableLength, program); tableTop->AddTranslation(gmtl::Vec3f(0.0f, legY+floorDimensions[1]+legHeight, 0.0f)); tableTop->type = TABLETOP; tableTop->parent = NULL; tableTop->SetTexture(LoadTexture("textures/dirt.ppm")); tableTop->children.clear(); sceneGraph.push_back(tableTop); SceneObject* brleg = new SceneObject("OBJs/cylinder.obj", ballRadius, legHeight, program); brleg->AddTranslation(gmtl::Vec3f(tableWidth - ballRadius, legY, -(tableWidth - ballRadius))); brleg->type = LEG; brleg->parent = NULL; brleg->SetTexture(LoadTexture("textures/dirt.ppm")); brleg->children.clear(); brleg->mass = FLT_MAX; brleg->velocity = ZERO_VECTOR; sceneGraph.push_back(brleg); SceneObject* blleg = new SceneObject("OBJs/cylinder.obj", ballRadius, legHeight, program); blleg->AddTranslation(gmtl::Vec3f(-(tableWidth - ballRadius), legY, -(tableWidth - ballRadius))); blleg->type = LEG; blleg->parent = NULL; blleg->SetTexture(LoadTexture("textures/dirt.ppm")); blleg->children.clear(); blleg->mass = FLT_MAX; blleg->velocity = ZERO_VECTOR; sceneGraph.push_back(blleg); SceneObject* frleg = new SceneObject("OBJs/cylinder.obj", ballRadius, legHeight, program); frleg->AddTranslation(gmtl::Vec3f(tableWidth - ballRadius, legY, tableWidth - ballRadius)); frleg->type = LEG; frleg->parent = NULL; frleg->SetTexture(LoadTexture("textures/dirt.ppm")); frleg->children.clear(); frleg->mass = FLT_MAX; frleg->velocity = ZERO_VECTOR; attractLeg = frleg; sceneGraph.push_back(frleg); SceneObject* flleg = new SceneObject("OBJs/cylinder.obj", ballRadius, legHeight, program); flleg->AddTranslation(gmtl::Vec3f(-(tableWidth - ballRadius), legY, tableWidth - ballRadius)); flleg->type = LEG; flleg->parent = NULL; flleg->SetTexture(LoadTexture("textures/dirt.ppm")); flleg->children.clear(); flleg->mass = FLT_MAX; flleg->velocity = ZERO_VECTOR; sceneGraph.push_back(flleg); }
bool OsgMovie::loadFile(std::string filename) { osgDB::Registry::instance()->loadLibrary("osgdb_ffmpeg.so"); //create shaders for left and right eye (use uniform to set mode, and also set which eye) // int eye 0 right eye, 1 left eye // mode 0 mono, 1 top down, 2 left right, 3 interlaced (need to complete 3 interlaced) /* static const char *fragShaderTop = { "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect movie_texture;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st;\n" " ivec2 size = textureSize(movie_texture, 0);\n" " coord.t = (size.t * 0.5) + (coord.t * 0.5); \n" " gl_FragColor = texture2DRect(movie_texture, coord);\n" "}\n" }; static const char *fragShaderBottom = { "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect movie_texture;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st;\n" " coord.t = (coord.t * 0.5); \n" " gl_FragColor = texture2DRect(movie_texture, coord);\n" "}\n" }; static const char *fragShaderLeft = { "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect movie_texture;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st;\n" " coord.s = (size.s * 0.5) \n" " gl_FragColor = texture2DRect(movie_texture, coord);\n" "}\n" }; static const char *fragShaderRight = { "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect movie_texture;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st;\n" " ivec2 size = textureSize(movie_texture, 0);\n" " coord.s = (size.s * 0.5) + (coord.s * 0.5); \n" " gl_FragColor = texture2DRect(movie_texture, coord);\n" "}\n" }; static const char *fragShaderEven = { "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect movie_texture;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st;\n" " ivec2 size = textureSize(movie_texture, 0); \n" " if( findLSB(coord.y) ) \n" " coord.s = (size.s * 0.5) + (coord.s * 0.5); \n" " gl_FragColor = texture2DRect(movie_texture, coord);\n" "}\n" }; */ static const char *fragShader = { "#extension GL_ARB_texture_rectangle : enable \n" "uniform sampler2DRect movie_texture; \n" "uniform int split;\n" "uniform int mode;\n" "uniform int type;\n" "uniform int eye;\n" "void main(void)\n" "{\n" " vec2 coord = gl_TexCoord[0].st; \n" " ivec2 size = textureSize(movie_texture, 0);\n" " if( (mode == 0) && split ) \n" " { \n" " if( type == 1 ) \n" " coord.y = (coord.y * 0.5); \n" " else \n" " coord.x = (coord.x * 0.5); \n" " } \n" " else if( mode == 1) \n" " { \n" " if( type == 1 ) \n" " coord.y = (coord.y * 0.5) + (0.5 * size.y * eye); \n" " else \n" " coord.x = (coord.x * 0.5) + (0.5 * size.x * eye); \n" " } \n" " gl_FragColor = texture2DRect(movie_texture, coord); \n" "}\n" }; osg::ref_ptr<osg::MatrixTransform> group = new osg::MatrixTransform; osg::ref_ptr<osg::Geode> geodeL = new osg::Geode; osg::ref_ptr<osg::Geode> geodeR = new osg::Geode; //get state for left geode osg::StateSet* stateset = geodeL->getOrCreateStateSet(); geodeL->setNodeMask(geodeL->getNodeMask() & ~(CULL_MASK_RIGHT)); stateset->addUniform(new osg::Uniform("eye",0)); //get state for right geode stateset = geodeR->getOrCreateStateSet(); geodeR->setNodeMask(geodeR->getNodeMask() & ~(CULL_MASK_LEFT)); geodeR->setNodeMask(geodeR->getNodeMask() & ~(CULL_MASK)); stateset->addUniform(new osg::Uniform("eye",1)); group->addChild(geodeR); group->addChild(geodeL); // add shader to group node osg::Program* program = new osg::Program; program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragShader)); // get name of file std::string name(filename); size_t found = filename.find_last_of("//"); if(found != filename.npos) { name = filename.substr(found + 1,filename.npos); } // create object to hold movie data struct VideoObject * currentobject = new struct VideoObject; currentobject->name = name; currentobject->stream = NULL; currentobject->scene = NULL; currentobject->firstPlay = false; currentobject->modeUniform = new osg::Uniform("mode",0); currentobject->typeUniform = new osg::Uniform("type",0); currentobject->splitUniform = new osg::Uniform("split",0); // set state parameters stateset = group->getOrCreateStateSet(); stateset->setAttribute(program); stateset->addUniform(new osg::Uniform("movie_texture",0)); stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); stateset->addUniform(currentobject->modeUniform); stateset->addUniform(currentobject->typeUniform); stateset->addUniform(currentobject->splitUniform); osg::Image* image = osgDB::readImageFile(filename.c_str()); osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); if (imagestream) { currentobject->stream = imagestream; currentobject->stream->pause(); osg::ImageStream::AudioStreams& audioStreams = currentobject->stream->getAudioStreams(); if ( !audioStreams.empty() ) { #ifdef FMOD_FOUND osg::AudioStream* audioStream = audioStreams[0].get(); audioStream->setAudioSink(new FmodAudioSink(audioStream)); currentobject->stream->setVolume(1.0); #endif } } if (image) { float width = image->s() * image->getPixelAspectRatio(); float height = image->t(); //check the ratio of the image float widthFactor = 1.0; if( (width / height) > 2.5 ) { widthFactor = 0.5; currentobject->splitUniform->set(1); // indicate double image } osg::ref_ptr<osg::Drawable> drawable = myCreateTexturedQuadGeometry(osg::Vec3(0.0,0.0,0.0), width * widthFactor, height,image); if (image->isImageTranslucent()) { drawable->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); drawable->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } geodeR->addDrawable(drawable.get()); geodeL->addDrawable(drawable.get()); // set bound group->dirtyBound(); } else { printf("Unable to read file\n"); return false; } // add stream to the scene SceneObject * so = new SceneObject(name,false,false,false,true,true); PluginHelper::registerSceneObject(so,"OsgMovie"); so->addChild(group); so->attachToScene(); so->setNavigationOn(true); so->addMoveMenuItem(); so->addNavigationMenuItem(); currentobject->scene = so; // simple default menu MenuCheckbox * mcb = new MenuCheckbox("Play", false); // make toggle button mcb->setCallback(this); so->addMenuItem(mcb); _playMap[currentobject] = mcb; MenuButton * mrb = new MenuButton("Restart"); mrb->setCallback(this); so->addMenuItem(mrb); _restartMap[currentobject] = mrb; MenuCheckbox * scb = new MenuCheckbox("Stereo", false); // make toggle button scb->setCallback(this); so->addMenuItem(scb); _stereoMap[currentobject] = scb; MenuCheckbox * tbcb = new MenuCheckbox("TopBottom", false); // make toggle button tbcb->setCallback(this); so->addMenuItem(tbcb); _stereoTypeMap[currentobject] = tbcb; MenuRangeValue * ms = new MenuRangeValue("Scale", 0.0, 10.0, 1.0); // make video scale ms->setCallback(this); so->addMenuItem(ms); _scaleMap[currentobject] = ms; MenuButton * msab = new MenuButton("Save"); // make position and scale of video msab->setCallback(this); so->addMenuItem(msab); _saveMap[currentobject] = msab; MenuButton * mscb = new MenuButton("Load"); // load position of video mscb->setCallback(this); so->addMenuItem(mscb); _loadMap[currentobject] = mscb; MenuButton * mb = new MenuButton("Delete"); mb->setCallback(this); so->addMenuItem(mb); _deleteMap[currentobject] = mb; _loadedVideos.push_back(currentobject); return true; }
void PlayerCreationManager::addProfessionStartingItems(CreatureObject* creature, const String& profession, const String& clientTemplate, bool equipmentOnly) { ProfessionDefaultsInfo* professionData = professionDefaultsInfo.get( profession); if (professionData == NULL) professionData = professionDefaultsInfo.get(0); Reference<Skill*> startingSkill = professionData->getSkill(); //Reference<Skill*> startingSkill = SkillManager::instance()->getSkill("crafting_artisan_novice"); //Starting skill. SkillManager::instance()->awardSkill(startingSkill->getSkillName(), creature, false, true, true); //Set the hams. for (int i = 0; i < 6; i++) { int mod = 1000; // All stats start at 1k. creature->setBaseHAM(i, mod, false); creature->setHAM(i, mod, false); creature->setMaxHAM(i, mod, false); } SortedVector < String > *itemTemplates = professionData->getProfessionItems( clientTemplate); if (itemTemplates == NULL) return; for (int i = 0; i < itemTemplates->size(); ++i) { String itemTemplate = itemTemplates->get(i); //instance()->info("Add Profession Starting Items: " + itemTemplate, true); ManagedReference<SceneObject*> item; try { item = zoneServer->createObject(itemTemplate.hashCode(), 1); } catch (Exception& e) { } if (item != NULL) { String error; if (creature->canAddObject(item, 4, error) == 0) { creature->transferObject(item, 4, false); } else { item->destroyObjectFromDatabase(true); } } else { error( "could not create item in PlayerCreationManager::addProfessionStartingItems: " + itemTemplate); } } // Get inventory. if (!equipmentOnly) { SceneObject* inventory = creature->getSlottedObject("inventory"); if (inventory == NULL) { return; } //Add profession specific items. for (int itemNumber = 0; itemNumber < professionData->getStartingItems()->size(); itemNumber++) { String itemTemplate = professionData->getStartingItems()->get( itemNumber); ManagedReference<SceneObject*> item = zoneServer->createObject( itemTemplate.hashCode(), 1); if (item != NULL) { if (!inventory->transferObject(item, -1, false)) { item->destroyObjectFromDatabase(true); } } else if (item == NULL) { error("could not create profession item " + itemTemplate); } } } }
SceneObject Scene::parseObject(QXmlStreamReader &xml) { SceneObject obj; if(xml.tokenType() != QXmlStreamReader::StartElement && xml.name() == "object") { return obj; } QXmlStreamAttributes attributes = xml.attributes(); assert( attributes.hasAttribute("shape") ); assert( attributes.hasAttribute("material") ); string shapestr = attributes.value("shape").toString().toStdString(); string materstr = attributes.value("material").toString().toStdString(); obj = SceneObject(shapestr, materstr); // parse transformation information glm::vec3 S = glm::vec3(1, 1, 1); glm::vec3 T = glm::vec3(0.0); glm::vec3 R = glm::vec3(0.0); xml.readNext(); while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "object")) { if(xml.tokenType() == QXmlStreamReader::StartElement) { if( xml.name() == "transformation" ) { xml.readNext(); while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "transformation")) { if(xml.tokenType() == QXmlStreamReader::StartElement) { if(xml.name() == "translation") { T = parseVectorNode(xml); } if(xml.name() == "scale") { S = parseVectorNode(xml); } if(xml.name() == "rotation") { R = parseVectorNode(xml); } } xml.readNext(); } } } xml.readNext(); } obj.setTransformation(Transformation(S, R, T)); xml.readNext(); return obj; }
int CreatureManagerImplementation::notifyDestruction(TangibleObject* destructor, AiAgent* destructedObject, int condition) { if (destructedObject->isDead()) return 1; destructedObject->setPosture(CreaturePosture::DEAD, true); destructedObject->updateTimeOfDeath(); ManagedReference<PlayerManager*> playerManager = zoneServer->getPlayerManager(); // lets unlock destructor so we dont get into complicated deadlocks // lets copy the damage map before we remove it all ThreatMap* threatMap = destructedObject->getThreatMap(); ThreatMap copyThreatMap(*threatMap); threatMap->removeObservers(); threatMap->removeAll(); // we can clear the original one if (destructedObject != destructor) destructor->unlock(); bool shouldRescheduleCorpseDestruction = false; try { ManagedReference<CreatureObject*> player = copyThreatMap.getHighestDamageGroupLeader(); uint64 ownerID = 0; if (player != NULL) { if(player->isGrouped()) { ownerID = player->getGroupID(); } else { ownerID = player->getObjectID(); } if (player->isPlayerCreature()) { Locker locker(player, destructedObject); player->notifyObservers(ObserverEventType::KILLEDCREATURE, destructedObject); FactionManager* factionManager = FactionManager::instance(); if (!destructedObject->getPvPFaction().isEmpty() && !destructedObject->isEventMob()) { int level = destructedObject->getLevel(); if(!player->isGrouped()) factionManager->awardFactionStanding(player, destructedObject->getPvPFaction(), level); else factionManager->awardFactionStanding(copyThreatMap.getHighestDamagePlayer(), destructedObject->getPvPFaction(), level); } } } if (playerManager != NULL) playerManager->disseminateExperience(destructedObject, ©ThreatMap); SceneObject* creatureInventory = destructedObject->getSlottedObject("inventory"); if (creatureInventory != NULL && player != NULL && player->isPlayerCreature()) { LootManager* lootManager = zoneServer->getLootManager(); if (destructedObject->isNonPlayerCreatureObject() && !destructedObject->isEventMob()) destructedObject->setCashCredits(lootManager->calculateLootCredits(destructedObject->getLevel())); creatureInventory->setContainerOwnerID(ownerID); lootManager->createLoot(creatureInventory, destructedObject); } CombatManager::instance()->attemptPeace(destructedObject); // Check to see if we can expedite the despawn of this corpse // We can expedite the despawn when corpse has no loot, no credits, player cannot harvest, and no group members in range can harvest shouldRescheduleCorpseDestruction = playerManager->shouldRescheduleCorpseDestruction(player, destructedObject); } catch (...) { destructedObject->scheduleDespawn(); // now we can safely lock destructor again if (destructedObject != destructor) destructor->wlock(destructedObject); throw; } destructedObject->scheduleDespawn(); if (shouldRescheduleCorpseDestruction) { Reference<DespawnCreatureTask*> despawn = destructedObject->getPendingTask("despawn").castTo<DespawnCreatureTask*>(); if (despawn != NULL) { despawn->cancel(); despawn->reschedule(10000); } } // now we can safely lock destructor again if (destructedObject != destructor) destructor->wlock(destructedObject); return 1; }
int CoaEncodedDiskMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* player, byte selectedID) { if (!player->isPlayerCreature()) { return 0; } SceneObject* inventory = player->getSlottedObject("inventory"); if (inventory == NULL) { return 0; } if (!inventory->hasObjectInContainer(sceneObject->getObjectID())) { player->sendSystemMessage("@encoded_disk/message_fragment:sys_not_in_inv"); // The disk can't be used unless it is in your inventory! return 0; } TangibleObject* disk = cast<TangibleObject*>(sceneObject); if (disk == NULL) { return 0; } PlayerObject* ghost = player->getPlayerObject(); if (ghost == NULL) { return 0; } String faction = getFaction(disk); if (faction.isEmpty()) { return 0; } bool decoded = isDecoded(disk); if (selectedID == 20) { String file = "@theme_park/alderaan/act2/" + faction + "_missions"; String title, body; if (faction == "imperial") { title = file + ":disk_title"; body = file + ":disk_text"; } else if (faction == "rebel" && decoded) { title = file + ":disk_decoded_title"; body = file + ":disk_decoded_text"; } else { title = file + ":disk_encoded_title"; body = file + ":disk_encoded_text"; } ManagedReference<SuiMessageBox*> box = new SuiMessageBox(player, 0); box->setPromptTitle(title); box->setPromptText(body); box->setUsingObject(disk); box->setOkButton(true, "@theme_park/alderaan/act2/shared_" + faction + "_missions:close"); // Close ghost->addSuiBox(box); player->sendMessage(box->generateMessage()); return 0; } else if (selectedID == 68) { if (faction != "rebel") { return 0; } String file = "@theme_park/alderaan/act2/shared_" + faction + "_missions"; uint32 decoderCRC = STRING_HASHCODE("object/tangible/encoded_disk/dead_eye_decoder.iff"); bool hasDecoder = false; for (int i=0; i< inventory->getContainerObjectsSize(); i++) { SceneObject* sco = inventory->getContainerObject(i); if (sco->getServerObjectCRC() == decoderCRC) { hasDecoder = true; break; } } if (hasDecoder) { String key = "disk_name_decoded"; StringId stringid("theme_park/alderaan/act2/shared_rebel_missions", key); Locker locker(disk); disk->setObjectName(stringid, true); player->sendSystemMessage(file + ":decoded_data_disk"); // Using the old Imperial Decoder you were able to decode the Dead Eye message. return 0; } else { player->sendSystemMessage(file + ":decode_failed"); // You do not have the required decoder to decode this message. return 0; } } return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject, player, selectedID); }
void SceneObjectImplementation::broadcastMessagesPrivate(Vector<BasePacket*>* messages, SceneObject* selfObject) { ZoneServer* zoneServer = getZoneServer(); if (zoneServer != NULL && zoneServer->isServerLoading()) return; if (parent.get() != NULL) { ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get()); if (grandParent != NULL) { grandParent->broadcastMessagesPrivate(messages, selfObject); return; } else { while (!messages->isEmpty()) { delete messages->remove(0); } return; } } if (zone == NULL) { while (!messages->isEmpty()) { delete messages->remove(0); } return; } //getZone()->rlock(); //Locker zoneLocker(zone); bool readlock = !zone->isLockedByCurrentThread(); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; int maxInRangeObjectCount = 0; // zone->rlock(readlock); try { if (closeobjects == NULL) { info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagesPrivate", true); zone->getInRangeObjects(getPositionX(), getPositionY(), 192, &closeSceneObjects, true); maxInRangeObjectCount = closeSceneObjects.size(); } else { maxInRangeObjectCount = closeobjects->size(); closeSceneObjects.removeAll(maxInRangeObjectCount, 10); //closeSceneObjects.addAll(*closeobjects); closeobjects->safeCopyTo(closeSceneObjects); maxInRangeObjectCount = closeSceneObjects.size(); } } catch (Exception& e) { } //getZone()->runlock(); //zoneLocker.release(); // zone->runlock(readlock); for (int i = 0; i < maxInRangeObjectCount; ++i) { SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get()); if (selfObject == scno) continue; ManagedReference<ZoneClientSession*> client = scno->getClient(); if (scno->isVehicleObject() || client != NULL || scno->isMount()) { for (int j = 0; j < messages->size(); ++j) { BasePacket* msg = messages->get(j); scno->sendMessage(msg->clone()); } } } while (!messages->isEmpty()) { delete messages->remove(0); } }
void TangibleObjectImplementation::repair(CreatureObject* player) { if(player == NULL || player->getZoneServer() == NULL) return; if(!isASubChildOf(player)) return; if (getConditionDamage() == 0) { player->sendSystemMessage("That item is not in need of repair."); return; } //Condition is unrepairable if ((getMaxCondition() - getConditionDamage()) <= 0) { StringIdChatParameter cantrepair("error_message", "sys_repair_unrepairable"); cantrepair.setTT(getDisplayedName()); player->sendSystemMessage(cantrepair); //%TT's condition is beyond repair even for your skills. return; } SceneObject* inventory = player->getSlottedObject("inventory"); if(inventory == NULL) return; ManagedReference<RepairTool*> repairTool = NULL; Reference<RepairToolTemplate*> repairTemplate = NULL; for(int i = 0; i < inventory->getContainerObjectsSize(); ++i) { ManagedReference<SceneObject*> item = inventory->getContainerObject(i); if(item->isRepairTool()) { repairTemplate = cast<RepairToolTemplate*>(item->getObjectTemplate()); if (repairTemplate == NULL) { error("No RepairToolTemplate for: " + String::valueOf(item->getServerObjectCRC())); return; } if(repairTemplate->getRepairType() & getGameObjectType()) { repairTool = cast<RepairTool*>(item.get()); break; } repairTemplate = NULL; } } if(repairTool == NULL) return; /// Luck Roll + Profession Mod(25) + Luck Tapes /// + Station Mod - BF /// Luck Roll int roll = System::random(100); int repairChance = roll; /// Profession Bonus if(player->hasSkill(repairTemplate->getSkill())) repairChance += 35; /// Get Skill mods repairChance += player->getSkillMod(repairTemplate->getSkillMod()); repairChance += player->getSkillMod("crafting_repair"); repairChance += player->getSkillMod("force_repair_bonus"); /// use tool quality to lower chances if bad tool float quality = 1.f - (((100.f - repairTool->getQuality()) / 2) / 100.f); repairChance *= quality; ManagedReference<PlayerManager*> playerMan = player->getZoneServer()->getPlayerManager(); /// Increase if near station if(playerMan->getNearbyCraftingStation(player, repairTemplate->getStationType()) != NULL) { repairChance += 15; } /// Subtract battle fatigue repairChance -= (player->getShockWounds() / 2); /// Subtract complexity repairChance -= (getComplexity() / 3); /// 5% random failure if(getMaxCondition() < 20 || roll < 5) repairChance = 0; if(roll > 95) repairChance = 100; String result = repairAttempt(repairChance); Locker locker(repairTool); repairTool->destroyObjectFromWorld(true); repairTool->destroyObjectFromDatabase(true); player->sendSystemMessage(result); }
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) { ZoneServer* zoneServer = getZoneServer(); if (zoneServer != NULL && zoneServer->isServerLoading()) return; if (parent.get() != NULL) { ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get()); if (grandParent != NULL) { grandParent->broadcastDestroyPrivate(object, selfObject); return; } else { return; } } if (zone == NULL) return; //Locker zoneLocker(zone); // bool readlock = !zone->isLockedByCurrentThread(); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; int maxInRangeObjectCount = 0; // zone->rlock(readlock); try { if (closeobjects == NULL) { info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true); zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true); maxInRangeObjectCount = closeSceneObjects.size(); } else { CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects; closeSceneObjects.removeAll(vec->size(), 10); // closeSceneObjects.addAll(*closeobjects); vec->safeCopyTo(closeSceneObjects); maxInRangeObjectCount = closeSceneObjects.size();//closeobjects->size(); } } catch (...) { //zone->runlock(readlock); throw; } // zone->runlock(readlock); for (int i = 0; i < maxInRangeObjectCount; ++i) { SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get()); if (selfObject == scno) continue; ManagedReference<ZoneClientSession*> client = scno->getClient(); if (scno->isVehicleObject() || client != NULL || scno->isMount()) { object->sendDestroyTo(scno); } } }
void SceneObjectImplementation::broadcastMessagePrivate(BasePacket* message, SceneObject* selfObject, bool lockZone) { ZoneServer* zoneServer = getZoneServer(); if (zoneServer != NULL && zoneServer->isServerLoading()) return; if (parent.get() != NULL) { ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get()); if (grandParent != NULL) { grandParent->broadcastMessagePrivate(message, selfObject, lockZone); return; } else { delete message; return; } } if (zone == NULL) { delete message; return; } //Locker zoneLocker(zone); //getZone()->rlock(lockZone); // bool readlock = lockZone && !zone->isLockedByCurrentThread(); SortedVector<ManagedReference<QuadTreeEntry*> >* closeSceneObjects = NULL; SortedVector<ManagedReference<QuadTreeEntry*> >* closeNoneReference = NULL; int maxInRangeObjectCount = 0; bool deleteVector = true; try { // zone->rlock(readlock); if (closeobjects == NULL) { info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagePrivate", true); closeSceneObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >(); zone->getInRangeObjects(getPositionX(), getPositionY(), 192, closeSceneObjects, true); maxInRangeObjectCount = closeSceneObjects->size(); deleteVector = true; } else { // maxInRangeObjectCount = closeobjects->size(); //closeSceneObjects = closeobjects; closeNoneReference = new SortedVector<ManagedReference<QuadTreeEntry*> >(maxInRangeObjectCount, 50); /* for (int i = 0; i < closeobjects->size(); ++i) { closeNoneReference->add(closeobjects->get(i).get()); } */ closeobjects->safeCopyTo(*closeNoneReference); maxInRangeObjectCount = closeNoneReference->size(); //closeSceneObjects.removeAll(maxInRangeObjectCount, 10); //closeSceneObjects.addAll(*closeobjects); } /* for (int i = 0; i < maxInRangeObjectCount; ++i) { SceneObject* scno = cast<SceneObject*>(closeSceneObjects->get(i).get()); if (selfObject == scno) continue; ManagedReference<ZoneClientSession*> client = scno->getClient(); if (client != NULL || scno->isVehicleObject()) { scno->sendMessage(message->clone()); } } */ //zone->runlock(readlock); } catch (...) { // zone->runlock(readlock); delete message; throw; } for (int i = 0; i < maxInRangeObjectCount; ++i) { SceneObject* scno; if (closeSceneObjects != NULL) scno = cast<SceneObject*>(closeSceneObjects->get(i).get()); else scno = cast<SceneObject*>(closeNoneReference->get(i).get()); if (selfObject == scno) continue; ManagedReference<ZoneClientSession*> client = scno->getClient(); if ((dynamic_cast<VehicleObject*>(scno) != NULL) || client != NULL || scno->isMount()) scno->sendMessage(message->clone()); } delete message; if (closeSceneObjects != NULL) delete closeSceneObjects; else delete closeNoneReference; }
bool SceneObject::operator<(const SceneObject& other) { return GetZOrder() < other.GetZOrder(); }
void OsgChromosome::renderChromosome(char * file){ Sphere * mysphere; ShapeDrawable * mydrawable; Geode* mygeode = new Geode(); osg::ref_ptr<osg::Material> pMaterial; ifstream myReadFile; SceneObject * so = new SceneObject(file, true, true, true, true, false); PluginHelper::registerSceneObject(so); so->attachToScene(); so->setNavigationOn(true); so->addMoveMenuItem(); so->addNavigationMenuItem(); // open file to read myReadFile.open(file); string chr, start, end, comp, x, y, z, output; Vec3 prev, curr; Vec4 color; bool isFirst = true; if (myReadFile.is_open()) { printf("is open\n"); // get rid of top line getline(myReadFile, output); // read each table entry while (!myReadFile.eof()) { myReadFile >> chr; myReadFile >> start; myReadFile >> end; myReadFile >> comp; myReadFile >> x; myReadFile >> y; myReadFile >> z; curr = Vec3(atof(x.c_str()), atof(y.c_str()), atof(z.c_str())); mysphere = new Sphere(curr, .02); mydrawable = new ShapeDrawable(mysphere); mygeode = new Geode(); mygeode->addDrawable(mydrawable); so->addChild(mygeode); //root->addChild(mygeode); // determine the color of the segment pMaterial = new osg::Material; if (comp.compare("A") == 0) color = Vec4(1,0,0,1); else if (comp.compare("B") == 0) color = Vec4(0,0,1,1); else color = Vec4(0,1,0,1); // set the color of the sphere pMaterial->setDiffuse( osg::Material::FRONT, color); mygeode->getOrCreateStateSet()->setAttribute( pMaterial, osg::StateAttribute::OVERRIDE ); // draw the cylinder bewtween spheres if (!isFirst) { //mygeode = new Geode(); AddCylinderBetweenPoints(prev, curr, (float) .02, color, so/*(Group *) root*/); //root->addChild(mygeode); } prev = curr; isFirst = false; } printf("get attached is %d, number of children is %d\n", so->getAttached(), so->getNumChildObjects()); }
void FireworkShowMenuComponent::addEvent(CreatureObject* player, FireworkObject* fireworkShow) const { DataObjectComponent* data = fireworkShow->getDataObjectComponent()->get(); if (data == NULL || !data->isFireworkShowData()) return; FireworkShowDataComponent* fireworkShowData = cast<FireworkShowDataComponent*>(data); int curFireworks = fireworkShowData->getTotalFireworkCount(); int showCapacity = fireworkShow->getCapacity(); ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); if (ghost == NULL) return; if (curFireworks >= showCapacity && !ghost->isPrivileged()) { player->sendSystemMessage("This firework show is at full capacity."); return; } if (ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_ADDEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REMOVEEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REORDERSHOW) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_MODIFYEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_DELAYSELECTION)) { return; } Locker plocker(player); ManagedReference<SuiListBox*> suiBox = new SuiListBox(player, SuiWindowType::FIREWORK_SHOW_ADDEVENT, SuiListBox::HANDLETWOBUTTON); suiBox->setPromptTitle("Select Show Addition"); suiBox->setPromptText("Select the firework to append to the end of the show package."); suiBox->setOkButton(true, "@ok"); suiBox->setCancelButton(true, "@cancel"); suiBox->setUsingObject(fireworkShow); ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory"); SceneObject* sceneObject = NULL; for (int i = 0; i < inventory->getContainerObjectsSize(); i++) { sceneObject = inventory->getContainerObject(i); if (sceneObject == NULL) continue; FireworkObject* firework = cast<FireworkObject*>(sceneObject); if (firework == NULL) continue; DataObjectComponent* data = firework->getDataObjectComponent()->get(); if (data != NULL && data->isFireworkShowData()) continue; if (sceneObject->getObjectID() != fireworkShow->getObjectID()) { String itemWithUseCount = sceneObject->getDisplayedName() + " (" + firework->getUseCount() + ")"; suiBox->addMenuItem(itemWithUseCount, sceneObject->getObjectID()); } } suiBox->setCallback(new FireworkShowAddEventSuiCallback(player->getZoneServer())); ghost->addSuiBox(suiBox); player->sendMessage(suiBox->generateMessage()); }
void ChatManagerImplementation::handleSocialInternalMessage(CreatureObject* sender, const UnicodeString& arguments) { if (sender->isPlayerCreature()) { ManagedReference<PlayerObject*> senderGhost = sender->getPlayerObject(); if (senderGhost == NULL) return; if (senderGhost->isMuted()) { String reason = senderGhost->getMutedReason(); if (reason != "") sender->sendSystemMessage("Your chat abilities are currently disabled by Customer Support for '" + reason + "'."); else sender->sendSystemMessage("Your chat abilities are currently disabled by Customer Support."); return; } } Zone* zone = sender->getZone(); if (zone == NULL) return; StringTokenizer tokenizer(arguments.toString()); uint64 targetid; uint32 emoteid, unkint, unkint2; try { targetid = tokenizer.getLongToken(); emoteid = tokenizer.getIntToken(); unkint = tokenizer.getIntToken(); unkint2 = tokenizer.getIntToken(); } catch (const Exception& e) { return; } //bool readlock = !zone->isLockedByCurrentThread(); bool showtext = true; if (unkint2 == 0) showtext = false; String firstName; if (sender->isPlayerCreature()) firstName = (cast<CreatureObject*>(sender))->getFirstName().toLowerCase(); CloseObjectsVector* vec = (CloseObjectsVector*) sender->getCloseObjects(); SortedVector<QuadTreeEntry* > closeEntryObjects(200, 50); if (vec != NULL) { vec->safeCopyTo(closeEntryObjects); } else { sender->info("Null closeobjects vector in ChatManager::handleSocialInternalMessage", true); zone->getInRangeObjects(sender->getWorldPositionX(), sender->getWorldPositionX(), 128, &closeEntryObjects, true); } float range = defaultSpatialChatDistance; for (int i = 0; i < closeEntryObjects.size(); ++i) { SceneObject* object = cast<SceneObject*>(closeEntryObjects.get(i)); if (object->isPlayerCreature()) { CreatureObject* creature = cast<CreatureObject*>(object); Reference<PlayerObject*> ghost = creature->getSlottedObject("ghost").castTo<PlayerObject*>(); if (ghost == NULL) continue; if (!ghost->isIgnoring(firstName) && creature->isInRange(sender, range)) { Emote* emsg = new Emote(creature, sender, targetid, emoteid, showtext); creature->sendMessage(emsg); } } } }
void SceneManager::sceneChange() { int activeScreenNumber = 0; // Handle removing the scene if (_scene) { activeScreenNumber = _scene->_activeScreenNumber; _scene->remove(); } // Clear the scene objects SynchronizedList<SceneObject *>::iterator io = _globals->_sceneObjects->begin(); while (io != _globals->_sceneObjects->end()) { SceneObject *sceneObj = *io; ++io; sceneObj->removeObject(); } // Clear the secondary scene object list io = _globals->_sceneManager._altSceneObjects.begin(); while (io != _globals->_sceneManager._altSceneObjects.end()) { SceneObject *sceneObj = *io; ++io; sceneObj->removeObject(); } // Clear the hotspot list SynchronizedList<SceneItem *>::iterator ii = _globals->_sceneItems.begin(); while (ii != _globals->_sceneItems.end()) { SceneItem *sceneItem = *ii; ++ii; sceneItem->remove(); } // TODO: Clear _list_45BAA list // If there is an active scene, deactivate it if (_scene) { _previousScene = _sceneNumber; delete _scene; _scene = NULL; _sceneNumber = -1; } // Set the next scene to be active _sceneNumber = _nextSceneNumber; // Free any regions disposeRegions(); // Ensure that the same number of objects are registered now as when the scene started if (_objectCount > 0) { assert(_objectCount == _saver->getObjectCount()); } _objectCount = _saver->getObjectCount(); _globals->_sceneHandler._delayTicks = 2; // Instantiate and set the new scene _scene = getNewScene(); if (!_saver->getMacroRestoreFlag()) _scene->postInit(); else _scene->loadScene(activeScreenNumber); }
void ChatManagerImplementation::broadcastMessage(CreatureObject* player, const UnicodeString& message, uint64 target, uint32 moodid, uint32 mood2) { Zone* zone = player->getZone(); PlayerObject* myGhost = NULL; bool godMode = false; if (zone == NULL) return; int language = 0; String firstName; if (player->isPlayerCreature() /*|| !((Player *)player)->isChatMuted() */) { CreatureObject* playerCreature = cast<CreatureObject*>(player); if (playerCreature) { firstName = playerCreature->getFirstName().toLowerCase(); myGhost = playerCreature->getPlayerObject(); } if (myGhost) language = myGhost->getLanguageID(); } if (myGhost) { if (myGhost->hasGodMode()) godMode = true; } StringIdChatParameter* param = NULL; if (message[0] == '@' && message.indexOf(":") != -1) { param = new StringIdChatParameter(message.toString()); } CloseObjectsVector* closeObjects = (CloseObjectsVector*) player->getCloseObjects(); SortedVector<QuadTreeEntry*> closeEntryObjects(200, 50); if (closeObjects != NULL) { closeObjects->safeCopyTo(closeEntryObjects); } else { player->info("Null closeobjects vector in ChatManager::broadcastMessage", true); zone->getInRangeObjects(player->getWorldPositionX(), player->getWorldPositionY(), 128, &closeEntryObjects, true); } float range = defaultSpatialChatDistance; float specialRange = spatialChatDistances.get(mood2); if (specialRange != -1) { range = specialRange; } try { for (int i = 0; i < closeEntryObjects.size(); ++i) { SceneObject* object = cast<SceneObject*>(closeEntryObjects.get(i)); if (player->isInRange(object, range)) { //Notify observers that are expecting spatial chat. if (object->getObserverCount(ObserverEventType::SPATIALCHATRECEIVED)) { ManagedReference<ChatMessage*> chatMessage = new ChatMessage(); chatMessage->setString(message.toString()); EXECUTE_TASK_3(object, chatMessage, player, { if (player_p == NULL || object_p == NULL) return; Locker locker(object_p); SortedVector<ManagedReference<Observer*> > observers = object_p->getObservers(ObserverEventType::SPATIALCHATRECEIVED); for (int oc = 0; oc < observers.size(); oc++) { Observer* observer = observers.get(oc); Locker clocker(observer, object_p); if (observer->notifyObserverEvent(ObserverEventType::SPATIALCHATRECEIVED, object_p, chatMessage_p, player_p->getObjectID()) == 1) object_p->dropObserver(ObserverEventType::SPATIALCHATRECEIVED, observer); } }); } if (object->isPlayerCreature()) { CreatureObject* creature = cast<CreatureObject*>(object); PlayerObject* ghost = creature->getPlayerObject(); if (ghost == NULL) continue; if (!ghost->isIgnoring(firstName) || godMode) { SpatialChat* cmsg = NULL; if (param == NULL) { cmsg = new SpatialChat(player->getObjectID(), creature->getObjectID(), message, target, moodid, mood2, language); } else { cmsg = new SpatialChat(player->getObjectID(), creature->getObjectID(), *param, target, moodid, mood2); } creature->sendMessage(cmsg); } } else if( object->isPet() ){ AiAgent* pet = cast<AiAgent*>(object); if (pet == NULL ) continue; if( pet->isDead() || pet->isIncapacitated() ) continue; PetManager* petManager = server->getPetManager(); Locker clocker(pet, player); petManager->handleChat( player, pet, message.toString() ); } } }
void Application::Update( void ) { if (!m_initialized) { return; } // 计算delta T LARGE_INTEGER counter; QueryPerformanceCounter(&counter); float dt = static_cast<float>((counter.QuadPart - m_nTicks) / double(m_nTicksPerSecond)); m_nTicks = counter.QuadPart; // 显示FPS char str[256]; sprintf_s(str, 256, "FPS: %.1f", 1.0f / dt); m_textOutput->Print(str, 5, 5); // 切换shading mode if (m_inputCapturer->IsKeyPressed(KC_T)) { int shadeMode = m_renderer->GetShadeMode(); if (shadeMode == Renderer::SHADING_MODE_MAX - 1) { shadeMode = Renderer::SHADING_MODE_START; } shadeMode++; m_renderer->SetShadeMode(static_cast<Renderer::ShadeMode>(shadeMode)); } // 切换当前物体 if (m_inputCapturer->IsKeyPressed(KC_C)) { m_sceneObjectList[m_activeObjectIndex]->Hide(true); if (m_activeObjectIndex < m_sceneObjectList.size() - 1) { m_activeObjectIndex++; } else { m_activeObjectIndex = 0; } m_sceneObjectList[m_activeObjectIndex]->Hide(false); } SceneObject* object = m_sceneObjectList[m_activeObjectIndex]; // 控制物体旋转 // --begin-- float rotationX = 0.0f; float rotationY = 0.0f; float rotationAmount = 90.0f * dt; if (m_inputCapturer->IsKeyDown(KC_UP_ARROW) && !m_inputCapturer->IsKeyDown(KC_DOWN_ARROW)) { rotationX = rotationAmount; } else if (!m_inputCapturer->IsKeyDown(KC_UP_ARROW) && m_inputCapturer->IsKeyDown(KC_DOWN_ARROW)) { rotationX = -rotationAmount; } if (m_inputCapturer->IsKeyDown(KC_LEFT_ARROW) && !m_inputCapturer->IsKeyDown(KC_RIGHT_ARROW)) { rotationY = rotationAmount; } else if (!m_inputCapturer->IsKeyDown(KC_LEFT_ARROW) && m_inputCapturer->IsKeyDown(KC_RIGHT_ARROW)) { rotationY = -rotationAmount; } if (rotationX != 0.0f || rotationY != 0.0f) { object->LocalRotate(rotationX, rotationY, 0.0f); } // 控制物体旋转 // --end-- // 控制摄像机移动 // --begin-- float offsetX = 0.0f; float offsetY = 0.0f; float offsetZ = 0.0f; float offsetAmount = 10.0f * dt; if (m_inputCapturer->IsKeyDown(KC_A) && !m_inputCapturer->IsKeyDown(KC_D)) { offsetX = -offsetAmount; } else if (!m_inputCapturer->IsKeyDown(KC_A) && m_inputCapturer->IsKeyDown(KC_D)) { offsetX = offsetAmount; } if (m_inputCapturer->IsKeyDown(KC_Q) && !m_inputCapturer->IsKeyDown(KC_E)) { offsetY = -offsetAmount; } else if (!m_inputCapturer->IsKeyDown(KC_Q) && m_inputCapturer->IsKeyDown(KC_E)) { offsetY = offsetAmount; } if (m_inputCapturer->IsKeyDown(KC_W) && !m_inputCapturer->IsKeyDown(KC_S)) { offsetZ = offsetAmount; } else if (!m_inputCapturer->IsKeyDown(KC_W) && m_inputCapturer->IsKeyDown(KC_S)) { offsetZ = -offsetAmount; } if (offsetX != 0.0f || offsetY != 0.0f || offsetZ != 0.0f) { m_activeCamera->LocalMove(offsetX, offsetY, offsetZ); } // 控制摄像机移动 // --end-- // 控制摄像机旋转 // --begin-- if (m_inputCapturer->IsLeftBtnDown()) { int dx, dy; m_inputCapturer->GetMouseMovement(dx, dy); if (dx != 0 || dy != 0) { m_activeCamera->LocalRotate(dy * 0.5f, dx * 0.5f); } } // 控制摄像机旋转 // --end-- // 重置场景 if (m_inputCapturer->IsKeyPressed(KC_R)) { object->ResetRotation(); m_activeCamera->Reset(); } m_inputCapturer->ClearMouseMovement(); }
void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone ) { AssertFatal( this == gClientSceneGraph, "SceneManager::_buildSceneGraph - Only the client scenegraph can support this call!" ); PROFILE_SCOPE( SceneGraph_batchRenderImages ); // In the editor, override the type mask for diffuse passes. if( gEditingMission && state->isDiffusePass() ) objectMask = EDITOR_RENDER_TYPEMASK; // Update the zoning state and traverse zones. if( getZoneManager() ) { // Update. getZoneManager()->updateZoningState(); // If zone culling isn't disabled, traverse the // zones now. if( !state->getCullingState().disableZoneCulling() ) { // Find the start zone if we haven't already. if( !baseObject ) { getZoneManager()->findZone( state->getCameraPosition(), baseObject, baseZone ); AssertFatal( baseObject != NULL, "SceneManager::_renderScene - findZone() did not return an object" ); } // Traverse zones starting in base object. SceneTraversalState traversalState( &state->getCullingState() ); PROFILE_START( Scene_traverseZones ); baseObject->traverseZones( &traversalState, baseZone ); PROFILE_END(); // Set the scene render box to the area we have traversed. state->setRenderArea( traversalState.getTraversedArea() ); } } // Set the query box for the container query. Never // make it larger than the frustum's AABB. In the editor, // always query the full frustum as that gives objects // the opportunity to render editor visualizations even if // they are otherwise not in view. if( !state->getFrustum().getBounds().isOverlapped( state->getRenderArea() ) ) { // This handles fringe cases like flying backwards into a zone where you // end up pretty much standing on a zone border and looking directly into // its "walls". In that case the traversal area will be behind the frustum // (remember that the camera isn't where visibility starts, it's the near // distance). return; } Box3F queryBox = state->getFrustum().getBounds(); if( !gEditingMission ) { queryBox.minExtents.setMax( state->getRenderArea().minExtents ); queryBox.maxExtents.setMin( state->getRenderArea().maxExtents ); } PROFILE_START( Scene_cullObjects ); //TODO: We should split the codepaths here based on whether the outdoor zone has visible space. // If it has, we should use the container query-based path. // If it hasn't, we should fill the object list directly from the zone lists which will usually // include way fewer objects. // Gather all objects that intersect the scene render box. mBatchQueryList.clear(); getContainer()->findObjectList( queryBox, objectMask, &mBatchQueryList ); // Cull the list. U32 numRenderObjects = state->getCullingState().cullObjects( mBatchQueryList.address(), mBatchQueryList.size(), !state->isDiffusePass() ? SceneCullingState::CullEditorOverrides : 0 // Keep forced editor stuff out of non-diffuse passes. ); //HACK: If the control object is a Player and it is not in the render list, force // it into it. This really should be solved by collision bounds being separate from // object bounds; only because the Player class is using bounds not encompassing // the actual player object is it that we have this problem in the first place. // Note that we are forcing the player object into ALL passes here but such // is the power of proliferation of things done wrong. GameConnection* connection = GameConnection::getConnectionToServer(); if( connection ) { Player* player = dynamic_cast< Player* >( connection->getControlObject() ); if( player ) { mBatchQueryList.setSize( numRenderObjects ); if( !mBatchQueryList.contains( player ) ) { mBatchQueryList.push_back( player ); numRenderObjects ++; } } } PROFILE_END(); // Render the remaining objects. PROFILE_START( Scene_renderObjects ); state->renderObjects( mBatchQueryList.address(), numRenderObjects ); PROFILE_END(); // Render bounding boxes, if enabled. if( smRenderBoundingBoxes && state->isDiffusePass() ) { GFXDEBUGEVENT_SCOPE( Scene_renderBoundingBoxes, ColorI::WHITE ); GameBase* cameraObject = 0; if( connection ) cameraObject = connection->getCameraObject(); GFXStateBlockDesc desc; desc.setFillModeWireframe(); desc.setZReadWrite( true, false ); for( U32 i = 0; i < numRenderObjects; ++ i ) { SceneObject* object = mBatchQueryList[ i ]; // Skip global bounds object. if( object->isGlobalBounds() ) continue; // Skip camera object as we're viewing the scene from it. if( object == cameraObject ) continue; const Box3F& worldBox = object->getWorldBox(); GFX->getDrawUtil()->drawObjectBox( desc, Point3F( worldBox.len_x(), worldBox.len_y(), worldBox.len_z() ), worldBox.getCenter(), MatrixF::Identity, ColorI::WHITE ); } } }
void Application::Render( void ) { if (!m_initialized) { return; } for (unsigned i = 0; i < m_sceneObjectList.size(); i++) { SceneObject* object = m_sceneObjectList[i]; Material* material = object->GetMaterial(); if (object->IsHidden()) { continue; } RenderUnit* renderUnit = new RenderUnit(); renderUnit->m_vb = object->GetMesh()->GetVertexBuffer(); renderUnit->m_ib = object->GetMesh()->GetIndexBuffer(); renderUnit->m_wireFrame = material->wireFrame; int vertexShaderId = m_renderer->GetShadeMode() == Renderer::SHADING_MODE_PHONG ? material->vertexShaderId : (material->vertexShaderId == VS_TANGENT_SPACE_LIGHTING_SC2_UV ? VS_FIXED_FUNCTION_ALT_UV : VS_FIXED_FUNCTION); int pixelShaderId = m_renderer->GetShadeMode() == Renderer::SHADING_MODE_PHONG ? material->pixelShaderId : PS_FIXED_FUNCTION; switch (vertexShaderId) { case VS_FIXED_FUNCTION: { VsFixedFunction* myVS = new VsFixedFunction(); renderUnit->m_vs = myVS; Matrix4 worldMatrix; object->GetWorldMatrix(worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; myVS->ambientColor = m_activeLight->ambientColor; myVS->diffuseColor = m_activeLight->diffuseColor; } break; case VS_FIXED_FUNCTION_ALT_UV: { VsFixedFunctionAltUv* myVS = new VsFixedFunctionAltUv(); renderUnit->m_vs = myVS; Matrix4 worldMatrix; object->GetWorldMatrix(worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; myVS->ambientColor = m_activeLight->ambientColor; myVS->diffuseColor = m_activeLight->diffuseColor; } break; case VS_TANGENT_SPACE_LIGHTING: { VsTangentSpaceLighting* myVS = new VsTangentSpaceLighting(); renderUnit->m_vs = myVS; object->GetWorldMatrix(myVS->worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, myVS->worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; } break; case VS_TANGENT_SPACE_LIGHTING_SC2_UV: { VsTangentSpaceLightingSc2Uv* myVS = new VsTangentSpaceLightingSc2Uv(); renderUnit->m_vs = myVS; object->GetWorldMatrix(myVS->worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, myVS->worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; } break; default: break; } switch (pixelShaderId) { case PS_FIXED_FUNCTION: { PsFixedFunction* myPS = new PsFixedFunction(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); } break; case PS_NORMAL_MAP: { PsNormalMap* myPS = new PsNormalMap(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); myPS->normalTexture = m_textureManager->GetTexture(material->bumpTextureId); myPS->diffuseColor = m_activeLight->diffuseColor; myPS->ambientColor = m_activeLight->ambientColor; } break; case PS_TOON_LIGHTING: { PsToonLighting* myPS = new PsToonLighting(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); myPS->diffuseColor = m_activeLight->diffuseColor; myPS->ambientColor = m_activeLight->ambientColor; } break; default: break; } m_renderer->AddRenderUnit(renderUnit); } m_backBuffer->Clear(); m_depthBuffer->Clear(); m_renderer->SetRenderTarget(m_backBuffer, m_depthBuffer); m_renderer->Render(); m_backBuffer->Present(); }
U32 SceneCullingState::cullObjects( SceneObject** objects, U32 numObjects, U32 cullOptions ) const { PROFILE_SCOPE( SceneCullingState_cullObjects ); U32 numRemainingObjects = 0; // We test near and far planes separately in order to not do the tests // repeatedly, so fetch the planes now. const PlaneF& nearPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneNear ]; const PlaneF& farPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneFar ]; for( U32 i = 0; i < numObjects; ++ i ) { SceneObject* object = objects[ i ]; bool isCulled = true; // If we should respect editor overrides, test that now. if( !( cullOptions & CullEditorOverrides ) && gEditingMission && ( ( object->isCullingDisabledInEditor() && object->isRenderEnabled() ) || object->isSelected() ) ) { isCulled = false; } // If the object is render-disabled, it gets culled. The only // way around this is the editor override above. else if( !( cullOptions & DontCullRenderDisabled ) && !object->isRenderEnabled() ) { isCulled = true; } // Global bounds objects are never culled. Note that this means // that if these objects are to respect zoning, they need to manually // trigger the respective culling checks for whatever they want to // batch. else if( object->isGlobalBounds() ) isCulled = false; // If terrain occlusion checks are enabled, run them now. else if( !mDisableTerrainOcclusion && object->getWorldBox().minExtents.x > -1e5 && isOccludedByTerrain( object ) ) { // Occluded by terrain. isCulled = true; } // If the object shouldn't be subjected to more fine-grained culling // or if zone culling is disabled, just test against the root frustum. else if( !( object->getTypeMask() & CULLING_INCLUDE_TYPEMASK ) || ( object->getTypeMask() & CULLING_EXCLUDE_TYPEMASK ) || disableZoneCulling() ) { isCulled = getCullingFrustum().isCulled( object->getWorldBox() ); } // Go through the zones that the object is assigned to and // test the object against the frustums of each of the zones. else { CullingTestResult result = _test( object->getWorldBox(), SceneObject::ObjectZonesIterator( object ), nearPlane, farPlane ); isCulled = ( result == SceneZoneCullingState::CullingTestNegative || result == SceneZoneCullingState::CullingTestPositiveByOcclusion ); } if( !isCulled ) isCulled = isOccludedWithExtraPlanesCull( object->getWorldBox() ); if( !isCulled ) objects[ numRemainingObjects ++ ] = object; } return numRemainingObjects; }
void Weapon::Use( int function, Real Param1, Real Param2, Real Param3, Real FrameTime) { //Reload the weapon if it's not already //in the proccess of reloading if( function == WF_RELOAD ) { if(State != WS_RELOADING) { MeshA.Change( "reloading", .06f ); MeshB.Change( "reloading", .06f ); State = WS_RELOADING; TimeLeft = ReloadTime; //AMPtr->Play( ReloadSound ); DeviceManager::OpenALSound.PlaySoundImmediate( SndReload, Location.AsSoundSource() ); } } //Fire the weapon, if it's not already discharging a bullet //or reloading. if( function == WF_FIRE1 ) { if(State != WS_FIRING && State != WS_RELOADING && (Ammo > 0 || ClipAmmo > 0) ) { //Set it to the "firing" state and play the sound State = WS_FIRING; TimeLeft = RateOfFire; //AMPtr->Play( FiringSound ); DeviceManager::OpenALSound.PlaySoundImmediate( SndFiring, Location.AsSoundSource() ); if(!OddShot || !DualWeapons) MeshA.Change( "shooting", .020f ); else MeshB.Change( "shooting", .020f ); if(DualWeapons) { if(OddShot) OddShot = false; else OddShot = true; } //Spawn some hud smoke and create the particle //which represents the bullet. if(!InstantBullets ) { Smoke.SpawnParticles(10, false); Bullets.SpawnParticles(1, false); } else { //do something here Vector3D arrow = Bullets.StreamHeading; arrow.SetLength( 2000 ); MuzzleFlashFade = 1.0f; Vector3D hitPoint; Vector3D hitNormal; SceneObject* objectHit; Vector3D a = Location.GetVector(); Vector3D b = Location.GetVector() + arrow; bool c = WMPtr->CheckBulletCollision( a, b, &hitPoint, &hitNormal, &objectHit, &WMPtr->LocalPlayer ); if( c ) { if(objectHit ) { arrow.SetLength( DamageOnHit ); objectHit->Damage( a, arrow, hitPoint ); } else { Explosives.MoveSpawn( hitPoint.x, hitPoint.y, hitPoint.z ); Explosives.SpawnParticles( 15, false ); } } } //Decrease the ammount of ammo in the clip, then //reload if we're out of ammo ClipAmmo --; if(ClipAmmo < 1 && Ammo > 0) { ClipAmmo = 0; Use(WF_RELOAD, NULL, NULL, NULL, FrameTime); } } } }
void GlCanvas::OnKeyDown(wxKeyEvent & event) { static bool physics = true; _setCamera(); if (0 == m_pCamera) { return; } vec4 camPosition = m_pCamera->getPropfv(Camera::POSITION); vec4 camUp = m_pCamera->getPropfv(Camera::NORMALIZED_UP_VEC); vec4 camView = m_pCamera->getPropfv(Camera::NORMALIZED_VIEW_VEC); // vec3& camLookAt = m_pCamera->getLookAtPoint(); if ('K' == event.GetKeyCode()) { m_pEngine->sendKeyToEngine (event.GetKeyCode()); } if ('M' == event.GetKeyCode()) { EVENTMANAGER->notifyEvent("NEXT_POSE", "MainCanvas", "", NULL); } if ('9' >= event.GetKeyCode() && '0' <= event.GetKeyCode()) { //m_pEngine->sendKeyToEngine (event.GetKeyCode()); Camera *aCam = RENDERMANAGER->getCamera ("MainCamera"); vec3 v; switch (event.GetKeyCode()) { case '1': v.set (-14.486f * cos (DegToRad (-137.0)) - 59.256 * -sin (DegToRad (-137.0)), 13.266f, -59.256 * cos (DegToRad(-137.0)) + -14.486f * sin (DegToRad (-137.0))); aCam->setCamera (vec3 (-14.486f, 13.266f, -59.256f), v, vec3 (0.0f, 1.0f, 0.0f)); break; case '2': v.set (0.0f, 0.0f, -1.0f * cos (DegToRad (-141.4f))); aCam->setCamera (vec3 (7.930f, 16.135f, -38.392f), v, vec3 (0.0f, 1.0f, 0.0f)); break; case '3': v.set (0.0f, 0.0f, -1.0f * cos (DegToRad (-81.8f))); aCam->setCamera (vec3 (7.374f, 14.465f, -58.637f), v, vec3 (0.0f, 1.0f, 0.0f)); break; case '4': v.set (0.0f, 0.0f, -1.0f * cos (DegToRad (-17.0f))); aCam->setCamera (vec3 (13.363f, 13.977f, -47.436f), v, vec3 (0.0f, 1.0f, 0.0f)); break; case '5': v.set (0.0f, 0.0f, -1.0f * cos (DegToRad (135.58f))); aCam->setCamera (vec3 (-131.176f, 9.555f, 188.927f), v, vec3 (0.0f, 1.0f, 0.0f)); break; } } if ('B' == event.GetKeyCode()) { m_pEngine->sendKeyToEngine (event.GetKeyCode()); } if ('P' == event.GetKeyCode()) { m_pEngine->sendKeyToEngine (event.GetKeyCode()); } float direction; if (true == m_pCamera->isDynamic()) { direction = VELOCITY; } else { direction = NON_DYNAMIC_VELOCITY; } if (true == event.ShiftDown()) { // SHIFT = fast motion direction *= 10.0f; } else if (true == event.ControlDown()) { // CTRL = very fast motion. note: shift has precedence over control! direction *= 100.0f; } if ('S' == event.GetKeyCode()) { if (true == m_pCamera->isDynamic()) { vec4 vel (camView); //vel *= 2.0f; //vel -= m_OldCamView; //m_OldCamView.set (vel.x, vel.y, vel.z); vel.y = 0.0f; vel.normalize(); vel *= -direction; vec3 v3; v3.set(vel.x,vel.y,vel.z); m_pEngine->getWorld().setVelocity ("testCamera", v3); } else { curitiba::event_::CameraMotion c("BACKWARD", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if ('W' == event.GetKeyCode()) { if (true == m_pCamera->isDynamic()) { vec4 vel (camView); //vel *= 2.0f; //vel -= m_OldCamView; //m_OldCamView.set (camView.x, camView.y, camView.z); vel.y = 0.0f; vel.normalize(); vel *= direction; vec3 v3; v3.set(vel.x,vel.y,vel.z); m_pEngine->getWorld().setVelocity ("testCamera", v3); } else { curitiba::event_::CameraMotion c("FORWARD", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if ('A' == event.GetKeyCode()){ if (true == m_pCamera->isDynamic()) { vec4 vel (camView.cross (camUp)); vel *= -direction; vel.y = 0.0f; vec3 v3; v3.set(vel.x,vel.y,vel.z); m_pEngine->getWorld().setVelocity ("testCamera", v3); } else { curitiba::event_::CameraMotion c("LEFT", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if ('D' == event.GetKeyCode()){ if (true == m_pCamera->isDynamic()) { vec4 vel (camView.cross (camUp)); vel *= direction; vel.y = 0.0f; vec3 v3; v3.set(vel.x,vel.y,vel.z); m_pEngine->getWorld().setVelocity ("testCamera", v3); } else { curitiba::event_::CameraMotion c("RIGHT", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if ('Q' == event.GetKeyCode()){ if (false == m_pCamera->isDynamic()) { curitiba::event_::CameraMotion c("UP", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if ('Z' == event.GetKeyCode()){ if (false == m_pCamera->isDynamic()) { curitiba::event_::CameraMotion c("DOWN", direction); curitiba::event_::IEventData *e= curitiba::event_::EventFactory::create("Camera Motion"); e->setData(&c); EVENTMANAGER->notifyEvent("CAMERA_MOTION", "MainCanvas", "", e); delete e; } DlgCameras::Instance()->updateInfo(m_pCamera->getName()); } if (m_pCamera->isDynamic()){ EVENTMANAGER->notifyEvent("DYNAMIC_CAMERA", "MainCanvas", "", NULL); } /* if (WXK_SPACE == event.GetKeyCode()) { if (true == m_pCamera->m_IsDynamic) { vec3 vel (camUp); vel *= direction * 3; vel.x = 0.0f; vel.z = 0.0f; m_pEngine->getWorld().setVelocity ("MainCamera", vel); m_WaterState = changeWaterState (m_WaterState); } } */ /* if ('N' == event.GetKeyCode()){ m_pCamera->setNearPlane (m_pCamera->getNearPlane() + 0.5f); } if ('M' == event.GetKeyCode()){ m_pCamera->setNearPlane (m_pCamera->getNearPlane() - 0.5f); } if ('F' == event.GetKeyCode()){ m_pCamera->setFarPlane (m_pCamera->getFarPlane() + 1.0f); } if ('G' == event.GetKeyCode()){ m_pCamera->setFarPlane (m_pCamera->getFarPlane() - 1.0f); } */ if ('+' == event.GetKeyCode() || WXK_NUMPAD_ADD == event.GetKeyCode()) { SceneObject *aObject = RENDERMANAGER->getScene ("MainScene")->getSceneObject ("pPlane1"); aObject->_getTransformPtr()->translate (0.0f, 0.5f, 0.0f); } if ('-' == event.GetKeyCode() || WXK_NUMPAD_SUBTRACT == event.GetKeyCode()) { SceneObject *aObject = RENDERMANAGER->getScene ("MainScene")->getSceneObject ("pPlane1"); aObject->_getTransformPtr()->translate (0.0f, -0.5f, 0.0f); } curitiba::scene::Camera *cam = RENDERMANAGER->getCamera ("testCamera"); if ('L' == event.GetKeyCode()){ if (false == physics) { m_pEngine->enablePhysics(); cam->setDynamic(true); } else { m_pEngine->disablePhysics(); cam->setDynamic(false); } physics = !physics; } //if ('Y' == event.GetKeyCode()){ // // m_Stereo = !m_Stereo; // if (true == m_Stereo) { // m_pEngine->enableStereo(); // } else { // m_pEngine->disableStereo(); // } //} #if (CURITIBA_OPENGL_VERSIONOPENGL_VERSION >= 400) if ('C' == event.GetKeyCode()) { for (unsigned int i = 0; i < IRenderer::MAX_COUNTERS; i++) SLOG("%d", RENDERER->getCounter(i)); } #endif event.Skip(); }
void Scene::Attach (SceneObject& object) { object.BindToSpace (impl); }
bool SceneObject::_setSelectionEnabled( void *object, const char *index, const char *data ) { SceneObject* obj = reinterpret_cast< SceneObject* >( object ); obj->setSelectionEnabled( dAtob( data ) ); return false; }
int CampKitMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* player, byte selectedID) const { if (!sceneObject->isTangibleObject()) return 0; TangibleObject* tano = cast<TangibleObject*>(sceneObject); if (tano == NULL || !player->isPlayerCreature()) return 0; if (player->getZone() == NULL) return 0; if (!sceneObject->isASubChildOf(player)) return 0; if (selectedID == 20) { /// Get Camp Kit Template CampKitTemplate* campKitData = cast<CampKitTemplate*> (sceneObject->getObjectTemplate()); if (campKitData == NULL) { error("No CampKitTemplate for: " + String::valueOf(sceneObject->getServerObjectCRC())); return 0; } /// Get Camp Template SharedObjectTemplate* templateData = TemplateManager::instance()->getTemplate(campKitData->getSpawnObjectTemplate().hashCode()); CampStructureTemplate* campStructureData = cast<CampStructureTemplate*> (templateData); if (campStructureData == NULL) { error("No CampStructureTemplate for: " + campKitData->getSpawnObjectTemplate()); return 0; } ManagedReference<ZoneServer*> zoneServer = player->getZoneServer(); if (zoneServer == NULL) { error("ZoneServer is null when trying to create camp"); return 0; } ManagedReference<Zone*> zone = player->getZone(); if (zone == NULL) { error("Zone is null when trying to create camp"); return 0; } ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager(); if (planetManager == NULL) { error("Unable to get PlanetManager when placing camp"); return 0; } /// Get Ghost Reference<PlayerObject*> ghost = player->getSlottedObject("ghost").castTo<PlayerObject*>(); if (ghost == NULL) { error("PlayerCreature has no ghost: " + String::valueOf(player->getObjectID())); return 0; } int playerSkill = player->getSkillMod("camp"); if(playerSkill < campStructureData->getSkillRequired()) { player->sendSystemMessage("@camp:sys_nsf_skill"); return 0; } if(player->isInCombat()) { player->sendSystemMessage("@camp:sys_not_in_combat"); return 0; } if(player->getParent() != NULL && player->getParent().get()->isCellObject()) { player->sendSystemMessage("@camp:error_inside"); return 0; } if(!sceneObject->isASubChildOf(player)) { player->sendSystemMessage("@camp:sys_not_in_inventory"); return 0; } if(!player->isStanding() || player->isRidingMount()) { player->sendSystemMessage("@camp:error_cmd_fail"); return 0; } ManagedReference<CityRegion*> region = player->getCityRegion().get(); if(region != NULL) { player->sendSystemMessage("@camp:error_muni_true"); return 0; } /// Check for water if(player->isSwimming() || player->isInWater()) { player->sendSystemMessage("@camp:error_in_water"); return 0; } /// Make sure player doesn't already have a camp setup somewhere else for (int i = 0; i < ghost->getTotalOwnedStructureCount(); ++i) { uint64 oid = ghost->getOwnedStructure(i); ManagedReference<StructureObject*> structure = ghost->getZoneServer()->getObject(oid).castTo<StructureObject*>(); if (structure != NULL && structure->isCampStructure()) { player->sendSystemMessage("@camp:sys_already_camping"); return 0; } } /// Check if player is in another camp if(player->getCurrentCamp() != NULL) { player->sendSystemMessage("@camp:error_camp_exists"); return 0; } /// Check if player is elevated, on a building or porch /// Check camps/lairs nearby SortedVector<ManagedReference<QuadTreeEntry* > > nearbyObjects; zone->getInRangeObjects(player->getPositionX(), player->getPositionY(), 512, &nearbyObjects, true, false); for(int i = 0; i < nearbyObjects.size(); ++i) { SceneObject* scno = cast<SceneObject*>(nearbyObjects.get(i).get()); if (scno != NULL && scno->isCampStructure() && scno->getDistanceTo( player) <= scno->getObjectTemplate()->getNoBuildRadius() + campStructureData->getRadius()) { player->sendSystemMessage("@camp:error_camp_too_close"); return 0; } if (scno != NULL && !scno->isCampStructure() && scno->isStructureObject() && scno->getDistanceTo(player) <= 100) { player->sendSystemMessage("@camp:error_building_too_close"); return 0; } if(scno != NULL && scno->getDistanceTo(player) <= scno->getObjectTemplate()->getNoBuildRadius() + campStructureData->getRadius()) { if (scno->getObserverCount(ObserverEventType::OBJECTDESTRUCTION) > 0) { SortedVector<ManagedReference<Observer* > > observers = scno->getObservers(ObserverEventType::OBJECTDESTRUCTION); for(int j = 0; j < observers.size(); ++j) { if(observers.get(j)->isObserverType(ObserverType::LAIR)) { player->sendSystemMessage("@camp:error_lair_too_close"); return 0; } } } if (scno->getObserverCount(ObserverEventType::CREATUREDESPAWNED) > 0) { SortedVector<ManagedReference<Observer* > > observers2 = scno->getObservers(ObserverEventType::CREATUREDESPAWNED); for(int j = 0; j < observers2.size(); ++j) { if(observers2.get(j)->isObserverType(ObserverType::LAIR)) { player->sendSystemMessage("@camp:error_lair_too_close"); return 0; } } } } } /// Check to see if you can camp here (Allows building in city no-build zone but not within city limits which are checked above) if (!planetManager->isCampingPermittedAt(player->getPositionX(), player->getPositionY(), campStructureData->getRadius())) { player->sendSystemMessage("@camp:error_nobuild"); return 0; } player->sendSystemMessage("@camp:starting_camp"); /// Create Structure StructureObject* structureObject = StructureManager::instance()->placeStructure( player, campKitData->getSpawnObjectTemplate(), player->getPositionX(), player->getPositionY(), (int) player->getDirectionAngle()); if (structureObject == NULL) { error("Unable to create camp: " + campKitData->getSpawnObjectTemplate()); return 1; } /// Identify terminal for Active area Terminal* campTerminal = NULL; SortedVector < ManagedReference<SceneObject*> > *childObjects = structureObject->getChildObjects(); for (int i = 0; i < childObjects->size(); ++i) { if (childObjects->get(i)->isTerminal()) { campTerminal = cast<Terminal*> (childObjects->get(i).get()); break; } } if (campTerminal == NULL) { structureObject->destroyObjectFromDatabase(true); error("Camp does not have terminal: " + campStructureData->getTemplateFileName()); return 1; } String campName = player->getFirstName(); if(!player->getLastName().isEmpty()) campName += " " + player->getLastName(); campName += "'s Camp"; campTerminal->setCustomObjectName(campName, true); /// Create active area String areaPath = "object/camp_area.iff"; ManagedReference<CampSiteActiveArea*> campArea = (zoneServer->createObject( areaPath.hashCode(), 1)).castTo< CampSiteActiveArea*>(); if (campArea == NULL) { structureObject->destroyObjectFromDatabase(true); return 1; } Locker areaLocker(campArea, player); campArea->init(campStructureData); campArea->setTerminal(campTerminal); campArea->setCamp(structureObject); campArea->setOwner(player); campArea->setNoBuildArea(true); campArea->initializePosition(player->getPositionX(), 0, player->getPositionY()); if (!zone->transferObject(campArea, -1, false)) { structureObject->destroyObjectFromDatabase(true); campArea->destroyObjectFromDatabase(true); return 1; } campArea->setAbandoned(false); structureObject->addActiveArea(campArea); player->sendSystemMessage("@camp:camp_complete"); /// Remove Camp TangibleObject* tano = cast<TangibleObject*>(sceneObject); if(tano != NULL) tano->decreaseUseCount(); return 0; } else return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject, player, selectedID); return 0; }
void HandleCollisions() { SceneObject* checkObj; gmtl::Vec3f collisionNormal, normalRelativeVelocity; int cIndex; for (std::vector<SceneObject*>::iterator it = sceneGraph.begin(); it < sceneGraph.end(); ++it) { checkObj = (*it); for (std::vector<SceneObject*>::iterator innerIt = sceneGraph.begin(); innerIt < sceneGraph.end(); ++innerIt) { if (checkObj != (*innerIt) && !IsWall(checkObj)) { cIndex = AlreadyCollided(checkObj, (*innerIt)); if (IsCollided(checkObj, (*innerIt))) { collsionList.push_back(Collision(checkObj, (*innerIt))); collisionNormal = checkObj->GetPosition() - (*innerIt)->GetPosition(); collisionNormal = gmtl::makeNormal(collisionNormal); collisionNormal[1] = 0.0f; cout << gmtl::dot((checkObj->velocity - (*innerIt)->velocity), collisionNormal) << endl; if (gmtl::dot((checkObj->velocity - (*innerIt)->velocity), collisionNormal) <= 1.0f) { switch ((*innerIt)->type) { case FRONT_WALL: case BACK_WALL: checkObj->velocity = restitutionWall * gmtl::Vec3f(checkObj->velocity[0], checkObj->velocity[1], -checkObj->velocity[2]); break; case LEFT_WALL: case RIGHT_WALL: checkObj->velocity = restitutionWall * gmtl::Vec3f(-checkObj->velocity[0], checkObj->velocity[1], checkObj->velocity[2]); break; case LEG: normalRelativeVelocity = gmtl::dot((checkObj->velocity - (*innerIt)->velocity), collisionNormal)*collisionNormal; checkObj->velocity = (checkObj->velocity - ((1 + restitutionBall)*normalRelativeVelocity)) / (1 + (checkObj->mass / (*innerIt)->mass)); if (bounce) { checkObj->velocity *= -1.2f; } (*innerIt)->velocity = ((*innerIt)->velocity + ((1 + restitutionBall)*normalRelativeVelocity)) / (1 + ((*innerIt)->mass / checkObj->mass)); break; case BALL: normalRelativeVelocity = gmtl::dot((checkObj->velocity - (*innerIt)->velocity), collisionNormal)*collisionNormal; checkObj->velocity = (checkObj->velocity - ((1 + restitutionBall)*normalRelativeVelocity)) / (1 + (checkObj->mass / (*innerIt)->mass)); (*innerIt)->velocity = ((*innerIt)->velocity + ((1 + restitutionBall)*normalRelativeVelocity)) / (1 + ((*innerIt)->mass / checkObj->mass)); break; } } } else if (!IsCollided(checkObj, (*innerIt)) && cIndex > -1) { collsionList.erase(collsionList.begin()+cIndex); } } } } }
void WorldEditorSelection::rotate(const EulerF & rot, const Point3F & center) { // single selections will rotate around own axis, multiple about world if(size() == 1) { SceneObject* object = dynamic_cast< SceneObject* >( at( 0 ) ); if( object ) { MatrixF mat = object->getTransform(); Point3F pos; mat.getColumn(3, &pos); // get offset in obj space Point3F offset = pos - center; MatrixF wMat = object->getWorldTransform(); wMat.mulV(offset); // MatrixF transform(EulerF(0,0,0), -offset); transform.mul(MatrixF(rot)); transform.mul(MatrixF(EulerF(0,0,0), offset)); mat.mul(transform); object->setTransform(mat); } } else { for( iterator iter = begin(); iter != end(); ++ iter ) { SceneObject* object = dynamic_cast< SceneObject* >( *iter ); if( !object ) continue; MatrixF mat = object->getTransform(); Point3F pos; mat.getColumn(3, &pos); // get offset in obj space Point3F offset = pos - center; MatrixF transform(rot); Point3F wOffset; transform.mulV(offset, &wOffset); MatrixF wMat = object->getWorldTransform(); wMat.mulV(offset); // transform.set(EulerF(0,0,0), -offset); mat.setColumn(3, Point3F(0,0,0)); wMat.setColumn(3, Point3F(0,0,0)); transform.mul(wMat); transform.mul(MatrixF(rot)); transform.mul(mat); mat.mul(transform); mat.normalize(); mat.setColumn(3, wOffset + center); object->setTransform(mat); } } mCentroidValid = false; }
static void processGeometry( string name, Obj *child, Scene *scene, const mmap& materials, TransformNode *transform ) { if( name == "translate" ) { const mytuple& tup = child->getTuple(); verifyTuple( tup, 4 ); processGeometry( tup[3], scene, materials, transform->createChild(mat4f::translate( vec3f(tup[0]->getScalar(), tup[1]->getScalar(), tup[2]->getScalar() ) ) ) ); } else if( name == "rotate" ) { const mytuple& tup = child->getTuple(); verifyTuple( tup, 5 ); processGeometry( tup[4], scene, materials, transform->createChild(mat4f::rotate( vec3f(tup[0]->getScalar(), tup[1]->getScalar(), tup[2]->getScalar() ), tup[3]->getScalar() ) ) ); } else if( name == "scale" ) { const mytuple& tup = child->getTuple(); if( tup.size() == 2 ) { double sc = tup[0]->getScalar(); processGeometry( tup[1], scene, materials, transform->createChild(mat4f::scale( vec3f( sc, sc, sc ) ) ) ); } else { verifyTuple( tup, 4 ); processGeometry( tup[3], scene, materials, transform->createChild(mat4f::scale( vec3f(tup[0]->getScalar(), tup[1]->getScalar(), tup[2]->getScalar() ) ) ) ); } } else if( name == "transform" ) { const mytuple& tup = child->getTuple(); verifyTuple( tup, 5 ); const mytuple& l1 = tup[0]->getTuple(); const mytuple& l2 = tup[1]->getTuple(); const mytuple& l3 = tup[2]->getTuple(); const mytuple& l4 = tup[3]->getTuple(); verifyTuple( l1, 4 ); verifyTuple( l2, 4 ); verifyTuple( l3, 4 ); verifyTuple( l4, 4 ); processGeometry( tup[4], scene, materials, transform->createChild(mat4f(vec4f( l1[0]->getScalar(), l1[1]->getScalar(), l1[2]->getScalar(), l1[3]->getScalar() ), vec4f( l2[0]->getScalar(), l2[1]->getScalar(), l2[2]->getScalar(), l2[3]->getScalar() ), vec4f( l3[0]->getScalar(), l3[1]->getScalar(), l3[2]->getScalar(), l3[3]->getScalar() ), vec4f( l4[0]->getScalar(), l4[1]->getScalar(), l4[2]->getScalar(), l4[3]->getScalar() ) ) ) ); } else if( name == "trimesh" || name == "polymesh" ) { // 'polymesh' is for backwards compatibility processTrimesh( name, child, scene, materials, transform); } else { SceneObject *obj = NULL; Material *mat; //if( hasField( child, "material" ) ) mat = getMaterial(getField( child, "material" ), materials ); //else // mat = new Material(); if( name == "sphere" ) { obj = new Sphere( scene, mat ); } else if( name == "box" ) { obj = new Box( scene, mat ); } else if (name == "cylinder") { bool capped = true; maybeExtractField(child, "capped", capped); obj = new Cylinder(scene, mat, capped); } else if( name == "cone" ) { double height = 1.0; double bottom_radius = 1.0; double top_radius = 0.0; bool capped = true; maybeExtractField( child, "height", height ); maybeExtractField( child, "bottom_radius", bottom_radius ); maybeExtractField( child, "top_radius", top_radius ); maybeExtractField( child, "capped", capped ); obj = new Cone( scene, mat, height, bottom_radius, top_radius, capped ); } else if( name == "square" ) { obj = new Square( scene, mat ); } obj->setTransform(transform); scene->add(obj); } }
SceneObject* ObjectManager::cloneObject(SceneObject* object, bool makeTransient) { ObjectOutputStream objectData(500); (cast<ManagedObject*>(object))->writeObject(&objectData); objectData.reset(); ObjectInputStream objectInput; objectData.copy(&objectInput, 0); objectInput.reset(); uint32 serverCRC = object->getServerObjectCRC(); SceneObject* clonedObject = NULL; ObjectDatabase* database = getTable(object->getObjectID()); String databaseName; uint64 oid; if (database != NULL) { database->getDatabaseName(databaseName); oid = getNextObjectID(databaseName); } else oid = getNextFreeObjectID(); clonedObject = instantiateSceneObject(serverCRC, oid, false); if (makeTransient || !object->isPersistent()) { //clonedObject = createObject(serverCRC, 0, databaseName); clonedObject->setPersistent(0); } else if (object->isPersistent()) { //clonedObject = createObject(serverCRC, object->getPersistenceLevel(), databaseName); clonedObject->setPersistent(object->getPersistenceLevel()); } Locker locker(clonedObject); clonedObject->readObject(&objectInput); clonedObject->createComponents(); clonedObject->setParent(NULL); VectorMap<String, ManagedReference<SceneObject*> > slottedObjects; clonedObject->getSlottedObjects(slottedObjects); for (int i=slottedObjects.size()-1; i>=0; i--) { String key = slottedObjects.elementAt(i).getKey(); Reference<SceneObject*> obj = slottedObjects.elementAt(i).getValue(); clonedObject->removeSlottedObject(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); slottedObjects.put(key, clonedChild); } VectorMap<uint64, ManagedReference<SceneObject*> > objects; clonedObject->getContainerObjects(objects); for (int i=objects.size()-1; i>=0; i--) { uint64 key = objects.elementAt(i).getKey(); Reference<SceneObject*> obj = objects.elementAt(i).getValue(); objects.remove(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); objects.put(key, clonedChild); } clonedObject->onCloneObject(object); if (clonedObject->isPersistent()) updatePersistentObject(clonedObject); return clonedObject; }