StimulusPresentation ModelStimuli 3DAPI Scene Programming

Forum for software developers to discuss BCI2000 software development
Locked
ripspinner
Posts: 1
Joined: 03 Mar 2011, 16:01

StimulusPresentation ModelStimuli 3DAPI Scene Programming

Post by ripspinner » 03 Mar 2011, 16:12

I am attempting to implement a new stimuli called ModelStimuli which is a 3DAPI Scene() that has a model3D() as a member. I used much of the code from the feedback3d scene, the main difference is my Stimuli is a scene as well as a Visualstimulus.

At this point I can tell the Scene instantiates because the GraphDisplay is grabbed by the scene. The stimulus is treated like anyother stimulus in StimulusPresentationTask the problem is it doesn't render the 3ds model or boundary cuboid when the stimuli are run. I can't figure out why.

Here is the code (in its entirety) note some of it may be a little frayed attempt at get it to work , anyhow ModelStimulus

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// $Id: ImageStimulus.cpp 3099 2011-02-10 16:08:47Z mellinger $
// Author: juergen.mellinger@uni-tuebingen.de
// Description: A stimulus consisting of an image.
//
// $BEGIN_BCI2000_LICENSE$
// 
// This file is part of BCI2000, a platform for real-time bio-signal research.
// [ Copyright (C) 2000-2011: BCI2000 team and many external contributors ]
// 
// BCI2000 is free software: you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
// 
// BCI2000 is distributed in the hope that it will be useful, but
//                         WITHOUT ANY WARRANTY
// - without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License along with
// this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// $END_BCI2000_LICENSE$
////////////////////////////////////////////////////////////////////////////////
#include "PCHIncludes.h"
#pragma hdrstop


#include "ModelStimulus.h"
#include "Environment.h"
#include "BCIDirectory.h"
#include "BCIError.h"

#ifdef __BORLANDC__
# include <VCL.h>
#else // __BORLANDC__
# include <QPainter>
#endif // __BORLANDC__

using namespace std;
using namespace GUI;

ModelStimulus::ModelStimulus( GraphDisplay& display )
: Scene(display),
  mRenderingMode( RenderingMode::Opaque ),
  mpModel ( NULL ),
  mpBoundary (NULL )
 
{
		
}

ModelStimulus::~ModelStimulus()
{
  ClearObjects();
  //delete mpImageBufferNormal;
  //delete mpImageBufferHighlighted;
}

ModelStimulus & ModelStimulus::Initialize()
{
  ClearObjects();
 
	
  //mpScene = new Scene( mpDisplay );
  mpModel = new model3D(*this , BCIDirectory::AbsolutePath(mpFile));
  mpBoundary = new invertedCuboid( *this );
  // The drawingOrder property allows correct z ordering in the absence of depth
  // testing.
  mpBoundary->setDrawingOrder( -2 );
  mpModel->setDrawingOrder( -1 );

  this->CameraAndLight().setQuality( 1 );

  enum { x, y, z, dx, dy, dz };
  ParamRef CameraPos = Parameter( "CameraPos" );
  this->CameraAndLight().setCamViewPoint(
    CameraPos( x ),
    CameraPos( y ),
    CameraPos( z )
  );
  ParamRef CameraAim = Parameter( "CameraAim" );
  this->CameraAndLight().setCamAim(
    CameraAim( x ),
    CameraAim( y ),
    CameraAim( z )
  );
  this->CameraAndLight().setCamUp( 0, 1, 0 );

  enum { flat = 0, wideAngle, narrowAngle };
  switch( int( Parameter( "CameraProjection" ) ) )
  {
    case flat:
      this->CameraAndLight().setFieldOfView( 0 );
      break;
    case wideAngle:
      this->CameraAndLight().setFieldOfView( 60 );
      break;
    case narrowAngle:
      this->CameraAndLight().setFieldOfView( 35 );
      break;
  }
  ParamRef LightSourcePos = Parameter( "LightSourcePos" );
   this->CameraAndLight().setLight(
    LightSourcePos( x ),
    LightSourcePos( y ),
    LightSourcePos( z )
  );
  RGBColor lightSourceColor = RGBColor( Parameter( "LightSourceColor" ) );
  this->CameraAndLight().setLightColor(
    lightSourceColor.R()/255.,
    lightSourceColor.G()/255.,
    lightSourceColor.B()/255.
  );
  this->CameraAndLight().setLightBri( 0.8f );
  this->CameraAndLight().setAmbLightBri( 0.2f );

  bool showTextures = ( Parameter( "RenderingQuality" ) > 0 );

  mpBoundary->setOrigin( 50, 50, 50 );
  mpBoundary->setDimensions( 100, 100, 100 );
  mpBoundary->setFaceVisible( 0, false );
  mpBoundary->setBrightness( 1 );
  RGBColor boundaryColor = RGBColor( Parameter( "WorkspaceBoundaryColor" ) );
  mpBoundary->setColor(
    boundaryColor.R()/255.,
    boundaryColor.G()/255.,
    boundaryColor.B()/255.
  );
  mpBoundary->setVisible( boundaryColor != RGBColor( RGBColor::NullColor ) );
  string boundaryTexture;
  if( showTextures )
    boundaryTexture = ( string )Parameter( "WorkspaceBoundaryTexture" );
  if( !boundaryTexture.empty() )
    boundaryTexture = BCIDirectory::AbsolutePath( boundaryTexture );
  mpBoundary->setTexture( boundaryTexture );
  this->CameraAndLight().setBoundingBox( *mpBoundary );

  mpModel->setOrigin( 0, 0, 0 );
  //mpModel->->setRadius( Parameter( "CursorWidth" ) / 2 );
  ParamRef ModelPos = Parameter( "CursorPos" );
  SetModelPosition( ModelPos( x ), ModelPos( y ), ModelPos( z ) );
  mpModel->setBrightness( 1 );
  string ModelTexture;
  if( showTextures )
    ModelTexture = ( string )Parameter( "CursorTexture" );
  if( !ModelTexture.empty() )
    ModelTexture = BCIDirectory::AbsolutePath( ModelTexture );
  mpModel->setTexture( ModelTexture );
  mpModel->setVisible( false );

 string targetTexture;
  if( showTextures )
    targetTexture = ( string )Parameter( "TargetTexture" );
  if( !targetTexture.empty() )
    targetTexture = BCIDirectory::AbsolutePath( targetTexture );
  ParamRef Targets = Parameter( "Targets" );
  for( int i = 0; i < Parameter( "NumberTargets" ); ++i )
  {
    cuboid* pTarget = new cuboid( *this,
      Targets( i, x ),  Targets( i, y ),  Targets( i, z ),
      Targets( i, dx ), Targets( i, dy ), Targets( i, dz )
    );
    pTarget->setBrightness( 1 );
    pTarget->setTexture( targetTexture );
    pTarget->setVisible( false );
    mTargets.push_back( pTarget );
  }

  
  this->SetBitDepth( Parameter( "WindowBitDepth" ) );
  this->SetDoubleBuffering( true );
  this->SetDisableVsync( true );
  GUI::Rect rect = { 0, 0, 1, 1 };
  this->SetDisplayRect( rect );
 
  return *this;
}



float
ModelStimulus::ModelXPosition() const
{
  return mpModel->getOrigin().x;
}

float
ModelStimulus::ModelYPosition() const
{
  return mpModel->getOrigin().y;
}

float
ModelStimulus::ModelZPosition() const
{
  return mpModel->getOrigin().z;
}

ModelStimulus&
ModelStimulus::SetModelPosition( float inX, float inY, float inZ )
{
  mpModel->setOrigin( inX, inY, inZ );
  this->Invalidate();
  return *this;
}

ModelStimulus&
ModelStimulus::SetModelVisible( bool inVisible )
{
	bciout << "ModelStimulus::In SetModelVisible() function " << endl;
  mpBoundary->setVisible(inVisible);	
  mpModel->setVisible( inVisible );
  return *this;
}

ModelStimulus&
ModelStimulus::SetModelColor( RGBColor inColor )
{
  mpModel->setColor( inColor.R()/255., inColor.G()/255., inColor.B()/255. );
  return *this;
}


void
ModelStimulus::ClearObjects()
{
  mpModel = NULL;
  mpBoundary = NULL;
  mTargets.clear();
}


ModelStimulus& ModelStimulus::SetFile( const string& inName )
{
  bool errorOccurred = false;

  // Attempt to load the image
#ifdef __BORLANDC__

  delete mpImage;
  mpImage = new TPicture;
  try
  {
    mpImage->LoadFromFile( BCIDirectory::AbsolutePath( inName ).c_str() );
  }
  catch( EInOutError& )
  {
    errorOccurred = true;
  }
  catch( EFOpenError& )
  {
    errorOccurred = true;
  }
  catch( EInvalidGraphic& )
  {
    errorOccurred = true;
  }

#else // __BORLANDC__
  
  delete mpModel;
  mpModel = NULL;
  mpFile=inName;
  bciout << "ModelStimulus SetFile to " << mpFile << endl;
  this->Initialize();
  mpBoundary->setVisible(true);
  mpModel->setVisible(true);
  
  if (mpModel == NULL)
	  errorOccurred = true;
                     
#endif // __BORLANDC__

  // An error occurred while loading the image
  if( errorOccurred )
  {
    bcierr << "Could not load model from file \"" << inName << "\"" << endl;
    delete mpModel;
    mpModel = NULL;
    mpFile = "";
  }
 
  Change();
  return *this;
}

const string&
ModelStimulus::File() const
{
  return mpFile;
}

ModelStimulus&
ModelStimulus::SetRenderingMode( int inMode )
{
  mRenderingMode = inMode;
  Invalidate();
  return *this;
}

int
ModelStimulus::RenderingMode() const
{
  return mRenderingMode;
}

void
ModelStimulus::OnPaint( const DrawContext& inDC )
{
  // Display the model 
   mpBoundary->setVisible(true);
	mpModel->setVisible(true);
	mpModel->render();
	mpBoundary->render();
   bciout << "In ModelStimulus::OnPaint set mpModel visible" << endl;
#ifdef __BORLANDC__

  Graphics::TBitmap* pBuffer = BeingPresented() ?
                               mpImageBufferHighlighted :
                               mpImageBufferNormal;
  if( pBuffer != NULL )
  {
    TCanvas* pCanvas = new TCanvas;
    try
    {
      pBuffer->Transparent = ( mRenderingMode == GUI::RenderingMode::Transparent );
      pBuffer->TransparentMode = tmAuto;
      pCanvas->Handle = ( HDC )inDC.handle;
      pCanvas->Draw( inDC.rect.left, inDC.rect.top, pBuffer );
    }
    __finally
    {
      delete pCanvas;
    }
  }

#else // __BORLANDC__

	
#endif // __BORLANDC__
}


void
ModelStimulus::OnChange( DrawContext& ioDC )
{
  //delete mpModelBufferNormal;
  //mpImageBufferNormal = NULL;
  //delete mpImageBufferHighlighted;
  //mpImageBufferHighlighted = NULL;
  
#ifdef __BORLANDC__

  if( mpImage != NULL )
  {
    int width = ioDC.rect.right - ioDC.rect.left,
        height = ioDC.rect.bottom - ioDC.rect.top,
        hCenter = ( ioDC.rect.left + ioDC.rect.right ) / 2,
        vCenter = ( ioDC.rect.bottom + ioDC.rect.top ) / 2;

    switch( AspectRatioMode() )
    {
      case GUI::AspectRatioModes::AdjustWidth:
        width = ( mpImage->Width * height ) / mpImage->Height;
        ioDC.rect.left = hCenter - width / 2;
        ioDC.rect.right = ioDC.rect.left + width;
        break;

      case GUI::AspectRatioModes::AdjustHeight:
        height = ( mpImage->Height * width ) / mpImage->Width;
        ioDC.rect.top = vCenter - height / 2;
        ioDC.rect.bottom = ioDC.rect.top + height;
        break;

      case GUI::AspectRatioModes::AdjustBoth:
        width = mpImage->Width;
        height = mpImage->Height;
        ioDC.rect.left = hCenter - width / 2;
        ioDC.rect.right = ioDC.rect.left + width;
        ioDC.rect.top = vCenter - height / 2;
        ioDC.rect.bottom = ioDC.rect.top + height;
        break;

      case GUI::AspectRatioModes::AdjustNone:
      default:
        ;
    }
    TRect bufRect( 0, 0, width, height );
    mpImageBufferNormal = new Graphics::TBitmap;
    mpImageBufferNormal->Width = width;
    mpImageBufferNormal->Height = height;
    mpImageBufferNormal->Canvas->StretchDraw( bufRect, mpImage->Graphic );

    mpImageBufferHighlighted = new Graphics::TBitmap;
    mpImageBufferHighlighted->Assign( mpImageBufferNormal );

    TCanvas* pCanvas = mpImageBufferHighlighted->Canvas;
    switch( PresentationMode() )
    {
      case ShowHide:
        delete mpImageBufferNormal;
        mpImageBufferNormal = NULL;
        break;

      case Intensify:
        for( int i = 0; i < bufRect.Width(); ++i )
          for( int j = 0; j < bufRect.Height(); ++j )
          {
            RGBColor c = RGBColor::FromWinColor( pCanvas->Pixels[ i ][ j ] );
            c *= 1 / DimFactor();
            pCanvas->Pixels[ i ][ j ] = TColor( c.ToWinColor() );
          }
        break;

      case Grayscale:
        mpImageBufferHighlighted->Monochrome = true;
        break;

      case Invert:
        for( int i = 0; i < bufRect.Width(); ++i )
          for( int j = 0; j < bufRect.Height(); ++j )
            pCanvas->Pixels[ i ][ j ] = TColor( ~pCanvas->Pixels[ i ][ j ] );
        break;

      case Dim:
        for( int i = 0; i < bufRect.Width(); ++i )
          for( int j = 0; j < bufRect.Height(); ++j )
          {
            RGBColor c = RGBColor::FromWinColor( pCanvas->Pixels[ i ][ j ] );
            c *= DimFactor();
            pCanvas->Pixels[ i ][ j ] = TColor( c.ToWinColor() );
          }
        break;
    }
  }

#else // __BORLANDC__

  if( mpModel != NULL )
  {
    int modelWidth = static_cast<int>( ioDC.rect.right - ioDC.rect.left ),
        modelHeight = static_cast<int>( ioDC.rect.bottom - ioDC.rect.top ),
        hCenter = static_cast<int>( ( ioDC.rect.left + ioDC.rect.right ) / 2 ),
        vCenter = static_cast<int>( ( ioDC.rect.bottom + ioDC.rect.top ) / 2 );

    switch( AspectRatioMode() )
    {
      case GUI::AspectRatioModes::AdjustWidth:
        /*
		  modelWidth = ( mpModel->width() * modelHeight ) / mpModel->height();
        ioDC.rect.left = hCenter - modelWidth / 2;
        ioDC.rect.right = ioDC.rect.left + modelWidth;
        */
		break;

      case GUI::AspectRatioModes::AdjustHeight:
        /*
		  imageHeight = ( mpImage->modelheight() * modelWidth ) / mpModel->width();
        ioDC.rect.top = vCenter - modelHeight / 2;
        ioDC.rect.bottom = ioDC.rect.top + modelHeight;
        */
		break;

      case GUI::AspectRatioModes::AdjustBoth:
        /*
		ioDC.rect.left = hCenter - mpModel->width() / 2;
        ioDC.rect.right = ioDC.rect.left + mpModel->width();
        ioDC.rect.top = vCenter - mpModel->height() / 2;
        ioDC.rect.bottom = ioDC.rect.top + mpModel->height();
        */
		break;

      case GUI::AspectRatioModes::AdjustNone:
      default:
        ;
    }
    static bool toggelshow = false;
    switch( PresentationMode() )
    {
      case ShowHide:
        //delete mpModImageBufferNormal;

        //mpImageBufferNormal = NULL;
		mpModel->setVisible(!toggelshow);	  
		  break;

      case Intensify:
        break;

      case Grayscale:
        break;

      case Invert:
        break;

      case Dim:
         break;
  
	}

#endif // __BORLANDC__

  GraphObject::OnChange( ioDC );
}

;

}

I also updated the code in presentation task. Really it's kind of like a mashup, not much original here.

mellinger
Posts: 1065
Joined: 12 Feb 2003, 11:06

Re: StimulusPresentation ModelStimuli 3DAPI Scene Programmin

Post by mellinger » 10 Mar 2011, 09:11

Hi,

your OnPaint() and OnChange() handlers should read:

Code: Select all

void
ModelStimulus::OnPaint( const DrawContext& inDC )
{
  if( BeingPresented() )
    Scene::OnPaint( inDC );
}

void
ModelStimulus::OnChange( const DrawContext& inDC )
{
  Scene::OnChange( inDC );
}
This should display the contents of the scene when the stimulus object is drawn.

Juergen

Locked

Who is online

Users browsing this forum: No registered users and 1 guest