void gkScene::addObject(gkGameObject* gobj)
{
	GK_ASSERT(gobj);

	const gkHashedString name = gobj->getName();

	if (m_objects.find(name) != GK_NPOS)
	{
		gkPrintf("Scene: Duplicate object '%s' found in this scene\n", name.str().c_str());
		return;
	}


	if (gobj->getType() == GK_LIGHT)
		m_hasLights = true;


	if (gobj->getOwner() != this)
	{
		if (gobj->getOwner() != 0)
		{
			if (!_replaceObjectInScene(gobj, gobj->getOwner(), this))
				return;
		}
		else
		{
			gobj->setOwner(this);
			m_objects.insert(name, gobj);
		}
	}

}
void gkScene::removeObject(gkGameObject* gobj)
{
	const gkHashedString name = gobj->getName();
	if (m_objects.find(name) != GK_NPOS)
	{
		gkPrintf("Scene: object '%s' not found in this scene\n", name.str().c_str());
		return;
	}

	gobj->destroyInstance();
}
void gkScene::destroyObject(gkGameObject* gobj)
{
	const gkHashedString name = gobj->getName();
	if (gobj->getOwner() != this)
	{
		gkPrintf("Scene: object '%s' not found in this scene\n", name.str().c_str());
		return;
	}


	gobj->destroyInstance();
	m_objects.remove(name);
	gkGameObjectManager::getSingleton().destroy(gobj);
	//delete gobj;
}
void gkScene::_eraseObject(gkGameObject* gobj)
{
	const gkHashedString name = gobj->getName();
	if (m_objects.find(name) == UT_NPOS)
	{
		gkPrintf("Scene: object '%s' not found in this scene\n", name.str().c_str());
		return;
	}

	gobj->destroyInstance();
	gobj->setOwner(0);

	if (m_constraintManager)
		m_constraintManager->notifyObjectDestroyed(gobj);

	m_objects.remove(name);
}
void gkScene::_applyBuiltinParents(gkGameObjectSet& instanceObjects)
{
	gkGameObjectSet::Iterator it = instanceObjects.iterator();
	while (it.hasMoreElements())
	{
		gkGameObject* gobj = it.getNext(), *pobj = 0;

		GK_ASSERT(gobj->isInstanced());

		const gkHashedString pname = gobj->getProperties().m_parent;

		if (!pname.str().empty())
			pobj = findInstancedObject(pname.str());

		if (pobj)
		{

			pobj->addChild(gobj);

			// m_transform no longer contains
			// parent information, we must do it here.


			gkMatrix4 omat, pmat;

			gobj->getProperties().m_transform.toMatrix(omat);
			pobj->getProperties().m_transform.toMatrix(pmat);

			omat = pmat.inverse() * omat;

			gkTransformState st;
			gkMathUtils::extractTransform(omat, st.loc, st.rot, st.scl);


			// apply
			gobj->setTransform(st);
		}
	}
}
void gkGameObjectInstance::destroyObject(gkGameObject* gobj)
{
	if (!gobj)
		return;

	if (gobj->getGroupInstance() != this)
	{
		gkLogMessage("GameObjectInstance: Attempting to remove an object that does not belong to this instance!");
		return;
	}


	const gkHashedString name = gobj->getName();

	UTsize pos;
	if ((pos = m_objects.find(name)) == UT_NPOS)
	{
		gkLogMessage("GameObjectInstance: Missing object " << name.str() << ".");
		return;
	}

	m_objects.remove(name);
	delete gobj;
}
void gkGameObjectInstance::destroyObject(const gkHashedString& name)
{

	UTsize pos;
	if ((pos = m_objects.find(name)) == UT_NPOS)
	{
		gkLogMessage("GameObjectInstance: Missing object " << name.str() << ".");
		return;
	}

	gkGameObject* gobj = m_objects.at(pos);
	gobj->destroyInstance();


	m_objects.remove(name);
	delete gobj;
}