Class ViewExp

3DS Max Plug-In SDK

Class ViewExp

See Also: List of Snap Flags, Class Ray, Class Point3, Class IPoint2, Class Matrix3, Class ModContext, Class HitData, Class GraphicsWindow, Class INode.

class ViewExp : public InterfaceServer

Description:

This class provides methods to access properties of the viewport, convert points between viewport and world coordinates, snap points and lengths, etc. Many methods associated with hit testing are also here. All the methods of this class are implemented by the system.

Method Groups:

The hyperlinks below jump to the start of groups of related methods within the class:

Screen Space - World Space Conversion

Osnap Related Methods

Perspective/Camera View Properties

Snapping

Access to Viewport Properties

Node Level Hit Testing

Sub-Object Level Hit Testing

Controller Gizmo Hit Testing

AutoGrid Related Methods

Methods:

Screen Space - World Space Conversion

Prototype:

virtual float NonScalingObjectSize()=0;

Remarks:

The value returned from this method may be used as a scale factor that will counteract the viewport zoom. For example, lights, cameras, and tape helper objects use this factor so the size of the node in the scene remains constant when the viewport is zoomed in and out.

This value is affected by the 'Non-Scaling Object Size' spinner in the Viewport Preferences dialog, so the user has some control over this as well.

Sample Code:

This sample is from \MAXSDK\SAMPLES\OBJECTS\TAPEHELP.CPP. The computed matrix is used in several places like displaying, snapping, hit testing, etc.

void TapeHelpObject::GetMat(TimeValue t, INode* inode,

 ViewExp* vpt, Matrix3& tm)

 {

 tm = inode->GetObjectTM(t);

 tm.NoScale();

 float scaleFactor = vpt->NonScalingObjectSize() *

  vpt->GetVPWorldWidth(tm.GetTrans())/(float)360.0;

 tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));

 }

Prototype:

virtual Point3 GetPointOnCP(const IPoint2 &ps)=0;

Remarks:

Returns a point in world space on the current construction plane based on the specified screen coordinate.

Parameters:

const IPoint2 &ps

The 2D screen point to convert to a 3D world space coordinate.

Return Value:

The world space coordinate on the current construction plane.

Prototype:

virtual float GetCPDisp(const Point3 base, const Point3& dir, const IPoint2& sp1, const IPoint2& sp2 )=0;

Remarks:

This method returns a length in world space given a start screen point, an end screen point, a base point and a direction vector. For example, when creating a cylinder, the user clicks the mouse down to define the center point of the cylinder (base), then drags out a radius. They then drag out a height for the cylinder. This method is used to return intermediate and final heights for the cylinder based on the initial base point, the direction vector (the Z axis), the start mouse point, and the current point the user is interactively adjusting.

Parameters:

const Point3 base

Base point in object space.

const Point3& dir

Direction vector in object space.

const IPoint2& sp1

Screen start point. This is the point where the user clicked down with the mouse.

const IPoint2& sp2

Screen end point. This is the point where the user let up the mouse.

Return Value:

The length in world space based on the screen points and their projection onto the direction vector.

Sample Code:

float h = vpt->SnapLength(vpt->GetCPDisp(p[1],Point3(0,0,1),sp1,m));

From \MAXSDK\SAMPLES\OBJECTS\CYL.CPP in CylinderObjCreateCallBack::proc

Prototype:

virtual Point3 MapScreenToView( IPoint2& sp, float depth )=0;

Remarks:

Given a point on the screen (in window coordinates), and a depth in view coordinates, this method maps the point into view coordinates. This is just a scaling operation for parallel projections, but involves a divide by Z for perspective projections.

Parameters:

IPoint2& sp

Point in window coordinates.

float depth

Depth in view coordinates.

Return Value:

Point in view coordinates.

Sample Code:

Point3 p0 = vpt->MapScreenToView(mBase,GetPerspMouseSpeed());

Prototype:

virtual void MapScreenToWorldRay(float sx, float sy, Ray& ray)=0;

Remarks:

Creates a Ray in world space passing through the specified pixel directed toward the scene in the direction of view.

Parameters:

float sx

The x screen coordinate.

float sy

The y screen coordinate.

Ray& ray

The Ray in world space. See Class Ray.

Prototype:

virtual void GetAffineTM(Matrix3& tm)=0;

Remarks:

This method retrieves the affineTM which transforms from World coordinates to View coordinates. See the sample code below for an example of its use.

Parameters:

Matrix3& tm

The matrix to hold the affine TM.

Sample Code:

// This routine returns the view direction from the active viewport.

Point3 Utility::GetViewDirection() {

 Matrix3 aTM, coordSysTM;

 ViewExp *ve = ip->GetActiveViewport();

 // The affine TM transforms from world coords to view coords

 // so we need the inverse of this matrix

 ve->GetAffineTM(aTM);

 coordSysTM = Inverse(aTM);

 // The Z axis of this matrix is the view direction.

 Point3 viewDir = coordSysTM.GetRow(2);

 ip->ReleaseViewport(ve);

 return viewDir;

}

Note: You can also get the view position from this matrix. For example, in the above code, the statement:

Point3 viewPt = coordSysTM.GetRow(3);

gets the point in space the view is taken from.

Prototype:

virtual BOOL SetAffineTM(const Matrix3& m)=0;

Remarks:

This method is available in release 2.0 and later only.

This method sets the viewport affine transformation and returns TRUE if the view is a user view (isometric or perspective). If the view is not a user view then the transformation is not changed and the method returns FALSE. See SetViewUser() below.

Parameters:

const Matrix3& m

The transformation matrix to set.

Prototype:

virtual float GetScreenScaleFactor(const Point3 worldPoint)=0;

Remarks:

Returns the screen scale factor for a point given in world coordinates. This factor gives the width in world-space units at the point's distance of the viewport.

Parameters:

const Point3 worldPoint

The point in world coordinates.

Return Value:

The screen scale factor in world space units.

Prototype:

virtual float GetVPWorldWidth(const Point3 wPoint)=0;

Remarks:

Returns the viewport screen width factor in world space at a point in world space.

Parameters:

const Point3 wPoint

The point in world space.

Return Value:

The viewport screen width factor in world space.

Prototype:

virtual Point3 MapCPToWorld(const Point3 cpPoint)=0;

Remarks:

Given a point on the construction plane this method returns the corresponding world space point. For example, if you use GetPointOnCP() to convert a screen coordinate to a point on the construction plane, you could then call this method to convert that point on the construction plane to a world space point.

Parameters:

const Point3 cpPoint

The point on the construction plane.

Return Value:

The world space point.

AutoGrid Related Methods

Prototype:

virtual void TrackImplicitGrid(IPoint2 m, Matrix3* mat = NULL, ULONG hitTestFlags = 0)=0;

Remarks:

This method is available in release 3.0 and later only.

If AutoGrid is enabled, this method determines a grid coordinate system by casting a ray into the scene through the screen coordinate m, obtaining a surface normal from the closest node , and using the "arbitrary axis algorithm" to orient the xy axes. You can get this coordinate system back by passing in a pointer to a matrix. A tripod is displayed in the viewports showing the orientation.

Parameters:

IPoint2 m

The 2D screen point that the user clicked on.

Matrix3* mat = NULL

The implicit grid coordinate system matrix can be retrieved by passing a pointer to a matrix here.

ULONG hitTestFlags = 0

This parameter is available in release 4.0 and later only.

See Hit Test Flags.

Prototype:

virtual void CommitImplicitGrid(IPoint2 m, int mouseflags, Matrix3* mat = NULL)=0;

Remarks:

This method is available in release 3.0 and later only.

If AutoGrid is enabled, this method creates a grid and activates it. The mouseflags parameter is used to determine if the ALT key is down. If it is, this grid will not be deactivated in ReleaseImplicitGrid() (below).

Parameters:

IPoint2 m

The 2D screen point that the user clicked on.

int mouseflags

These flags describe the state of the mouse buttons. See List of Mouse Callback Flags.

Matrix3* mat = NULL

Developers can get the implicit grid coordinate system back by passing in a pointer to a matrix here.

Prototype:

virtual void ReleaseImplicitGrid()=0;

Remarks:

This method is available in release 3.0 and later only.

This method deactivates an implicit grid and restores the previously active grid. If the implicit grid was committed with ALT-key held down, then this call does nothing.

Osnap Related Methods

Prototype:

virtual void SnapPreview(const IPoint2 &in, IPoint2 &out, Matrix3 *plane2d=NULL, DWORD flags=0)=0;

Remarks:

This method is available in release 2.0 and later only.

This is a method used as part of the osnap system in 3ds max. It is the method that displays the snap marker in the viewports prior to the first point event. It's really just a call to SnapPoint() which returns nothing. This method should be called in response to a MOUSE_FREEMOVE event from any creation or transformation proc which calls SnapPoint(). Here's an example creation proc:

Sample Code:

int PointHelpObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) {

if (msg == MOUSE_FREEMOVE)

// Show a preview snap in the viewport prior to the

// first point event.

vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);

 

if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {

switch(point) {

case 0:

ob->suspendSnap = TRUE;

mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));

break;

case 1:

mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));

if (msg==MOUSE_POINT) {

ob->suspendSnap = FALSE;

return 0;

}

break;

}

} else

if (msg == MOUSE_ABORT) {

return CREATE_ABORT;

}

return 1;

}

Parameters:

const IPoint2 &in

The 2D screen coordinate to snap.

IPoint2 &out

The snapped 2D screen coordinate. This is used if you need to move the mouse position to the snapped location.

Matrix3 *plane2d = NULL

This optional argument allows you to use any plane (not just the current construction plane).

int flags

See List of Snap Flags.

Prototype:

virtual void GetGridDims(float *MinX, float *MaxX, float *MinY, float *MaxY) = 0;

Remarks:

This method is available in release 2.0 and later only.

This method is used internally. It fills up it's arguments with the world space extents of the home grid (i.e. the extents of the grid as displayed). It doesn't work for grid helper which always display to their size limits. This was exposed so 3ds max could do the grid snapping and is not needed by plug-in developers.

Perspective/Camera View Properties

Prototype:

virtual BOOL IsPerspView()=0;

Remarks:

Returns TRUE if the viewport is a perspective view; otherwise returns FALSE.

Prototype:

virtual int GetViewType()=0;

Remarks:

This method is available in release 3.0 and later only.

Returns the type of view. One of the following values:

enum ViewType {

VIEW_LEFT,VIEW_RIGHT,VIEW_TOP,VIEW_BOTTOM,VIEW_FRONT,VIEW_BACK,

 VIEW_ISO_USER, VIEW_PERSP_USER, VIEW_CAMERA, VIEW_GRID, VIEW_NONE,

VIEW_TRACK, VIEW_SPOT, VIEW_SHAPE, VIEW_SCHEMATIC, VIEW_OTHER

};

Prototype:

virtual float GetFOV()=0;

Remarks:

This method is available in release 2.0 and later only.

Returns the field of view of a perspective viewport in radians.

 

Prototype:

virtual float GetFocalDist()=0;

Remarks:

This method is available in release 2.0 and later only.

Returns the focal distance of a perspective view.

Prototype:

virtual INode *GetViewCamera()=0;

Remarks:

Returns the INode pointer of the camera associated with this viewport. If this is not a camera view then NULL is returned.

Prototype:

virtual void SetViewCamera(INode *camNode)=0;

Remarks:

Set this viewport to a camera view.

Parameters:

INode *camNode

The camera node to set.

Prototype:

virtual INode *GetViewSpot();

Remarks:

This method is available in release 3.0 and later only.

Returns the INode pointer of the spotlight associated with this viewport. If this is not a spotlight view then NULL is returned.

Prototype:

virtual void SetViewSpot(INode *spotNode)=0;

Remarks:

Set this viewport to a spotlight view.

Parameters:

INode *spotNode

The spotlight node to set.

Prototype:

virtual void SetViewUser(BOOL persp)=0;

Remarks:

This method is available in release 2.0 and later only.

This method sets the viewport to be a user view, with the persp argument indicating whether this should be a perspective or iso view. Note that the user viewport defaults are used for field-of-view, etc.

Parameters:

BOOL persp

TRUE for perspective; FALSE for isometric.

Snapping

Prototype:

virtual Point3 SnapPoint(const IPoint2 &in, IPoint2 &out, Matrix3 *plane2d = NULL, int flags = 0)=0;

Remarks:

Given a 2D screen coordinate, this method returns a 3D point on the current construction plane based on the current snap settings and flags passed.

Parameters:

const IPoint2 &in

The 2D screen coordinate to snap.

IPoint2 &out

The snapped 2D screen coordinate. This is used if you need to move the mouse position to the snapped location.

Matrix3 *plane2d = NULL

This optional argument allows you to use any plane (not just the current construction plane).

int flags

See List of Snap Flags.

Return Value:

The snapped 3D point in world space.

Prototype:

virtual float SnapLength(float in)=0;

Remarks:

Given the distance passed, this method snaps the length to the nearest snap increment and returns the snapped distance.

Parameters:

float in

The input distance to be snapped.

Return Value:

The snapped distance.

Access to Viewport Properties

Prototype:

virtual GraphicsWindow *getGW()=0;

Remarks:

Returns a pointer to the instance of GraphicsWindow associated with this viewport.

Note: A GraphicsWindow always has a transform associated with it, for faster object-to-screen space conversions. The GraphicsWindow * returned by this method may have a non-identity transform already in place. A developer can call gw->setTransform() with a node's transform for fast work in Display routines. But this value must be explicitly set to the identity for world-to-screen displays.

Prototype:

virtual HWND GetHWnd()=0;

Remarks:

This returns the window handle of the viewport - this is the transparent window that catches mouse input. Note that this window handle is different than the handle that can be retrieved from the viewport's GraphicsWindow. getGW()->getHWnd() is the window that things are drawn on.

Return Value:

The window handle of the viewport.

Prototype:

virtual BOOL setBkgImageDsp(BOOL onOff)=0;

Remarks:

This method is used to turn on and off the background image display in this viewport. Note that it is necessary to redraw the viewports in order to see the effect of this method. Use the method Interface::RedrawViews() to do this.

Parameters:

BOOL onOff

TRUE to turn the background image on; FALSE to turn it off.

Return Value:

TRUE if the image was set; otherwise FALSE.

Prototype:

virtual int getBkgImageDsp()=0;

Remarks:

Returns nonzero if the background image is displayed in this viewport; otherwise 0.

Prototype:

virtual void setSFDisplay(int onOff)=0;

Remarks:

This method may be used to turn the safe frame display on and off in this viewport.

Parameters:

int onOff

Nonzero to turn on the safe frame; zero to turn it off.

Prototype:

virtual int getSFDisplay()=0;

Remarks:

Returns nonzero if the safe frame is displayed in this viewport; otherwise 0.

Prototype:

virtual int IsWire()=0;

Remarks:

Determines if this viewport is in wire-frame rendering mode (as opposed to a shaded mode).

Return Value:

Nonzero if the viewport is in wire-frame rendering mode; otherwise 0.

Prototype:

virtual Rect GetDammageRect()=0;

Remarks:

Returns the damaged rectangle of the viewport. This is the area that needs to be updated on the next screen refresh. This can be used for example, to pass into the Mesh method render() to only display the damaged area of the object. A developer could also use this in the implementation of their own Display() method.

Sample Code:

int SimpleObject::Display(TimeValue t, INode* inode,

 ViewExp *vpt, int flags) {

 if (!OKtoDisplay(t)) return 0;

 GraphicsWindow *gw = vpt->getGW();

 Matrix3 mat = inode->GetObjectTM(t);

 UpdateMesh(t); // UpdateMesh() just calls BuildMesh()

 gw->setTransform(mat);

 mesh.render(gw, inode->Mtls(),

  (flags&USE_DAMAGE_RECT) ? &vpt->GetDammageRect() : NULL,

  COMP_ALL, inode->NumMtls());

 return(0);

}

Prototype:

virtual void GetConstructionTM( Matrix3 &tm )=0;

Remarks:

Retrieves the transformation matrix of the construction plane.

Parameters:

Matrix3 &tm

The transformation matrix is returned here.

Prototype:

virtual void SetGridSize(float size)=0;

Remarks:

Sets the size of the construction grid spacing.

Parameters:

float size

Specifies the grid spacing.

Prototype:

virtual float GetGridSize()=0;

Remarks:

Returns the construction grid spacing. This is the grid spacing on a per viewport basis. It is dependent on how far zoomed in or out the user is. This is the exact same value that you can see in the right most status panel below the viewports.

Prototype:

virtual BOOL IsGridVisible()=0;

Remarks:

Returns TRUE if the grid is turned on for this viewport; otherwise FALSE.

 

Prototype:

virtual int GetGridType()=0;

Remarks:

Returns the grid type. One of the following values (from OBJECT.H):

GRID_PLANE_NONE

GRID_PLANE_TOP

GRID_PLANE_LEFT

GRID_PLANE_FRONT

GRID_PLANE_BOTTOM

GRID_PLANE_RIGHT

GRID_PLANE_BACK

Prototype:

virtual BOOL IsActive()=0;

Remarks:

This method is available in release 3.0 and later only.

Returns TRUE if the viewport is the active on; otherwise FALSE.

Prototype:

virtual BOOL IsEnabled()=0;

Remarks:

This method is available in release 3.0 and later only.

Returns TRUE if the viewport is enabled; FALSE if disabled.

For node level hit-testing

Prototype:

virtual void ClearHitList()=0;

Remarks:

Implemented by the System.

Clears the list of node level hit records.

Prototype:

virtual INode *GetClosestHit()=0;

Remarks:

Implemented by the System.

Returns the INode pointer of the node that was the closest of all those hit. If none were hit, NULL is returned.

Prototype:

virtual INode *GetHit(int i)=0;

Remarks:

This method is available in release 2.0 and later only.

Returns the INode pointer of the 'i-th' node level hit.

Parameters:

int i

The index of the hit to retrieve.

Prototype:

virtual int HitCount()=0;

Remarks:

Implemented by the System.

Returns the number of hits recorded by the last node level hit test.

For sub-object level hit-testing

Prototype:

virtual void LogHit(Node *nr, ModContext *mc, DWORD dist, ulong info, HitData *hitdat = NULL)=0;

Remarks:

Implemented by the System.

This method records a sub-object level hit record with the system using the specified parameters. This hit can later be retrieved using the method GetSubObjHitList() and the methods of class HitLog.

Parameters:

Node *nr

The node that was hit.

ModContext *mc

The ModContext of the modifier.

DWORD dist

The 'distance' of the hit. What the distance actually represents depends on the rendering level of the viewport. For wireframe modes, it refers to the distance in the screen XY plane from the mouse to the sub-object component. In a shaded mode, it refers to the Z depth of the sub-object component. In both cases, smaller values indicate that the sub-object component is 'closer' to the mouse cursor.

ulong info

Identifies the sub-object component that was hit.

HitData *hitdat = NULL

If the info data member is insufficient to indicate the sub-object component that was hit, pass an instance of the HitData class that contains the needed information.

Prototype:

virtual HitLog& GetSubObjHitList()=0;

Remarks:

Returns the sub-object hit list. See Class HitLog.

Prototype:

virtual void ClearSubObjHitList()=0;

Remarks:

Clears the sub-object hit list. This deletes all previously saved HitRecords.

Prototype:

virtual int NumSubObjHits()=0;

Remarks:

Returns the number of sub-object hits recorded.

For controller apparatus hit testing.

Prototype:

virtual void CtrlLogHit(INode *nr, DWORD dist, ulong info, DWORD infoExtra)=0;

Remarks:

This method records a controller sub-object level hit record with the system using the specified parameters. This hit can later be retrieved using the method GetCtrlHitList() and the methods of class CtrlHitLog.

Parameters:

INode *nr

The node that was hit.

DWORD dist

The 'distance' of the hit. What the distance actually represents depends on the rendering level of the viewport. For wireframe modes, it refers to the distance in the screen XY plane from the mouse to the sub-object component. In a shaded mode, it refers to the Z depth of the sub-object component. In both cases, smaller values indicate that the sub-object component is 'closer' to the mouse cursor.

ulong info

A general unsigned long value. Most controllers will just need this to identity the sub-object element. The meaning of this value (how it is used to identify the element) is up to the plug-in.

DWORD infoExtra;

If the above hitInfo data member is not sufficient to describe the sub-object element this data member may be used as well.

Prototype:

virtual CtrlHitLog& GetCtrlHitList()=0;

Remarks:

Returns the list of controller gizmo hits recorded. See Class CtrlHitLog.

Prototype:

virtual void ClearCtrlHitList()=0;

Remarks:

Clears the controller hit list. This deletes all the HitRecords previously recorded.

Prototype:

virtual INT_PTR Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0);

Remarks:

This method is available in release 4.0 and later only.

This is a general purpose function that allows the API to be extended in the future. The 3ds max development team can assign new cmd numbers and continue to add functionality to this class without having to 'break' the API.

Parameters:

int cmd

The index of the command to execute.

ULONG arg1=0

Optional argument 1. See the documentation where the cmd option is discussed for more details on these parameters.

ULONG arg2=0

Optional argument 2.

ULONG arg3=0

Optional argument 3.

Return Value:

An integer return value. See the documentation where the cmd option is discussed for more details on the meaning of this value.