Exemple #1
0
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;
}
Exemple #2
0
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);


}
Exemple #3
0
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);
			}
		}
	}
}
Exemple #5
0
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, &copyThreatMap);

		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);

			}
		}
	}

}
Exemple #16
0
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() );

				}
			}
		}
Exemple #18
0
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
         );
      }
   }
}
Exemple #20
0
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;
}
Exemple #22
0
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();
}
Exemple #24
0
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;
}
Exemple #27
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;
}
Exemple #29
0
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;
}