예제 #1
0
파일: entity.cpp 프로젝트: clbr/netradiant
inline scene::Node& entity_for_eclass(EntityClass* eclass)
{
  if((string_compare_nocase_n(eclass->name(), "misc_", 5) == 0 && string_equal_nocase(eclass->name() + string_length(eclass->name()) - 5, "model")) // misc_*model (also misc_model) // TODO make classname_* wrapper functions for this
  || classname_equal(eclass->name(), "model_static"))
  {
    return New_MiscModel(eclass);
  }
  else if(classname_equal(eclass->name(), "light")
    || classname_equal(eclass->name(), "lightJunior"))
  {
    return New_Light(eclass);
  }
  if(!eclass->fixedsize)
  {
    if(g_gameType == eGameTypeDoom3)
    {
      return New_Doom3Group(eclass);
    }
    else
    {
      return New_Group(eclass);
    }
  }
  else if(!string_empty(eclass->modelpath()))
  {
    return New_EclassModel(eclass);
  }
  else
  {
    return New_GenericEntity(eclass);
  }
}
예제 #2
0
bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
	ClearPatches();
	ClearBrushes();
	ClearEPairs();

	QER_Entity = &ent;

	LoadEPairList( Node_getEntity( ent ) );

	bool keep = false;
	int i;
	for ( i = 0; brushEntityList[i]; i++ )
	{
		if ( string_equal_nocase( brushEntityList[i], m_Classname ) ) {
			keep = true;
			break;
		}
	}

	if ( !keep ) {
		return false;
	}

	if ( Node_getTraversable( ent ) ) {
		class load_brushes_t : public scene::Traversable::Walker
		{
		DEntity* m_entity;
		mutable int m_count;
public:
		load_brushes_t( DEntity* entity )
			: m_entity( entity ), m_count( 0 ){
		}

		bool pre( scene::Node& node ) const {
			scene::Path path( NodeReference( GlobalSceneGraph().root() ) );
			path.push( NodeReference( *m_entity->QER_Entity ) );
			path.push( NodeReference( node ) );
			scene::Instance* instance = GlobalSceneGraph().find( path );
			ASSERT_MESSAGE( instance != 0, "" );

			if ( Node_isPatch( node ) ) {
				DPatch* loadPatch = m_entity->NewPatch();
				loadPatch->LoadFromPatch( *instance );
			}
			else if ( Node_isBrush( node ) ) {
				DBrush* loadBrush = m_entity->NewBrush( m_count++ );
				loadBrush->LoadFromBrush( *instance, true );
			}
			return false;
		}
		} load_brushes( this );

		Node_getTraversable( ent )->traverse( load_brushes );
	}

	return true;
}
예제 #3
0
unsigned int global_keys_find(const char* name)
{
  for(int i = 0; i < g_nKeyCount; ++i)
  {
    if(string_equal_nocase(g_Keys[i].m_strName, name))
    {
      return g_Keys[i].m_nVKKey;
    }
  }
  return 0;
}
예제 #4
0
void DMap::ResetTextures( const char* textureName, float fScale[2],      float fShift[2],      int rotation, const char* newTextureName,
						  int bResetTextureName,  int bResetScale[2],  int bResetShift[2],  int bResetRotation ){
	for ( std::list<DEntity *>::const_iterator texEntity = entityList.begin(); texEntity != entityList.end(); texEntity++ )
	{
		if ( string_equal_nocase( "worldspawn", ( *texEntity )->m_Classname ) ) {
			( *texEntity )->ResetTextures( textureName,        fScale,       fShift,       rotation, newTextureName,
										   bResetTextureName,  bResetScale,  bResetShift,  bResetRotation, true );
		}
		else
		{
			if ( ( *texEntity )->ResetTextures( textureName,        fScale,       fShift,       rotation, newTextureName,
												bResetTextureName,  bResetScale,  bResetShift,  bResetRotation, false ) ) {
				RebuildEntity( *texEntity );
			}
		}
	}
}
예제 #5
0
int
lua_import(stream_t* stream, const uuid_t uuid_given) {
	uuid_t uuid = uuid_given;
	string_const_t path;
	string_const_t extension;
	bool store_import = false;
	luaimport_dump_t dump = {0, 0};
	int ret;

	path = stream_path(stream);
	extension = path_file_extension(STRING_ARGS(path));
	if (!string_equal_nocase(STRING_ARGS(extension), STRING_CONST("lua")))
		return -1;

	if (uuid_is_null(uuid))
		uuid = resource_import_map_lookup(STRING_ARGS(path)).uuid;

	if (uuid_is_null(uuid)) {
		uuid = uuid_generate_random();
		store_import = true;
	}

	if (store_import) {
		uuid_t founduuid = resource_import_map_store(STRING_ARGS(path), uuid, uint256_null());
		if (uuid_is_null(founduuid)) {
			log_warn(HASH_RESOURCE, WARNING_SUSPICIOUS,
			         STRING_CONST("Unable to open import map file to store new resource"));
			return -1;
		}
		uuid = founduuid;
	}

	if ((ret = lua_import_stream(stream, uuid, &dump)) < 0)
		goto exit;

	if ((ret = lua_import_output(uuid, &dump)) < 0)
		goto exit;

	resource_import_map_store(STRING_ARGS(path), uuid, stream_sha256(stream));

exit:

	memory_deallocate(dump.bytecode);

	return ret;
}
예제 #6
0
int
render_import(stream_t* stream, const uuid_t uuid_given) {
	renderimport_type_t type = IMPORTTYPE_UNKNOWN;
	renderimport_type_t guess = IMPORTTYPE_UNKNOWN;
	uuid_t uuid = uuid_given;
	string_const_t path;
	string_const_t extension;
	int ret;
	bool store_import = false;

	path = stream_path(stream);
	extension = path_file_extension(STRING_ARGS(path));
	if (string_equal_nocase(STRING_ARGS(extension), STRING_CONST("shader")))
		guess = IMPORTTYPE_SHADER;
	else if (string_equal_nocase(STRING_ARGS(extension), STRING_CONST("program")))
		guess = IMPORTTYPE_PROGRAM;

	type = render_import_shader_guess_type(stream);

	if ((type == IMPORTTYPE_UNKNOWN) && (guess != IMPORTTYPE_UNKNOWN))
		type = guess;

	if (type == IMPORTTYPE_UNKNOWN)
		return -1;

	if (uuid_is_null(uuid))
		uuid = resource_import_lookup(STRING_ARGS(path)).uuid;

	if (uuid_is_null(uuid)) {
		uuid = uuid_generate_random();
		store_import = true;
	}

	if (store_import) {
		uuid_t founduuid = resource_import_map_store(STRING_ARGS(path), uuid, uint256_null());
		if (uuid_is_null(founduuid)) {
			log_warn(HASH_RESOURCE, WARNING_SUSPICIOUS,
			         STRING_CONST("Unable to open import map file to store new resource"));
			return -1;
		}
		uuid = founduuid;
	}

	switch (type) {
	case IMPORTTYPE_PROGRAM:
		ret = render_import_program(stream, uuid);
		break;
	case IMPORTTYPE_SHADER:
		ret = render_import_shader(stream, uuid);
		break;
	case IMPORTTYPE_GLSL_VERTEXSHADER:
		ret = render_import_glsl_vertexshader(stream, uuid);
		break;
	case IMPORTTYPE_GLSL_PIXELSHADER:
		ret = render_import_glsl_pixelshader(stream, uuid);
		break;
	case IMPORTTYPE_UNKNOWN:
	default:
		return -1;
	}

	if (ret == 0)
		resource_import_map_store(STRING_ARGS(path), uuid, stream_sha256(stream));

	return ret;
}
예제 #7
0
void Entity_createFromSelection(const char* name, const Vector3& origin)
{
#if 0
  if(string_equal_nocase(name, "worldspawn"))
  {
    gtk_MessageBox(GTK_WIDGET(MainFrame_getWindow()), "Can't create an entity with worldspawn.", "info");
    return;
  }
#endif

  EntityClass* entityClass = GlobalEntityClassManager().findOrInsert(name, true);

  bool isModel = string_equal_nocase(name, "misc_model")
    || string_equal_nocase(name, "misc_gamemodel")
    || string_equal_nocase(name, "model_static")
    || (GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase(name, "func_static"));

  if(!(entityClass->fixedsize || isModel) && Scene_countSelectedBrushes(GlobalSceneGraph()) == 0)
  {
    globalErrorStream() << "failed to create a group entity - no brushes are selected\n";
    return;
  }


  NodeSmartReference node(GlobalEntityCreator().createEntity(entityClass));

  Node_getTraversable(GlobalSceneGraph().root())->insert(node);

  scene::Path entitypath(makeReference(GlobalSceneGraph().root()));
  entitypath.push(makeReference(node.get()));
  scene::Instance& instance = findInstance(entitypath);

  if(entityClass->fixedsize)
  {
    Select_Delete();
    
    Transformable* transform = Instance_getTransformable(instance);
    if(transform != 0)
    {
      transform->setType(TRANSFORM_PRIMITIVE);
      transform->setTranslation(origin);
      transform->freezeTransform();
    }

    GlobalSelectionSystem().setSelectedAll(false);

    Instance_setSelected(instance, true);
  }
  else
  {
    Scene_parentSelectedBrushesToEntity(GlobalSceneGraph(), node);
    Scene_forEachChildSelectable(SelectableSetSelected(true), instance.path());
  }

  // tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box
  // see SF bug 105383

  if (g_pGameDescription->mGameType == "hl")
  {
    // FIXME - Hydra: really we need a combined light AND color dialog for halflife.
    if (string_equal_nocase(name, "light")
      || string_equal_nocase(name, "light_environment")
      || string_equal_nocase(name, "light_spot"))
    {
      int intensity = g_iLastLightIntensity;

      if (DoLightIntensityDlg (&intensity) == eIDOK)
      {
        g_iLastLightIntensity = intensity;
        char buf[30];
        sprintf( buf, "255 255 255 %d", intensity );
        Node_getEntity(node)->setKeyValue("_light", buf);
      }
    }
  }
  else if(g_pGameDescription->mGameType != "doom3" && string_equal_nocase(name, "light"))
  {
    int intensity = g_iLastLightIntensity;

    if (DoLightIntensityDlg (&intensity) == eIDOK)
    {
      g_iLastLightIntensity = intensity;
      char buf[10];
      sprintf( buf, "%d", intensity );
      Node_getEntity(node)->setKeyValue("light", buf);
    }
  }

  if(isModel)
  {
    const char* model = misc_model_dialog(GTK_WIDGET(MainFrame_getWindow()));
    if(model != 0)
    {
      Node_getEntity(node)->setKeyValue("model", model);
    }
  }
}
예제 #8
0
void Entity_createFromSelection( const char* name, const Vector3& origin ){
#if 0
	if ( string_equal_nocase( name, "worldspawn" ) ) {
		ui::alert( MainFrame_getWindow( ), "Can't create an entity with worldspawn.", "info" );
		return;
	}
#endif

	EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( name, true );

	bool isModel = ( string_compare_nocase_n( name, "misc_", 5 ) == 0 && string_equal_nocase( name + string_length( name ) - 5, "model" ) ) // misc_*model (also misc_model)
				   || string_equal_nocase( name, "model_static" )
				   || ( GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase( name, "func_static" ) );

	bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;

	if ( !( entityClass->fixedsize || isModel ) && !brushesSelected ) {
		globalErrorStream() << "failed to create a group entity - no brushes are selected\n";
		return;
	}

	AABB workzone( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) );


	NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) );

	Node_getTraversable( GlobalSceneGraph().root() )->insert( node );

	scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) );
	entitypath.push( makeReference( node.get() ) );
	scene::Instance& instance = findInstance( entitypath );

	if ( entityClass->fixedsize || ( isModel && !brushesSelected ) ) {
		Select_Delete();

		Transformable* transform = Instance_getTransformable( instance );
		if ( transform != 0 ) {
			transform->setType( TRANSFORM_PRIMITIVE );
			transform->setTranslation( origin );
			transform->freezeTransform();
		}

		GlobalSelectionSystem().setSelectedAll( false );

		Instance_setSelected( instance, true );
	}
	else
	{
		if ( g_pGameDescription->mGameType == "doom3" ) {
			Node_getEntity( node )->setKeyValue( "model", Node_getEntity( node )->getKeyValue( "name" ) );
		}

		Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), node );
		Scene_forEachChildSelectable( SelectableSetSelected( true ), instance.path() );
	}

	// tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box
	// see SF bug 105383

	if ( g_pGameDescription->mGameType == "hl" ) {
		// FIXME - Hydra: really we need a combined light AND color dialog for halflife.
		if ( string_equal_nocase( name, "light" )
			 || string_equal_nocase( name, "light_environment" )
			 || string_equal_nocase( name, "light_spot" ) ) {
			int intensity = g_iLastLightIntensity;

			if ( DoLightIntensityDlg( &intensity ) == eIDOK ) {
				g_iLastLightIntensity = intensity;
				char buf[30];
				sprintf( buf, "255 255 255 %d", intensity );
				Node_getEntity( node )->setKeyValue( "_light", buf );
			}
		}
	}
	else if ( string_equal_nocase( name, "light" ) ) {
		if ( g_pGameDescription->mGameType != "doom3" ) {
			int intensity = g_iLastLightIntensity;

			if ( DoLightIntensityDlg( &intensity ) == eIDOK ) {
				g_iLastLightIntensity = intensity;
				char buf[10];
				sprintf( buf, "%d", intensity );
				Node_getEntity( node )->setKeyValue( "light", buf );
			}
		}
		else if ( brushesSelected ) { // use workzone to set light position/size for doom3 lights, if there are brushes selected
			AABB bounds( Doom3Light_getBounds( workzone ) );
			StringOutputStream key( 64 );
			key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2];
			Node_getEntity( node )->setKeyValue( "origin", key.c_str() );
			key.clear();
			key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2];
			Node_getEntity( node )->setKeyValue( "light_radius", key.c_str() );
		}
	}

	if ( isModel ) {
		const char* model = misc_model_dialog(MainFrame_getWindow());
		if ( model != 0 ) {
			Node_getEntity( node )->setKeyValue( "model", model );
		}
	}
}
예제 #9
0
void Entity_createFromSelection( const char* name, const Vector3& origin ){
#if 0
	if ( string_equal_nocase( name, "worldspawn" ) ) {
		gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Can't create an entity with worldspawn.", "info" );
		return;
	}
#else
	const scene::Node* world_node = Map_FindWorldspawn( g_map );
	if ( world_node && string_equal( name, "worldspawn" ) ) {
//		GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( MainFrame_getWindow() ), "There's already a worldspawn in your map!", "Info", eMB_OK, eMB_ICONDEFAULT );
		UndoableCommand undo( "ungroupSelectedPrimitives" );
		Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), Map_FindOrInsertWorldspawn( g_map ) ); //=no action, if no worldspawn (but one inserted) (since insertion deselects everything)
		//Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), *Map_FindWorldspawn( g_map ) ); = crash, if no worldspawn
		return;
	}
#endif

	StringOutputStream command;
	command << "entityCreate -class " << name;
	UndoableCommand undo( command.c_str() );

	EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( name, true );

	const bool isModel = entityClass->miscmodel_is
				   || ( GlobalSelectionSystem().countSelected() == 0 && classname_equal( name, "func_static" ) && g_pGameDescription->mGameType == "doom3" );

	const bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;

	//is important to have retexturing here; if doing in the end, undo doesn't succeed;
	if ( string_compare_nocase_n( name, "trigger_", 8 ) == 0 && brushesSelected && !entityClass->fixedsize ){
		//const char* shader = GetCommonShader( "trigger" ).c_str();
		Scene_PatchSetShader_Selected( GlobalSceneGraph(), GetCommonShader( "trigger" ).c_str() );
		Scene_BrushSetShader_Selected( GlobalSceneGraph(), GetCommonShader( "trigger" ).c_str() );
	}

	if ( !( entityClass->fixedsize || isModel ) && !brushesSelected ) {
		globalErrorStream() << "failed to create a group entity - no brushes are selected\n";
		return;
	}

	AABB workzone( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) );


	NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) );

	Node_getTraversable( GlobalSceneGraph().root() )->insert( node );

	scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) );
	entitypath.push( makeReference( node.get() ) );
	scene::Instance& instance = findInstance( entitypath );

	if ( entityClass->fixedsize || ( isModel && !brushesSelected ) ) {
		//Select_Delete();

		Transformable* transform = Instance_getTransformable( instance );
		if ( transform != 0 ) {
			transform->setType( TRANSFORM_PRIMITIVE );
			transform->setTranslation( origin );
			transform->freezeTransform();
		}

		GlobalSelectionSystem().setSelectedAll( false );

		Instance_setSelected( instance, true );
	}
	else
	{
		if ( g_pGameDescription->mGameType == "doom3" ) {
			Node_getEntity( node )->setKeyValue( "model", Node_getEntity( node )->getKeyValue( "name" ) );
		}

		Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), node );
		Scene_forEachChildSelectable( SelectableSetSelected( true ), instance.path() );
	}

	// tweaking: when right click dropping a light entity, ask for light value in a custom dialog box
	// see SF bug 105383

	if ( g_pGameDescription->mGameType == "hl" ) {
		// FIXME - Hydra: really we need a combined light AND color dialog for halflife.
		if ( string_equal_nocase( name, "light" )
			 || string_equal_nocase( name, "light_environment" )
			 || string_equal_nocase( name, "light_spot" ) ) {
			int intensity = g_iLastLightIntensity;

			if ( DoLightIntensityDlg( &intensity ) == eIDOK ) {
				g_iLastLightIntensity = intensity;
				char buf[30];
				sprintf( buf, "255 255 255 %d", intensity );
				Node_getEntity( node )->setKeyValue( "_light", buf );
			}
		}
	}
	else if ( string_equal_nocase( name, "light" ) ) {
		if ( g_pGameDescription->mGameType != "doom3" ) {
			int intensity = g_iLastLightIntensity;

			if ( DoLightIntensityDlg( &intensity ) == eIDOK ) {
				g_iLastLightIntensity = intensity;
				char buf[10];
				sprintf( buf, "%d", intensity );
				Node_getEntity( node )->setKeyValue( "light", buf );
			}
		}
		else if ( brushesSelected ) { // use workzone to set light position/size for doom3 lights, if there are brushes selected
			AABB bounds( Doom3Light_getBounds( workzone ) );
			StringOutputStream key( 64 );
			key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2];
			Node_getEntity( node )->setKeyValue( "origin", key.c_str() );
			key.clear();
			key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2];
			Node_getEntity( node )->setKeyValue( "light_radius", key.c_str() );
		}
	}

	if ( isModel ) {
		const char* model = misc_model_dialog( GTK_WIDGET( MainFrame_getWindow() ) );
		if ( model != 0 ) {
			Node_getEntity( node )->setKeyValue( entityClass->miscmodel_key() , model );
		}
	}
}