[solved] StarTrek phaser (Laser) effect.

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

[solved] StarTrek phaser (Laser) effect.

Post by leonardoaraujo.santos »

I trying to create an space game using
1)Technogenius starfield http://www.ogre3d.org/phpBB2/viewtopic.php?t=34555
2)TrekMeshes http://www.trekmeshes.ch/

Here are some screenshots
Image

Does anyone knows how to create a phaser effect with Billboard or other techinique?

I´m reading some topics on the subject but still don´t know how to start.
http://www.ogre3d.org/phpBB2/viewtopic. ... 6f4e2718c6

Here is the code listing...
(If someone could alter this code and add the "phaser effect" it would be great!)

Code: Select all

// Header do Ogre
#include <Ogre.h>
#include <ExampleApplication.h>

/*
Exemplo que usa ManualObjects para criar um efeito mais bonito e menos custoso para placa de video 
implementar estrelas
*/

// Classe que Implementa Randomicos
class Random{
    public:
    Random()
    {
    }

    double randomUniform(double min, double max)
    {
        double r;
        r=(double)rand()/RAND_MAX;
        r=min+r*(max-min);
        return r;
    }

    double randomNormal(double mean, double std)
    {
        double x1, x2, w, y1;
        do {
            x1 = 2.0 * randomUniform(0,1) - 1.0;
            x2 = 2.0 * randomUniform(0,1) - 1.0;
            w = x1 * x1 + x2 * x2;
            } while ( w >= 1.0);
            w = sqrt( (-2.0 * log( w ) ) / w );
            y1 = x1 * w;
            y1 = (y1 * std) + mean;
            return y1;
    }

    void randomSphere(double radius=80)
    {
        double l=0;
        for(int j=0;j<3; j++){
            Tabela[j] = randomNormal(0,1);
            l += Tabela[j]*Tabela[j];
        }
        l = sqrt(l);
        double r = randomUniform(0,1);
        r = pow( r, 1/3);
        for(int j=0;j<3; j++){
            Tabela[j] = radius*(r * Tabela[j] / l);
        }
    }

    double PegaTabela(int i = 0) { return Tabela[i]; }

    private:
    double Tabela [3];
};


class Starfield{
    public:
    Starfield()
    {
    }

    void CreateStarfield(Ogre::SceneManager* mSceneMgr, int NumberOfStars = 10000)
    {
        // Cria uma mesh manualmente
		ManualObject* manual = mSceneMgr->createManualObject("manual");

        manual->begin("BaseWhiteNoLighting", RenderOperation::OT_POINT_LIST);
        float brillance=0.0;
        Random p;
        for (int i=0; i<NumberOfStars; i++) 
		{
			// Tamanho da esfera
            p.randomSphere(10000);
            brillance = (int)((float)rand()/32767*99);
            brillance = brillance/100;            
            manual->position(p.PegaTabela(0), p.PegaTabela(1), p.PegaTabela(2));
            manual->colour(ColourValue(brillance, brillance, brillance, 1));
        }
        manual->end();

		// Agora cria um node e anexa a mesh manual criada
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
    }
};


class SampleApp : public ExampleApplication
{
public:    
    SampleApp()
    {}

protected:

    // Sobrecarrega do CreateScene
    void createScene(void)
    {
        /// Cria o campo estelar
        Starfield *p_Starfield = new Starfield();
        p_Starfield->CreateStarfield(mSceneMgr);		

		mSceneMgr->setSkyDome(true, "StarTrek/NebulaTeste", 5, 1);//5,1		
		//mSceneMgr->setSkyBox(true, "StarTrek/NebulaTeste");


		// Luz 
		mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
		Light *light = mSceneMgr->createLight("Light_BOP");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(0, 20, 0));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);

		light = mSceneMgr->createLight("LightGalaxy");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(50, 40, 100));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);
		
		light = mSceneMgr->createLight("Light3");
        light->setType(Light::LT_DIRECTIONAL);
        light->setDiffuseColour(ColourValue(.25, .25, 0));
        light->setSpecularColour(ColourValue(.25, .25, 0));

		light->setDirection(Vector3( 0, -1, 1 )); 

		// Nave Klingon
		Entity *ent2 = mSceneMgr->createEntity( "Nave_K", "BirdOfPrey.mesh" );        
		SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_K" );
        node2->attachObject( ent2 );

		// Nave Enterprise Galaxy
		Entity *ent3 = mSceneMgr->createEntity( "Nave_Galaxy", "Nave_Enterrpise.mesh" );        
		SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_Galaxy",Vector3( 50, 20, 100 ) );
        node3->attachObject( ent3 );
    }
};


// ----------------------------------------------------------------------------
// Main function, just boots the application object
// ----------------------------------------------------------------------------
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    SampleApp app;

    try
    {
        app.go();
    }
    catch( Exception& e )
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else

        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}
Last edited by leonardoaraujo.santos on Mon Sep 08, 2008 12:08 am, edited 1 time in total.
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I´ve succesfully created a "phaser" effect twisting the Hexidave Tubes (He gave me a different kind of approach I think... he told me that I could create with ManualObject 6 planes intersecting each other like an * pattern) and them use the same material with additive alpha blend... this would create the glow effect.... (The FPS is quite low now but it is because I´m in Debug mode)
Could anyone post me some sample mateiral of this "additive alpha blend" effect? (Please help me on this guys... :lol: )

Hexidave wikki on tubes....
http://www.ogre3d.org/wiki/index.php/A_Series_Of_Tubes


Another question... I could use a shader (Stencial glow effect ) to achieve the same result??
http://www.ogre3d.org/phpBB2/viewtopic.php?t=27477

Image

Anyway this is the code used in my Tube class twist??? (I just taked out the sphere thing in wiki

Tubes.h

Code: Select all

//#pragma once

#ifndef _TUBES_H_
#define _TUBES_H_

#include <OgrePrerequisites.h>
#include <OgreMaterial.h>
#include <OgreMesh.h>

namespace Ogre
{
	class SeriesOfTubes
	{
	public:
		SeriesOfTubes(
			Ogre::SceneManager* sceneMgr, 
			const Ogre::uint numberOfSides = 0, 
			const Ogre::Real radius = 0.0);
		~SeriesOfTubes();

		void addPoint(const Ogre::Vector3& pos);
		void removePoint(const Ogre::uint pointNumber);

		void setRadius(const Ogre::Real radius){mRadius = radius;}
		void setSides(const Ogre::uint numberOfSides){mSideCount = numberOfSides;}

		const Ogre::Real getRadius(){return mRadius;}
		const Ogre::uint getSides(){return mSideCount;}

		void setSceneNode(Ogre::SceneNode* sceneNode){mSceneNode = sceneNode;}
		Ogre::SceneNode* getSceneNode(){return mSceneNode;}

		Ogre::MaterialPtr getMaterial(){return mMaterial;}

		Ogre::ManualObject* createTubes(
			const Ogre::String& name, 
			const Ogre::String& materialName, 
			bool uniqueMaterial = false, 
			bool isDynamic = false, 
			bool disableUVs = false, 
			bool disableNormals = false);

		void _update(bool disableUVs = false, bool disableNormals = false);
		void _destroy();				

	private:
		Ogre::SceneManager* mSceneMgr;

		typedef std::vector<Ogre::Vector3> VVec;
		VVec mLineVertices;

		Ogre::uint mSideCount;
		Ogre::Real mRadius;
		bool mUniqueMaterial;

		Ogre::uint mSphereRings;
		Ogre::uint mSphereSegments;
		Ogre::Real mSphereRadius;
		Ogre::Real mSphereMaxVisDistance;

		Ogre::MaterialPtr mMaterial;
		Ogre::ManualObject* mTubeObject;

		typedef std::vector<Ogre::Entity*> SphereStorage;
		SphereStorage mSpheresJoints;
		Ogre::MeshPtr mSphereMesh;

		Ogre::SceneNode* mSceneNode;
		

	};
}

#endif
Tubes.cpp

Code: Select all

#include "Tubes.h"

#include <OgreManualObject.h>
#include <OgreMaterialManager.h>
#include <OgreSceneManager.h>
#include <OgreStringConverter.h>
#include <OgreEntity.h>
#include <OgreMeshManager.h>
#include <OgreHardwareVertexBuffer.h>
#include <OgreHardwareIndexBuffer.h>
#include <OgreSubMesh.h>


using namespace Ogre;


namespace Ogre
{



	SeriesOfTubes::SeriesOfTubes( 
		Ogre::SceneManager* sceneMgr, 
		const Ogre::uint numberOfSides /*= 0*/, 
		const Ogre::Real radius /*= 0.0*/)
		: mSceneMgr(sceneMgr),
		mSideCount(numberOfSides),
		mRadius(radius), 
		mTubeObject(0),
		mUniqueMaterial(false),				
		mSceneNode(0)
	{

	}

	SeriesOfTubes::~SeriesOfTubes()
	{
		_destroy();
	}

	void SeriesOfTubes::addPoint( const Ogre::Vector3& pos )
	{
		mLineVertices.push_back(pos);
	}

	void SeriesOfTubes::removePoint( const Ogre::uint pointNumber )
	{
		if (pointNumber < mLineVertices.size())
		{
			VVec::iterator it = mLineVertices.begin() + pointNumber;
			mLineVertices.erase(it);
		}
	}

	Ogre::ManualObject* SeriesOfTubes::createTubes( 
		const Ogre::String& name, 
		const Ogre::String& materialName, 
		bool uniqueMaterial /* = false*/,
		bool isDynamic /*= false*/,
		bool disableUVs /*= false*/, 
		bool disableNormals /*= false*/)
	{
		if (mTubeObject)
			return mTubeObject;

		mMaterial = MaterialManager::getSingleton().getByName(materialName);

		mUniqueMaterial = uniqueMaterial;

		if (mUniqueMaterial)
			mMaterial = mMaterial->clone(materialName + "_" + name);
        		

		mTubeObject = mSceneMgr->createManualObject(name);

		mTubeObject->setDynamic(isDynamic);

		_update(disableUVs,disableNormals);

		if (mSceneNode)
			mSceneNode->attachObject(mTubeObject);


		return mTubeObject;

		
	}

	void SeriesOfTubes::_update(bool disableUVs /*= false*/, bool disableNormals /*= false*/)
	{
		if (mTubeObject == 0 || mLineVertices.size() < 2)
			return;

		if (mTubeObject->getDynamic() == true && mTubeObject->getNumSections() > 0)
			mTubeObject->beginUpdate(0);
		else
			mTubeObject->begin(mMaterial->getName());


		Quaternion qRotation(Degree(360.0/(Real)mSideCount),Vector3::UNIT_Z);

		const uint iVertCount = mSideCount + 1;		

		Vector3* vCoreVerts = new Vector3[iVertCount];
		Vector3 vPos = Vector3::UNIT_X * mRadius;		
		

		for (int i=0;i<iVertCount;i++)
		{
			vCoreVerts[i] = vPos;
			vPos = qRotation * vPos;
		}


		Vector3 vLineVertA, vLineVertB;
		Vector3 vLine;
		Real dDistance;
		int A,B,C,D;
		int iOffset;

		Vector3* vCylinderVerts = new Vector3[iVertCount * 2];
		
		for (int i=1;i<mLineVertices.size();i++)
		{
			vLineVertA = mLineVertices[i-1];
			vLineVertB = mLineVertices[i];

			vLine = vLineVertB - vLineVertA;
			dDistance = vLine.normalise();

			qRotation = Vector3::UNIT_Z.getRotationTo(vLine);			

			for (int j=0;j<iVertCount;j++)
			{
				vCylinderVerts[j] = (qRotation * vCoreVerts[j]);
				vCylinderVerts[j + iVertCount] = (qRotation * (vCoreVerts[j] + (Vector3::UNIT_Z * dDistance)));								
			}

			Real u,v,delta;
			delta = 1.0 / (Real)(iVertCount-1);
			u = 0.0;
			v = 1.0;
			
			for (int j=0;j<(iVertCount*2);j++)
			{
				mTubeObject->position(vCylinderVerts[j] + vLineVertA);
				if (disableNormals == false)
				{
					mTubeObject->normal(vCylinderVerts[j].normalisedCopy());
				}
				if (disableUVs == false)
				{
					if (j == iVertCount){
						u = 0.0;
						v = 0.0;
					}
					mTubeObject->textureCoord(u,v);
					u += delta;
				}
			}

			iOffset = (i-1) * (iVertCount*2);
			for (int j=0;j<iVertCount;j++)
			{
				// End A: 0-(Sides-1)
				// End B: Sides-(Sides*2-1)								
				A = ((j+1) % iVertCount);
				B = j;
				C = A + iVertCount;
				D = B + iVertCount;

				A += iOffset;
				B += iOffset;
				C += iOffset;
				D += iOffset;


				// Tri #1
				// C,B,A

				mTubeObject->triangle(C,B,A);

				// Tri #2
				// C,D,B

				mTubeObject->triangle(C,D,B);

			}
		}

		delete[] vCoreVerts;
		delete[] vCylinderVerts;
		vCoreVerts = 0;
		vCylinderVerts = 0;		

		if (mSceneNode)
			mSceneNode->removeAndDestroyAllChildren();
		

		Entity* pEnt = 0;
		SceneNode* pChildNode = 0;
		VVec::iterator it = mLineVertices.begin()+1;
		for (int i=1; it != (mLineVertices.end()-1);++it,i++)
		{
			if (mSpheresJoints.size() < i)
			{
				pEnt = mSceneMgr->createEntity(mTubeObject->getName() + "_SphereEnt" + StringConverter::toString(i),mSphereMesh->getName());
				pEnt->setMaterialName(mMaterial->getName());
				mSpheresJoints.push_back(pEnt);
			}
			else
			{
				pEnt = mSpheresJoints[i-1];
			}
			pEnt->setRenderingDistance(mSphereMaxVisDistance);
            
			if (mSceneNode)
			{
				pChildNode = mSceneNode->createChildSceneNode();
				pChildNode->setPosition((*it));				
				pChildNode->attachObject(pEnt);
			}
		}


        mTubeObject->end();



	}

	void SeriesOfTubes::_destroy()
	{
		if (mTubeObject)
		{
			if (mTubeObject->getParentSceneNode())
				mTubeObject->getParentSceneNode()->detachObject(mTubeObject);


			mSceneMgr->destroyManualObject(mTubeObject);
		}

		

		if (mUniqueMaterial)
		{
			MaterialManager::getSingleton().remove(mMaterial->getName());
		}
		mMaterial.setNull();

		if (mSpheresJoints.size() > 0)
		{
			Entity* pEnt = 0;
			SphereStorage::iterator it = mSpheresJoints.begin();
			for (; it != mSpheresJoints.end(); ++it)
			{
				pEnt = (*it);
				pEnt->getParentSceneNode()->detachObject(pEnt);
				mSceneMgr->destroyEntity(pEnt);
			}
		}

		if (mSphereMesh.isNull() == false)
		{
			MeshManager::getSingleton().remove(mSphereMesh->getName());
			mSphereMesh.setNull();
		}

		if (mSceneNode)
		{
			mSceneNode->removeAndDestroyAllChildren();
			mSceneNode->getParentSceneNode()->removeAndDestroyChild(mSceneNode->getName());
			mSceneNode = 0;
		}

	}	
}
Using in my code... (kind the same on previous post.... but with this..)

Code: Select all

// Tubos..
		SceneNode* pNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes = new SeriesOfTubes(mSceneMgr,6,0.25); //6 faces , 0.25 radius of tube...
 
		// Ponto da Galaxy até a BOP
		mTubes->addPoint(Vector3(50,20,100));		
		mTubes->addPoint(Vector3(0,0,0));
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I think I´ve sucessfully created the asteristic pattern to create the phaser tube effect...

I´ve twisted the Imediate Tutorial 5 (Grass) to create some quads intersecting each other like the figure bellow....
Front view
Image

Far away view...
Image

I´ve used this material... (This is the Additive Alpha blend???)

Code: Select all

material Examples/GrassBlades
{
	// Vertex program waving grass

	// Non-vertex program technique (no waving)
	technique
    {
        pass
        {
	    alpha_rejection greater 150 
	    scene_blend add alpha_blend
            cull_hardware none
            cull_software none
            texture_unit
            {
                //texture gras_02.png 
		texture Phaser4.jpg
            }
        }
    }
}

And this is the texture used....
Image

I´ve also increased the number of planes...
Front View
Image

Far away view...
Image

I am missing something... ? I will try to use the stencil glow shader sample and as soon as I get some screenshots I will send you guys..

And this is the code to create the manual object....

Code: Select all

void createGrassMesh()
    {
        const float width = 5;
        const float height = 300;
        ManualObject mo("GrassObject");

        Vector3 vec(width/2, 0, 0);
        Quaternion rot;
        rot.FromAngleAxis(Degree(10), Vector3::UNIT_Y);//60
    
        mo.begin("Examples/GrassBlades", RenderOperation::OT_TRIANGLE_LIST);
        for (int i = 0; i < 18; ++i)//3
        {
            mo.position(-vec.x, height, -vec.z);
            mo.textureCoord(0, 0);

            mo.position(vec.x, height, vec.z);
            mo.textureCoord(1, 0);

            mo.position(-vec.x, 0, -vec.z);
            mo.textureCoord(0, 1);

            mo.position(vec.x, 0, vec.z);
            mo.textureCoord(1, 1);
            
            int offset = i * 4;//4
            mo.triangle(offset, offset+3, offset+1);
            mo.triangle(offset, offset+2, offset+3);

            vec = rot * vec;
        }
        mo.end();

        mo.convertToMesh("GrassBladesMesh");
    }
Vectrex
Ogre Magi
Posts: 1266
Joined: Tue Aug 12, 2003 1:53 am
Location: Melbourne, Australia
x 1

Post by Vectrex »

cool. Check out 'Particle universe' particle plugin. It's really great for these types of effects. Much more powerful than the standard ogre particles
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Using the stencil glow shader.... (Thanks to Assaf Raman)
Image
Image

Material

Code: Select all

vertex_program glow_vs_cg cg
{
	source vs_glow.cg
	entry_point main
	profiles vs_1_1 arbvp1

}

fragment_program glow_ps_cg cg
{
	source ps_glow.cg
	entry_point main
	profiles ps_2_0 arbfp1	
	


}




material cg/glow
{
	technique
	{
		pass
		{
			scene_blend alpha_blend
			depth_check on
			lighting off
			

			vertex_program_ref glow_vs_cg
			{
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				param_named size_value float 1.1
				param_named_auto time time_0_x 100
			}
			
			fragment_program_ref glow_ps_cg 
			{
				param_named alpha_value float 0.4
				param_named_auto time time_0_x 100
			}
		}
		
	}
}



material cg/alpha_glow
{
	technique
	{
		pass
		{
			scene_blend alpha_blend
			depth_check on
			lighting off
			
			fragment_program_ref glow_ps_cg 
			{
				param_named_auto time time_0_x 100
				param_named alpha_value float 0.0
			}
			vertex_program_ref glow_vs_cg 
			{
				// World projection matrix
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				
				// Glow size parameter
				param_named size_value float 0.5

				// Time parameter
				param_named_auto time time_0_x 100
			}
		}
		
	pass
		{
			scene_blend alpha_blend
			depth_check on
			lighting off
			
			fragment_program_ref glow_ps_cg 
			{
				param_named_auto time time_0_x 100
				param_named alpha_value float 0.0
			}
		}		
		
	}
}

material cg/no_depth_check_glow
{
	technique
	{
		pass
		{
			scene_blend alpha_blend
			depth_check off
			lighting off
			
			fragment_program_ref glow_ps_cg 
			{
				param_named_auto time time_0_x 100
				param_named alpha_value float 0.4
			}
		}
		
		pass
		{
			scene_blend alpha_blend
			depth_check off
			lighting off
			
			fragment_program_ref glow_ps_cg 
			{
				param_named_auto time time_0_x 100
				param_named alpha_value float 0.4
			}
			vertex_program_ref glow_vs_cg 
			{
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				param_named size_value float 1.1
				param_named_auto time time_0_x 100
			}
		}
	
	}
}
Vertex shader

Code: Select all

void main(float4 position : POSITION,
			  float3 normal   : NORMAL,
			  float2 uv		  : TEXCOORD0,
			  out float4 oPosition : POSITION,
			  out float2 oUv	   : TEXCOORD0,
			  out float4 colour    : COLOR,
			
			  uniform float4x4 worldViewProjMatrix,
			  uniform float size_value,
			   uniform float time
			)
{

   float4 mypos = position;
   mypos.xyz += size_value * (1.0 + (sin(time * 5.0) + 1.0)  / 5.0 ) * normal; 
   oPosition = mul(worldViewProjMatrix, mypos);
	
}
Pixel Shader

Code: Select all


float4 main(uniform float alpha_value,
			uniform float time
) : COLOR
{
   float4 color;
   color.x = 1.0; // RED
   color.y = 0.0; // Green
   color.z = 0.0; // Blue

   // Transparencia
   color.w =  alpha_value * ((sin(time * 5.0) / 3.14 + 1.0) / 2.0 );

   // Retorna cor...
   return color;     
}
Coding for creating scene

Code: Select all

// Sobrecarrega do CreateScene
    void createScene(void)
    {
        /// Cria o campo estelar
        //Starfield *p_Starfield = new Starfield();
        //p_Starfield->CreateStarfield(mSceneMgr);		
		
		mSceneMgr->setSkyBox(true, "StarTrek/NebulaTeste");


		// Luz 
		mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
		Light *light = mSceneMgr->createLight("Light_BOP");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(0, 20, 0));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);

		light = mSceneMgr->createLight("LightGalaxy");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(50, 40, 100));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);
		
		light = mSceneMgr->createLight("Light3");
        light->setType(Light::LT_DIRECTIONAL);
        light->setDiffuseColour(ColourValue(.25, .25, 0));
        light->setSpecularColour(ColourValue(.25, .25, 0));

		light->setDirection(Vector3( 0, -1, 1 )); 

		// Nave Klingon
		Entity *ent2 = mSceneMgr->createEntity( "Nave_K", "BirdOfPrey.mesh" );        
		SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_K" );
        node2->attachObject( ent2 );

		// Nave Enterprise Galaxy
		Entity *ent3 = mSceneMgr->createEntity( "Nave_Galaxy", "Nave_Enterrpise.mesh" );        
		SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_Galaxy",Vector3( 50, 20, 100 ) );
        node3->attachObject( ent3 );

		// Tubos.. (Para o glow serao 3 tubos)*********************
		SceneNode* pNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes->addPoint(Vector3(50,20,100));		
		mTubes->addPoint(Vector3(0,0,0));
		

		mTubes->setSceneNode(pNode);
		mTubes->createTubes("MyTubes","StarTrek/PhaserBeam");		

		//*******************************
		SceneNode* pNode1 = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes1 = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes1->addPoint(Vector3(50,20,100));		
		mTubes1->addPoint(Vector3(0,0,0));
		

		mTubes1->setSceneNode(pNode1);
		mTubes1->createTubes("MyTubes1","cg/alpha_glow");				
		mTubes1->setRenderQueueGroup(RENDER_QUEUE_FULL_GLOW_ALPHA_GLOW); 

		//******************************
		SceneNode* pNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes2 = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes2->addPoint(Vector3(50,20,100));		
		mTubes2->addPoint(Vector3(0,0,0));
		

		mTubes2->setSceneNode(pNode2);
		mTubes2->createTubes("MyTubes2","cg/no_depth_check_glow");				
		mTubes2->setRenderQueueGroup(RENDER_QUEUE_FULL_GLOW_GLOW); 
    }

	StencilOpQueueListener * mStencilOpFrameListener;

	virtual void createFrameListener(void)
	{
		ExampleApplication::createFrameListener();
		mStencilOpFrameListener = new StencilOpQueueListener();
		mSceneMgr->addRenderQueueListener(mStencilOpFrameListener);
	}
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

No... ball plasma shield! :cry:

Can anyone send me a ellipsoide mesh (Or an tutorial creating one in 3ds max)
Image

Anyway...
It´s a sphere with this material (The effect it´s a semi transparent mesh...)
This was the material texture used... (Lava and perlim noise with alpha)
Image

And the material code...

Code: Select all

material StarTrek/ForceShield
{
	technique
	{
		pass
		{	
			scene_blend alpha_blend
			texture_unit
			{				
				texture Force_Shield.png
				//env_map spherical
				rotate_anim 0.01
			}
		}
	}
}
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Well continue with my efforts with phaser and shields. I´ve sucessfuly created a ellipsoid mesh with some funky material and a decal...
Image

Some one know how I could know the hit point position from phaser to shield in order to centralize the decal...
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I´ve sucessfully solved the decal align problem with a SceneQuery them some vector math to calculate the 3d position intersection...

Code: Select all

Vector3 origem = RaioPhaser.getOrigin();
Vector3 direcao = RaioPhaser.getDirection(); 
Real tam_direcao = direcao.length(); 
Real distancia= itr->distance;
direcao = direcao / tam_direcao;
pos_impacto = origem + (direcao * distancia);					
					LogManager::getSingletonPtr()->logMessage("Pegou coordenada escudo");
The result (We still se that there is some error offset but I think this is enough... at least I think it is cheaper than using a physic ray cast)
Image

Still have some decal problems...
Image

Hope that sharing the code with others can help something...

Code: Select all

// Header do Ogre
#include <Ogre.h>
#include <ExampleApplication.h>
#include <Tubes.h>
#include <OgreRenderQueueListener.h> 

// render queues
#define RENDER_QUEUE_OUTLINE_GLOW_OBJECTS	RENDER_QUEUE_MAIN + 1
#define RENDER_QUEUE_OUTLINE_GLOW_GLOWS		RENDER_QUEUE_MAIN + 2
#define RENDER_QUEUE_FULL_GLOW_ALPHA_GLOW	RENDER_QUEUE_MAIN + 3
#define RENDER_QUEUE_FULL_GLOW_GLOW			RENDER_QUEUE_MAIN + 4
#define LAST_STENCIL_OP_RENDER_QUEUE		RENDER_QUEUE_FULL_GLOW_GLOW

// stencil values
#define STENCIL_VALUE_FOR_OUTLINE_GLOW 1
#define STENCIL_VALUE_FOR_FULL_GLOW 2
#define STENCIL_FULL_MASK 0xFFFFFFFF

// Mascaras
enum QueryFlags
{
    FRUSTUM_FLAG = 1<<0,
    NAVES = 1<<1,
    OBJETOS_ESTACIONARIOS = 1<<2,
	SHIELDS = 1<<3
};


// A FrameListener that gets passed our projector node and decal frustum so they can be animated
class ProjectiveDecalListener : public ExampleFrameListener
{
public:
    ProjectiveDecalListener(RenderWindow* win, Camera* cam, SceneNode *proj, Frustum *decal, SceneManager *mgrscr)
        : ExampleFrameListener(win, cam), mProjectorNode(proj), mDecalFrustum(decal), mAnim(0), mSceneMgr(mgrscr)
    {
    }

    bool frameStarted(const FrameEvent& evt)
    {
        RaySceneQuery *mRaySceneQuery;		

        // Animacoes de 2 segundos
        mAnim += evt.timeSinceLastFrame / 2;
        if (mAnim >= 1)
            mAnim -= 1;
        
		// Seta o FOV do frustrum do decal para 4 graus
		if (mDecalFrustum)
		{
			mDecalFrustum->setFOVy((Ogre::Degree)4);
		}

		// Cria RaySceneQuery para ver onde pegou no escudo
        mRaySceneQuery = mSceneMgr->createRayQuery(Ray());		
		Vector3 PosGalaxy = mSceneMgr->getSceneNode("Node_Nave_Galaxy")->getPosition();
		Vector3 PosBOP = mSceneMgr->getSceneNode("Node_Nave_K")->getPosition();
		Vector3 vDirecao = PosBOP - PosGalaxy;
		vDirecao.normalise();
		Ray RaioPhaser(PosGalaxy, vDirecao);
		mRaySceneQuery->setRay(RaioPhaser);
		// Procura somente escudo (Mascara da query)
		mRaySceneQuery->setQueryMask(SHIELDS | FRUSTUM_FLAG);
		RaySceneQueryResult &result = mRaySceneQuery->execute();		
		RaySceneQueryResult::iterator itr=result.begin(); 
		
		// Get the results & do something
		if (itr!=result.end()&&itr->movable)
		{   						
			for( ; itr != result.end() ; itr++ )
			{				
				static Vector3 pos_impacto;				
				if (itr->movable->getName() == "Esfera")
				{
					LogManager::getSingletonPtr()->logMessage("Pegou Escudo");							
					// Agora vamos calcular o ponto de impacto...
					Vector3 origem = RaioPhaser.getOrigin();
					Vector3 direcao = RaioPhaser.getDirection(); 
					Real tam_direcao = direcao.length(); 
					Real distancia= itr->distance;
					direcao = direcao / tam_direcao;
					pos_impacto = origem + (direcao * distancia);					
					LogManager::getSingletonPtr()->logMessage("Pegou coordenada escudo");
				}

				if (itr->movable->getMovableType() == "Frustum")
				{
					// Agora vamos calcular o ponto de impacto...					
					if (itr->movable->getParentNode()->getName() == "DecalProjectorNode")
					{						
						LogManager::getSingletonPtr()->logMessage("Pegou Frustum decal");							
						itr->movable->getParentNode()->setPosition(pos_impacto);
					}
				}
			}			
		}		
		else
		{
			LogManager::getSingletonPtr()->logMessage("NAO ACHOU NADA");
		}

        return ExampleFrameListener::frameStarted(evt);

    }

protected:
    SceneNode *mProjectorNode;
    Frustum *mDecalFrustum;
	SceneManager *mSceneMgr;
    float mAnim;
};


class StencilOpQueueListener : public Ogre::RenderQueueListener 
{ 
public: 
	virtual void renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation) 
	{ 
		if (queueGroupId == RENDER_QUEUE_OUTLINE_GLOW_OBJECTS) // outline glow object 
		{ 
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 

			rendersys->clearFrameBuffer(Ogre::FBT_STENCIL); 
			rendersys->setStencilCheckEnabled(true); 
			rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS,
				STENCIL_VALUE_FOR_OUTLINE_GLOW, STENCIL_FULL_MASK, 
				Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false);       
		} 
		if (queueGroupId == RENDER_QUEUE_OUTLINE_GLOW_GLOWS)  // outline glow
		{ 
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 
			rendersys->setStencilCheckEnabled(true); 
			rendersys->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL,
				STENCIL_VALUE_FOR_OUTLINE_GLOW, STENCIL_FULL_MASK, 
				Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false);       
		} 
		if (queueGroupId == RENDER_QUEUE_FULL_GLOW_ALPHA_GLOW)  // full glow - alpha glow
		{ 
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 
			rendersys->setStencilCheckEnabled(true); 
			rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS,
				STENCIL_VALUE_FOR_FULL_GLOW,STENCIL_FULL_MASK, 
				Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false);       
		} 

		if (queueGroupId == RENDER_QUEUE_FULL_GLOW_GLOW)  // full glow - glow
		{ 
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 
			rendersys->setStencilCheckEnabled(true); 
			rendersys->setStencilBufferParams(Ogre::CMPF_EQUAL,
				STENCIL_VALUE_FOR_FULL_GLOW,STENCIL_FULL_MASK, 
				Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_ZERO,false);       
		} 

	} 

	virtual void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation) 
	{ 
		if (( queueGroupId == LAST_STENCIL_OP_RENDER_QUEUE )) 
		{ 
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 
			rendersys->setStencilCheckEnabled(false); 
			rendersys->setStencilBufferParams(); 
		} 
	} 

}; 

/*
Exemplo que usa ManualObjects para criar um efeito mais bonito e menos custoso para placa de video 
implementar estrelas
*/

// Classe que Implementa Randomicos
class Random{
    public:
    Random()
    {
    }

    double randomUniform(double min, double max)
    {
        double r;
        r=(double)rand()/RAND_MAX;
        r=min+r*(max-min);
        return r;
    }

    double randomNormal(double mean, double std)
    {
        double x1, x2, w, y1;
        do {
            x1 = 2.0 * randomUniform(0,1) - 1.0;
            x2 = 2.0 * randomUniform(0,1) - 1.0;
            w = x1 * x1 + x2 * x2;
            } while ( w >= 1.0);
            w = sqrt( (-2.0 * log( w ) ) / w );
            y1 = x1 * w;
            y1 = (y1 * std) + mean;
            return y1;
    }

    void randomSphere(double radius=80)
    {
        double l=0;
        for(int j=0;j<3; j++){
            Tabela[j] = randomNormal(0,1);
            l += Tabela[j]*Tabela[j];
        }
        l = sqrt(l);
        double r = randomUniform(0,1);
        r = pow( r, 1/3);
        for(int j=0;j<3; j++){
            Tabela[j] = radius*(r * Tabela[j] / l);
        }
    }

    double PegaTabela(int i = 0) { return Tabela[i]; }

    private:
    double Tabela [3];
};


class Starfield{
    public:
    Starfield()
    {
    }

    void CreateStarfield(Ogre::SceneManager* mSceneMgr, int NumberOfStars = 10000)
    {
        // Cria uma mesh manualmente
		ManualObject* manual = mSceneMgr->createManualObject("manual");

        manual->begin("BaseWhiteNoLighting", RenderOperation::OT_POINT_LIST);
        float brillance=0.0;
        Random p;
        for (int i=0; i<NumberOfStars; i++) 
		{
			// Tamanho da esfera
            p.randomSphere(10000);
            brillance = (int)((float)rand()/32767*99);
            brillance = brillance/100;            
            manual->position(p.PegaTabela(0), p.PegaTabela(1), p.PegaTabela(2));
            manual->colour(ColourValue(brillance, brillance, brillance, 1));
        }
        manual->end();

		// Agora cria um node e anexa a mesh manual criada
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
    }
};


class SampleApp : public ExampleApplication
{
public:    
    SampleApp()
    {}

protected:
	SceneNode *mProjectorNode;
    Frustum *mDecalFrustum;
    Frustum *mFilterFrustum;

	// Funcao para criar o decal
    void createProjector()
    {
		// set up the main decal projection frustum
        mDecalFrustum = new Frustum();
		mDecalFrustum->setQueryFlags(FRUSTUM_FLAG);
        mProjectorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("DecalProjectorNode");
        mProjectorNode->attachObject(mDecalFrustum);
        //mProjectorNode->setPosition(4.6122017,1.8448830,9.2244034); //0,1.4,0		

        // include these two lines if you don't want perspective projection
        mDecalFrustum->setProjectionType(PT_ORTHOGRAPHIC);
        mDecalFrustum->setNearClipDistance(120);//25

        // Seta um frustum perpendicular
        mFilterFrustum = new Frustum();
        mFilterFrustum->setProjectionType(PT_ORTHOGRAPHIC);
		mFilterFrustum->setQueryFlags(FRUSTUM_FLAG);
        SceneNode *filterNode = mProjectorNode->createChildSceneNode("DecalFilterNode");
        filterNode->attachObject(mFilterFrustum);
        filterNode->setOrientation(Quaternion(Degree(90),Vector3::UNIT_Y));        

    }
	
	// Poe um pass extra no material que renderiza o decal no topo da textura
    void makeMaterialReceiveDecal(const String &matName)
    {
		// Pega o material
        MaterialPtr mat = (MaterialPtr)MaterialManager::getSingleton().getByName(matName);

        // Cria um novo pass na textura do material
        Pass *pass = mat->getTechnique(0)->createPass();

        // Seta o passe para se mesclar com a textura anterior
        pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
        pass->setDepthBias(1);

        // Poe o decal com iluminacao propia
        pass->setLightingEnabled(false);

        // Seta primeira textura
		TextureUnitState *texState = pass->createTextureUnitState("Nebula_tr.png");
        texState->setProjectiveTexturing(true, mDecalFrustum);
        texState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
        texState->setTextureFiltering(FO_POINT, FO_LINEAR, FO_NONE);

        // Seta textura de filtro (Mesmo tirando funciona)
        texState = pass->createTextureUnitState("decal_filter.png");
        texState->setProjectiveTexturing(true, mFilterFrustum);
        texState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
        texState->setTextureFiltering(TFO_NONE);

    }

	
	// Sobrecarrega do CreateScene
    void createScene(void)
    {        
		/// Cria o campo estelar
        //Starfield *p_Starfield = new Starfield();
        //p_Starfield->CreateStarfield(mSceneMgr);		
		
		mSceneMgr->setSkyBox(true, "StarTrek/NebulaTeste");
		

		// Luz 
		mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
		Light *light = mSceneMgr->createLight("Light_BOP");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(0, 20, 0));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);

		light = mSceneMgr->createLight("LightGalaxy");
        light->setType(Light::LT_POINT);        
		light->setPosition(Vector3(0, 20, 100));
		light->setDiffuseColour(1.0, 1.0, 1.0);
        light->setSpecularColour(1.0, 1.0, 1.0);
		
		light = mSceneMgr->createLight("Light3");
        light->setType(Light::LT_DIRECTIONAL);
        light->setDiffuseColour(ColourValue(.25, .25, 0));
        light->setSpecularColour(ColourValue(.25, .25, 0));

		light->setDirection(Vector3( 0, -1, 1 )); 

		// Nave Klingon
		Entity *ent2 = mSceneMgr->createEntity( "Nave_Klingon", "BirdOfPrey.mesh" );        
		SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_K" );
		ent2->setQueryFlags(NAVES);
        node2->attachObject( ent2 );
		// Esfera
		Entity *esfera_teste = mSceneMgr->createEntity("Esfera", "esfera_teste.mesh");
		esfera_teste->setMaterialName("StarTrek/ForceShield");
		esfera_teste->setQueryFlags(SHIELDS);
		SceneNode *node_esfera = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Escudo_BOP" );
		node_esfera->attachObject(esfera_teste);   

		// Pega o tamanho atual da esfera e divide por 4
		node_esfera->setScale(node_esfera->getScale() / 9);

		// Cria o decal		
        createProjector();
		// Poe o material em todas as subentities da entidade do escudo		
		for (unsigned int i = 0; i < esfera_teste->getNumSubEntities(); i++)
            makeMaterialReceiveDecal(esfera_teste->getSubEntity(i)->getMaterialName());		
			

		// Nave Enterprise Galaxy
		Entity *ent3 = mSceneMgr->createEntity( "Nave_Galaxy", "Nave_Enterrpise.mesh" );        
		SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Node_Nave_Galaxy",Vector3( 0, 20, 100 ) );
		ent3->setQueryFlags(NAVES);
        node3->attachObject( ent3 );

		// Tubos.. (Para o glow serao 3 tubos)*********************
		SceneNode* pNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes->addPoint(Vector3(0,20,100));		
		mTubes->addPoint(Vector3(0,0,0));
		

		mTubes->setSceneNode(pNode);
		mTubes->createTubes("Tubo_Phaser1","StarTrek/PhaserBeam");						

		//*******************************
		SceneNode* pNode1 = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes1 = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes1->addPoint(Vector3(0,20,100));		
		mTubes1->addPoint(Vector3(0,0,0));
		

		mTubes1->setSceneNode(pNode1);
		mTubes1->createTubes("Tubo_Phaser2","cg/alpha_glow");				
		mTubes1->setRenderQueueGroup(RENDER_QUEUE_FULL_GLOW_ALPHA_GLOW); 

		//******************************
		SceneNode* pNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		SeriesOfTubes* mTubes2 = new SeriesOfTubes(mSceneMgr,16,0.25); 
 
		// Ponto da Galaxy até a BOP
		mTubes2->addPoint(Vector3(0,20,100));		
		mTubes2->addPoint(Vector3(0,0,0));
		

		mTubes2->setSceneNode(pNode2);
		mTubes2->createTubes("Tubo_Phaser3","cg/no_depth_check_glow");				
		mTubes2->setRenderQueueGroup(RENDER_QUEUE_FULL_GLOW_GLOW); 
    }

	StencilOpQueueListener * mStencilOpFrameListener;

	virtual void createFrameListener(void)
	{		
		mStencilOpFrameListener = new StencilOpQueueListener();
		mSceneMgr->addRenderQueueListener(mStencilOpFrameListener);

		mFrameListener= new ProjectiveDecalListener(mWindow, mCamera, mProjectorNode, mDecalFrustum, mSceneMgr);
        mRoot->addFrameListener(mFrameListener);

	}
};


// ----------------------------------------------------------------------------
// Main function, just boots the application object
// ----------------------------------------------------------------------------
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    SampleApp app;

    try
    {
        app.go();
    }
    catch( Exception& e )
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else

        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

Hermit
Kobold
Posts: 32
Joined: Tue Feb 27, 2007 2:07 am

Post by Hermit »

User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hermit could you show me a code snippet of how you used the billboard and avoided the problem that I described above (When the ship emiting the phaser to target C moves from point A to B the phaser should remain firing to point C)

Also it's possible to create the pulse effect that I've achieved with the stencil shader)
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Inserting Sun and Dust (Debris) Particle System
Image

Code: Select all

// Criar particulas para sol
		ParticleSystem* sunParticle = mSceneMgr->createParticleSystem("Sol", "Space/Sun");
		SceneNode* particleNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ParticleNode");
		particleNode->attachObject(sunParticle);
		particleNode->setPosition(Ogre::Vector3(0,50,100));

		// Criar particulas para debris
		ParticleSystem* DebParticle = mSceneMgr->createParticleSystem("Debris", "Space/Dust");
		SceneNode* DebparticleNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ParticleNodeDebris");
		DebparticleNode->attachObject(DebParticle);		
I´m using the wiki Moving Space Dust Effect article to keep the debris following the camera.
http://www.ogre3d.org/wiki/index.php/Mo ... ust_Effect

And the particle code I´ve found on this post (Thanks to zenic)

http://www.ogre3d.org/phpBB2/viewtopic.php?t=19122

Code: Select all

CoarseDebrisSystem
{
    quota 2000
    particle_width 0.7
    particle_height 0.7
    cull_each false
    billboard_type point
    material        StarTrek/Debris

    emitter Box
    {
        width 400
        height 400
        depth 50
        
        emission_rate 1
        velocity 0
        time_to_live 10000
    }
}
Sun particle file...

Code: Select all

Space/Sun
{
   material        Examples/Flare
   particle_width  20
   particle_height 20
   cull_each       false
   quota           100
   billboard_type  point

   // Area emitter
   emitter Ellipsoid
   {
       angle           30
       emission_rate   30
       time_to_live_min 2
       time_to_live_max 5
       direction       0 1 0
       velocity       0.001
       colour 0.15 0.1 0.0
       width           5
       height          5
       depth           5
   }


   // Afeta a cor com a distancia...
   affector ColourFader
   {
       red -0.010
       green -0.025
       blue -0.025
   }
}
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I´m finished the Space Dust and camera modes using those articles... (I really hope that I´m not buging you guys with all those screenshots and code, my intention is to help people like me that are trying to learn ogre)
http://www.ogre3d.org/wiki/index.php/Mo ... ust_Effect
http://www.ogre3d.org/wiki/index.php/3r ... m_tutorial

I´ve created a new camera class including the Space Dust feature that always face the camera. (Source included in the end of this post)
Image

I´ve posted some videos here...
http://www.vimeo.com/1547961
http://www.viddler.com/explore/leonardoaraujo/videos/1/

My problems now are....
1) Integrate those classes to the GameState framework (This is easy)
http://www.ogre3d.org/wiki/index.php/Ma ... _with_OGRE
2) Create the warp speed effect those particles get a trail effect (Someone knows how to do it?)
Image

Here is the Demo source code

Code: Select all

/*
	Exemplo de camera em terceira pessoa
*/
#include "ExampleApplication.h"

class Personagem
{
protected:
	SceneNode *mMainNode;				// Node do personagem
	SceneNode *mNodeVisao;				// Node de ponto de visao
	SceneNode *mNodeCamera;				// Node da camera
	Entity *mEntidadePersonagem;		// Entidade do personagem
	SceneManager *mGerenciadorCena;
public:		
	// Atualiza posicao do personagem
	virtual void atualiza (Real elapsedTime, OIS::Keyboard *input) = 0;
	SceneNode *pegaNodeVisao () 
	{
		return mNodeVisao;
	}
	SceneNode *pegaNodeCamera () 
	{
		return mNodeCamera;
	}
	Vector3 pegaPosicaoMundo3d () 
	{
		return mMainNode->getWorldPosition();
	}

};

class PersonagemOgre : public Personagem
{	
protected:
	String mNome;
public:
	PersonagemOgre(String name, SceneManager *sceneMgr) 
	{
			// Setup basic member references
			mNome = name;
			mGerenciadorCena = sceneMgr;

			// Setup basic node structure to handle 3rd person cameras
			mMainNode = mGerenciadorCena->getRootSceneNode ()->createChildSceneNode (mNome);			

			// Carrega entidade
			mEntidadePersonagem = mGerenciadorCena->createEntity (mNome, "Ent2.mesh");			
			mMainNode->attachObject (mEntidadePersonagem);									

			// Node do ponto de vista
			//Alvo
			mNodeVisao = mMainNode->createChildSceneNode (mNome + "_sight", Vector3 (0, 0, 0));

			// Node da camera (Onde a camera vai sempre tentar estar..)
			mNodeCamera = mMainNode->createChildSceneNode (mNome + "_camera", Vector3 (0, 20, -100));
	}
	~PersonagemOgre() 
	{
		mMainNode->detachAllObjects ();
		delete mEntidadePersonagem;
		mMainNode->removeAndDestroyAllChildren ();
		mGerenciadorCena->destroySceneNode (mNome);
	}

	// Trata movimento
	void atualiza (Real elapsedTime, OIS::Keyboard *input) 
	{
		// Frente
		if (input->isKeyDown (OIS::KC_W)) 
		{
			mMainNode->translate (mMainNode->getOrientation () * Vector3 (0, 0, 100 * elapsedTime));
		}
		// Tras
		if (input->isKeyDown (OIS::KC_S)) 
		{
			mMainNode->translate (mMainNode->getOrientation () * Vector3 (0, 0, -25 * elapsedTime));
		}
		// Esquerda
		if (input->isKeyDown (OIS::KC_LEFT)) 
		{
			//mMainNode->yaw (Radian (2 * elapsedTime));
			mMainNode->roll(Radian (-0.5 *elapsedTime));
		}

		if (input->isKeyDown (OIS::KC_A)) 
		{
			mMainNode->yaw (Radian (0.5 * elapsedTime));			
		}

		// Direita
		if (input->isKeyDown (OIS::KC_RIGHT)) 
		{
			//mMainNode->yaw (Radian (-2 * elapsedTime));
			mMainNode->roll(Radian (0.5 *elapsedTime));
		}

		// Strafe direita
		if (input->isKeyDown (OIS::KC_D)) 
		{
			mMainNode->yaw (Radian (-0.5 * elapsedTime));			
		}

		// Para cima
		if (input->isKeyDown (OIS::KC_DOWN)) 
		{
			mMainNode->pitch (Radian (-0.5 * elapsedTime));
		}

		// Para Baixo
		if (input->isKeyDown (OIS::KC_UP)) 
		{
			mMainNode->pitch (Radian (0.5 * elapsedTime));
		}
		
	}

	void setaVisibilidade (bool visible) 
	{
		mMainNode->setVisible (visible);
	}

};

class CameraExtendida
{
protected:
	SceneNode *mNodeAlvo;				// Alvo da camera
	SceneNode *mNodeCamera;				// Node da camera
	Camera *mCamera;					// Objeto da camera
	SceneManager *mSceneMgr;
	String mNomeCamera;
	bool mCameraCriadaInternamente;		// Flag para saber se a camera foi criada dentro da classe
	Real mRigidezCamera;				// Tpo de movimento
	Ogre::ParticleSystem* spaceDust;	// Sistema de particulas para lixo espacial
public:
	CameraExtendida (String name, SceneManager *sceneMgr, Camera *camera = 0, ParticleSystem *ps = 0) 
	{		
		mNomeCamera = name;
		mSceneMgr = sceneMgr;
		spaceDust = ps;

		// Cria os nodes das cameras
		mNodeCamera = mSceneMgr->getRootSceneNode ()->createChildSceneNode (mNomeCamera);
		mNodeAlvo = mSceneMgr->getRootSceneNode ()->createChildSceneNode (mNomeCamera + "_target");
		// Camera sempre ira olhar para o node do "alvo"
		mNodeCamera->setAutoTracking (true, mNodeAlvo);
		mNodeCamera->setFixedYawAxis (true); // Needed because of auto tracking		

		// Cria a camera se ela nao foi passada como parametro
		if (camera == 0) 
		{
			mCamera = mSceneMgr->createCamera (mNomeCamera);
			mCameraCriadaInternamente = true;
		}
		else 
		{
			mCamera = camera;
            mCamera->setPosition(0.0,0.0,0.0);
			mCameraCriadaInternamente = false;
		}
		// Anexa camera ao node da camera
		mNodeCamera->attachObject (mCamera);

		// Razao da rigidez (Habilidade de ficar seguindo o alvo)
		mRigidezCamera = 0.01f;
	}
	
	~CameraExtendida() 
	{
		mNodeCamera->detachAllObjects ();
		if (mCameraCriadaInternamente)
			delete mCamera;
		mSceneMgr->destroySceneNode (mNomeCamera);
		mSceneMgr->destroySceneNode (mNomeCamera + "_target");
	}

	void setaRigidezCamera (Real rigidezCamera) 
	{
		mRigidezCamera = rigidezCamera;
	}

	Real pegaRigidezCamera () 
	{
		return mRigidezCamera;
	}

	Vector3 pegaPosicaoCamera () 
	{
		return mNodeCamera->getPosition ();
	}

	// Atualiza posicao
	void atualizaInstantaneamente(Vector3 cameraPosition, Vector3 targetPosition) 
	{
		mNodeCamera->setPosition (cameraPosition);
		mNodeAlvo->setPosition (targetPosition);
	}
	
	void atualiza (Real elapsedTime, Vector3 cameraPosition, Vector3 targetPosition) 
	{
		// Handle movement
		Vector3 displacement;
		displacement = (cameraPosition - mNodeCamera->getPosition ()) * mRigidezCamera;
		mNodeCamera->translate (displacement);
		displacement = (targetPosition - mNodeAlvo->getPosition ()) * mRigidezCamera;
		mNodeAlvo->translate (displacement);

		if (spaceDust)
		{
			atualiza_particulas(elapsedTime);
		}		
	}

	void atualiza_particulas(Real elapsedTime)
	{
		const float maxDist  = 250.0; //250.0
		const float mirrorDist = maxDist*0.99;
		const float dimFactor = 0.00002;//0.8*0.005*0.005;   
		const float maxDist2 = maxDist*maxDist;
				
		const Vector3& camPos = mCamera->getWorldPosition();
 	    const float twiceMaxDist = 2 * maxDist;

		// Pega Iterador para todas as particulas emitidas
		ParticleIterator pit = spaceDust->_getIterator();
		   
		while (!pit.end())
		{
			Particle* particle = pit.getNext();
			// Pega posicao no mundo 3d da particula
			Vector3& pos = particle->position;

			// Mantem a particula viva por um bom tempo
			particle->timeToLive = 999999.0f;

			/* 
				Posiciona as particulas perto da camera, continua movendo-as até uma certa
				distancia
			*/
			while (pos.x - camPos.x > maxDist)
				pos.x -= twiceMaxDist;
			while (pos.x - camPos.x < -maxDist)
				pos.x += twiceMaxDist;
			while (pos.y - camPos.y > maxDist)
				pos.y -= twiceMaxDist;
			while (pos.y - camPos.y < -maxDist)
				pos.y += twiceMaxDist;
			while (pos.z - camPos.z > maxDist)
				pos.z -= twiceMaxDist;
			while (pos.z - camPos.z < -maxDist)
				pos.z += twiceMaxDist;

		    // Vai degradando o tamanho da particula com a distancia
			Vector3 pDir = pos-camPos;
		    float dist = pDir.squaredLength();
		    float dim = dist*dimFactor;
		    particle->setDimensions(dim, dim);
		     
		}          	
	}

};

class SampleListener : public ExampleFrameListener
{
protected:
	// Referencias para o personagem e a camera
	Personagem *mChar;
	CameraExtendida *mExCamera;

	// Modo da camera (Primeira pessoa, terceira pessoa(chase e fixa)
	unsigned int mMode;

public:
	SampleListener(RenderWindow* win, Camera* cam): ExampleFrameListener(win, cam)
	{
		mChar = 0;
		mExCamera = 0;
		mMode = 0;
	}

	void setCharacter (Personagem *character) 
	{
		mChar = character;
	}

	void setExtendedCamera (CameraExtendida *cam) 
	{
		mExCamera = cam;
	}

	bool frameStarted(const FrameEvent& evt)
	{
		mKeyboard->capture();

		if (mChar) {
			mChar->atualiza (evt.timeSinceLastFrame, mKeyboard);

			if (mExCamera) 
			{
				switch (mMode) 
				{
					case 0: // 3rd person chase
						mExCamera->atualiza(evt.timeSinceLastFrame, mChar->pegaNodeCamera ()->getWorldPosition (), mChar->pegaNodeVisao()->getWorldPosition ());
						break;
					case 1: // 3rd person fixed
						mExCamera->atualiza(evt.timeSinceLastFrame, Vector3 (0, 200, 0), mChar->pegaNodeVisao()->getWorldPosition ());
						break;
					case 2: // 1st person
						mExCamera->atualiza (evt.timeSinceLastFrame, mChar->pegaPosicaoMundo3d (), mChar->pegaNodeVisao()->getWorldPosition ());
						break;
				}
			}
		}

		// Seta Modo da camera com F1,F2,F3

		// Terceira pessoa (Chase)
		if (mKeyboard->isKeyDown (OIS::KC_F1)) 
		{
			mMode = 0;
			if (mChar)
				static_cast<PersonagemOgre *>(mChar)->setaVisibilidade (true);
			if (mExCamera) 
			{
				if (mChar)
					mExCamera->atualizaInstantaneamente(mChar->pegaNodeCamera()->getWorldPosition (), mChar->pegaNodeVisao()->getWorldPosition());
				mExCamera->setaRigidezCamera (0.40f);
			}
 		}
		// Terceira pessoa (Fixa)
		if (mKeyboard->isKeyDown (OIS::KC_F2)) 
		{
			mMode = 1;
			if (mChar)
				static_cast<PersonagemOgre *>(mChar)->setaVisibilidade (true);
			if (mExCamera) 
			{
				if (mChar)
					mExCamera->atualizaInstantaneamente(Vector3 (0, 200, 0), mChar->pegaNodeVisao()->getWorldPosition ());
				mExCamera->setaRigidezCamera (0.5f);
			}
		}
		// Primeira pessoa
		if (mKeyboard->isKeyDown (OIS::KC_F3))  
		{
			mMode = 2;
			if (mChar)
				static_cast<PersonagemOgre *>(mChar)->setaVisibilidade (false);
			if (mExCamera) 
			{
				if (mChar)
					mExCamera->atualizaInstantaneamente(mChar->pegaPosicaoMundo3d(), mChar->pegaNodeVisao()->getWorldPosition());
				mExCamera->setaRigidezCamera (1.0f);
			}
		}

		// Sai se pressionar o ESC
		if(mKeyboard->isKeyDown (OIS::KC_ESCAPE))
			return false;

		return true;
	}
};


class TutorialApplication : public ExampleApplication
{
protected:
public:
    TutorialApplication()
    {
    }

    ~TutorialApplication() 
    {
    }
protected:
    // Create scene é chamado automaticamente
	void createScene(void)
    {
		// Poe um SkyBox
		mSceneMgr->setSkyBox(true, "StarTrek/NebulaTeste");

		// Set Luz ambiente
		mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
		
		// Cria luz
		Light* l = mSceneMgr->createLight("MainLight");		
		l->setType(Light::LT_DIRECTIONAL);
		l->setDirection(-0.5, -0.5, 0);

		// Seta posicao da camera
		mCamera->setPosition (0, 0, 0);	

		// Preenche a cena com alguns robos
		SceneNode *razorNode;
		Entity *razorEntity;
		for (unsigned int i = 0; i < 30; ++i) {
			razorNode = mSceneMgr->getRootSceneNode ()->createChildSceneNode (StringConverter::toString (i), Vector3 (Math::RangeRandom (-1000, 1000), 0, Math::RangeRandom (-1000, 1000)));
			razorEntity = mSceneMgr->createEntity (StringConverter::toString (i), "BirdOfPrey.mesh");
			razorNode->attachObject (razorEntity);
		}

		// Particulas para poeira espacial
		ParticleSystem* DebParticle = mSceneMgr->createParticleSystem("Debris", "Space/Dust");//CoarseDebrisSystem Space/Dust FineDebrisSystem
		SceneNode* DebparticleNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ParticleNodeDebris");
		DebparticleNode->attachObject(DebParticle);

		// Personagem Principal
		PersonagemOgre *ogre = new PersonagemOgre ("Ogre 1", mSceneMgr);
		CameraExtendida *exCamera = new CameraExtendida ("Extended Camera", mSceneMgr, mCamera,DebParticle);

		// FrameListener para tratar atualizacao da camera e do Personagem
		mFrameListener = new SampleListener (mWindow, mCamera);
		static_cast<SampleListener *>(mFrameListener)->setCharacter (ogre);
		static_cast<SampleListener *>(mFrameListener)->setExtendedCamera (exCamera);		
    }

	void createFrameListener(void)
	{
		mRoot->addFrameListener(mFrameListener);
	}

};

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
    // Objeto principal da classe de wrapper pro ogre
    TutorialApplication app;

	try 
	{
		app.go();
	} 
	catch( Exception& e )
	{
		MessageBox( NULL, (LPCTSTR)e.what(), (LPCTSTR)"An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
	}

    return 0;
}
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I'm using Raknet to create a multiplayer enviroment. As soon as I fix some bugs I will put the code in Subversion
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Post by Moohasha »

Dude, trekmeshes?!?! How on earth did I never find that?! That's freakin awesome!
Good work with the space game, it looks really nice. I was working on a space game not too long ago. I'll have to bookmark this thread and come back to it once I get back into my game.

Thanks for the posts!
Black holes are where God divided by 0
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Thanks Moohasha I'm actually working now on GUI (Using MyGUI), my current goals now are GUI and Sound (With OpenAL) as I keep going implementing features I post the code here ... I will also submit all code in SVN to share with others....

Code for using MyGUI

Code: Select all

void EstadoTelaConexao::entra(Ogre::RenderWindow* win, OIS::Mouse*  mouse, OIS::Keyboard* keyboard,  GerenciadorJogo* gerenciadorJogo)
5 	{
6 	        mMouse=mouse;
7 	        mTeclado=keyboard;
8 	        mJanela=win;
9 	
10 	        mMouse->setEventCallback(this);
11 	    mTeclado->setEventCallback(this);
12 	
13 	        // Pega objeto root do Ogre
14 	        mRoot = Ogre::Root::getSingletonPtr();
15 	
16 	        mGerenciadorCena = mRoot->createSceneManager(Ogre::ST_GENERIC,"TerrainSceneManager");
17 	
18 	        // Set Luz ambiente
19 	        mGerenciadorCena->setAmbientLight(Ogre::ColourValue(0.2, 0.2, 0.2));
20 	        // Cria luz
21 	        Ogre::Light* luz_direcional = mGerenciadorCena->createLight("Luz Direcional");         
22 	        luz_direcional->setType(Ogre::Light::LT_DIRECTIONAL);
23 	        luz_direcional->setDirection(-0.5, -0.5, 0);
24 	
25 	        mCamera = mGerenciadorCena->createCamera("PlayCamera");
26 	        mCamera->setPosition(0,0,0);
27 	        mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera,1);
28 	        mCamera->setAspectRatio(Ogre::Real(mViewport->getActualWidth()) / Ogre::Real(mViewport->getActualHeight()));
29 	        mCamera->setNearClipDistance(0.05);
30 	
31 	        mGerenciadorCena->setSkyBox(true, "StarTrek/NebulaTeste");
32 	
33 	        // Cria instancia do MyGui
34 	        mGUI = new MyGUI::Gui();       
35 	        mGUI->initialise(mJanela);     
36 	        /*
37 	                Carrega Layout criado pelo Layout editor (Este arquivo esta no diretorio MyGUI_Media
38 	                este diretorio deve estar configurado no arquivo Resource.cfg, o arquivo ConexaoClient.layout
39 	                foi criado pela ferramenta LayOutEditor do MyGui
40 	                
41 	                // Poe manualmente o widget
42 	                MyGUI::ButtonPtr button = mGUI->createWidget<MyGUI::Button>("Button", 10, 10, 300, 26, MyGUI::ALIGN_DEFAULT, "Main");
43 	                button->setCaption("exit");
44 	        */
45 	        MyGUI::LayoutManager::getInstance().load("ConexaoClient.layout");       
46 	        mGUI->setSceneManager(mGerenciadorCena);
47 	
48 	
49 	
50 	        // Poe o mouse para poder mapear toda a tela
51 	        int mWidth,mHeight;
52 	        mWidth = mJanela->getWidth();
53 	        mHeight = mJanela->getHeight();
54 	        if (mMouse)
55 	        {
56 	            const OIS::MouseState &ms = mMouse->getMouseState();
57 	            ms.width = (int)mWidth;
58 	            ms.height = (int)mHeight;
59 	        }
60 	
61 	
62 	}
The .layout file ....

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
    <Widget type="Widget" skin="Panel" position="48 80 256 128" layer="Back">
        <Widget type="Edit" skin="Edit" position="112 16 128 32" name="EdNomeUsuario"/>
        <Widget type="StaticText" skin="StaticText" position="8 16 96 24" name="LbNomeUsuario">
            <Property key="Widget_Caption" value="Nome usuario"/>
            <Property key="Widget_InheritsAlpha" value="true"/>
        </Widget>
        <Widget type="StaticText" skin="StaticText" position="8 48 96 24">
            <Property key="Widget_Caption" value="IP Servidor"/>
        </Widget>
        <Widget type="Edit" skin="Edit" position="112 48 128 32"/>
        <Widget type="Button" skin="Button" position="80 88 96 32">
            <Property key="Widget_Caption" value="Conectar"/>
        </Widget>
    </Widget>
</MyGUI>

Result
Image


If you can wait I will post those Trek meshes converted in .mesh format
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I've finally solved the phaser (Using quads) problem... I've posted the code here... http://www.ogre3d.org/phpBB2/viewtopic.php?t=44195

Old Phaser...
Image

New Phaser...
Image

I will try to SVN the complete code today
Image
Engineering tutorials (Robotics, Electronics, Software, Mechanics)
http://www.tutoriaisengenharia.com
User avatar
Nauk
Gnoll
Posts: 653
Joined: Thu May 11, 2006 9:12 pm
Location: Bavaria
x 36

Post by Nauk »

looks very good! thanks for sharing :)
User avatar
leonardoaraujo.santos
Greenskin
Posts: 141
Joined: Fri Apr 27, 2007 6:00 pm
Location: Brazil

Post by leonardoaraujo.santos »

Hi guys I've finally organized the code in Source forge SVN
I hope that this could help people trying to write his own games (Multiplayer) a place to start (And to give back to the Ogre comunity the help that I've received)
Those items are currently been used...
1) Raknet (Sever and client)
2) MyGUI
3) OgreAL
4) Wiki Ogre GameState class
5) Doxygen Documentation

I'm using the last Eihort revision (I will wait a little until port to Shoggoth)

Any question that I can provide
SVN:https://morradesgame.svn.sourceforge.ne ... jetoClient
Image
Engineering tutorials (Robotics, Electronics, Software, Mechanics)
http://www.tutoriaisengenharia.com