From ebb51bb178c8b5cfeb4f057fa53c3f91bfcfa9cc Mon Sep 17 00:00:00 2001 From: Areloch Date: Sun, 19 May 2019 21:30:45 -0500 Subject: [PATCH] Catch the template files up and add the improved convex editor bits. --- Engine/source/T3D/convexShape.cpp | 662 ++++++++++++++---- Engine/source/T3D/convexShape.h | 51 +- .../worldEditor/guiConvexShapeEditorCtrl.cpp | 582 ++++++++++++++- .../worldEditor/guiConvexShapeEditorCtrl.h | 35 + .../materials/processedShaderMaterial.cpp | 50 -- .../gui/scripts/fonts/Arial 14 (ansi).uft | Bin 4714 -> 4740 bytes .../scripts/fonts/ArialItalic 14 (ansi).uft | Bin 1612 -> 2110 bytes .../fonts/Lucida Console 12 (ansi).uft | Bin 4985 -> 5159 bytes .../game/tools/MainEditor/MainEditor.cs | 2 +- .../tools/convexEditor/convexEditorGui.cs | 156 ++++- .../convexEditor/convexEditorToolbar.ed.gui | 246 ++++--- .../BaseGame/game/tools/convexEditor/main.cs | 8 +- Templates/BaseGame/game/tools/main.cs | 1 - Templates/BaseGame/game/tools/settings.xml | 125 ++-- .../worldEditor/gui/objectBuilderGui.ed.gui | 18 + .../worldEditor/scripts/editors/creator.ed.cs | 7 + .../tools/worldEditor/scripts/lighting.ed.cs | 5 + .../tools/worldEditor/scripts/menus.ed.cs | 2 + 18 files changed, 1617 insertions(+), 333 deletions(-) diff --git a/Engine/source/T3D/convexShape.cpp b/Engine/source/T3D/convexShape.cpp index f179ad25a..b9a1ddcb1 100644 --- a/Engine/source/T3D/convexShape.cpp +++ b/Engine/source/T3D/convexShape.cpp @@ -42,6 +42,7 @@ #include "T3D/physics/physicsBody.h" #include "T3D/physics/physicsCollision.h" #include "console/engineAPI.h" +#include "core/strings/stringUnit.h" IMPLEMENT_CO_NETOBJECT_V1( ConvexShape ); @@ -206,6 +207,12 @@ bool ConvexShape::protectedSetSurface( void *object, const char *index, const ch Point3F pos; //MatrixF mat; + U32 matID; + Point2F offset; + Point2F scale; + F32 rot = 0; + bool horz = true, vert = true; + /* dSscanf( data, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", &mat[0], &mat[1], &mat[2], &mat[3], @@ -214,23 +221,61 @@ bool ConvexShape::protectedSetSurface( void *object, const char *index, const ch &mat[12], &mat[13], &mat[14], &mat[15] ); */ - dSscanf( data, "%g %g %g %g %g %g %g", &quat.x, &quat.y, &quat.z, &quat.w, &pos.x, &pos.y, &pos.z ); + String t = data; + S32 len = t.length(); + + dSscanf( data, "%g %g %g %g %g %g %g %i %g %g %g %g %f", &quat.x, &quat.y, &quat.z, &quat.w, &pos.x, &pos.y, &pos.z, + &matID, &offset.x, &offset.y, &scale.x, &scale.y, &rot); MatrixF surface; quat.setMatrix( &surface ); surface.setPosition( pos ); - shape->mSurfaces.push_back( surface ); + shape->mSurfaces.push_back( surface ); + + surfaceUV surfUV; + if (StringUnit::getUnitCount(data, " ") > 7) + { + surfUV.matID = matID; + surfUV.offset = offset; + surfUV.scale = scale; + surfUV.zRot = rot; + surfUV.horzFlip = horz; + surfUV.vertFlip = vert; + } + else + { + surfUV.matID = 0; + surfUV.offset = Point2F(0,0); + surfUV.scale = Point2F(1, 1); + surfUV.zRot = 0; + surfUV.horzFlip = false; + surfUV.vertFlip = false; + } + + shape->mSurfaceUVs.push_back(surfUV); return false; } +bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, const char *data) +{ + ConvexShape *shape = static_cast< ConvexShape* >(object); + + surfaceMaterial surface; + + surface.materialName = data; + + shape->mSurfaceTextures.push_back(surface); + + return false; +} ConvexShape::ConvexShape() : mMaterialName( "Grid512_OrangeLines_Mat" ), mMaterialInst( NULL ), - mVertCount( 0 ), - mPrimCount( 0 ), + //mVertCount( 0 ), + //mPrimCount( 0 ), mPhysicsRep( NULL ), mNormalLength( 0.3f ) { @@ -240,6 +285,10 @@ ConvexShape::ConvexShape() StaticShapeObjectType; mConvexList = new Convex; + + mSurfaceBuffers.clear(); + mSurfaceUVs.clear(); + mSurfaceTextures.clear(); } ConvexShape::~ConvexShape() @@ -247,6 +296,12 @@ ConvexShape::~ConvexShape() if ( mMaterialInst ) SAFE_DELETE( mMaterialInst ); + for(U32 i=0; i points; + points.push_back(a); + points.push_back(b); + points.push_back(c); + + Point3F vertices[64]; + p.clipPolygon(points.address(), points.size(), vertices); + return true; } @@ -374,6 +454,20 @@ void ConvexShape::writeFields( Stream &stream, U32 tabStop ) count = smMaxSurfaces; } + for (U32 i = 0; i < mSurfaceTextures.size(); i++) + { + stream.writeTabs(tabStop); + + char buffer[1024]; + dMemset(buffer, 0, 1024); + + const char* tex = mSurfaceTextures[i].materialName.c_str(); + + dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].materialName.c_str()); + + stream.writeLine((const U8*)buffer); + } + for ( U32 i = 0; i < count; i++ ) { const MatrixF &mat = mSurfaces[i]; @@ -386,8 +480,10 @@ void ConvexShape::writeFields( Stream &stream, U32 tabStop ) char buffer[1024]; dMemset( buffer, 0, 1024 ); - dSprintf( buffer, 1024, "surface = \"%g %g %g %g %g %g %g\";", - quat.x, quat.y, quat.z, quat.w, pos.x, pos.y, pos.z ); + dSprintf( buffer, 1024, "surface = \"%g %g %g %g %g %g %g %i %g %g %g %g %g %i %i\";", + quat.x, quat.y, quat.z, quat.w, pos.x, pos.y, pos.z, mSurfaceUVs[i].matID, + mSurfaceUVs[i].offset.x, mSurfaceUVs[i].offset.y, mSurfaceUVs[i].scale.x, + mSurfaceUVs[i].scale.y, mSurfaceUVs[i].zRot, mSurfaceUVs[i].horzFlip, mSurfaceUVs[i].vertFlip); stream.writeLine( (const U8*)buffer ); } @@ -398,6 +494,9 @@ bool ConvexShape::writeField( StringTableEntry fieldname, const char *value ) if ( fieldname == StringTable->insert("surface") ) return false; + if ( fieldname == StringTable->insert("surfaceTexture") ) + return false; + return Parent::writeField( fieldname, value ); } @@ -440,8 +539,26 @@ U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) Point3F pos( mSurfaces[i].getPosition() ); mathWrite( *stream, quat ); - mathWrite( *stream, pos ); + mathWrite( *stream, pos ); + + mathWrite(*stream, mSurfaceUVs[i].offset); + mathWrite(*stream, mSurfaceUVs[i].scale); + + stream->writeFlag(mSurfaceUVs[i].horzFlip); + stream->writeFlag(mSurfaceUVs[i].vertFlip); + + stream->writeInt(mSurfaceUVs[i].matID, 16); } + + const U32 surfaceTex = mSurfaceTextures.size(); + + stream->writeInt( surfaceTex, 32 ); + //next check for any texture coord or scale mods + for(U32 i=0; i < surfaceTex; i++) + { + String a = mSurfaceTextures[i].materialName; + stream->write( mSurfaceTextures[i].materialName ); + } } return retMask; @@ -464,10 +581,8 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream ) { stream->read( &mMaterialName ); - if ( isProperlyAdded() ) - _updateMaterial(); - mSurfaces.clear(); + mSurfaceUVs.clear(); const U32 surfCount = stream->readInt( 32 ); for ( S32 i = 0; i < surfCount; i++ ) @@ -483,8 +598,33 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream ) quat.setMatrix( &mat ); mat.setPosition( pos ); + + mSurfaceUVs.increment(); + + mathRead(*stream, &mSurfaceUVs[i].offset); + mathRead(*stream, &mSurfaceUVs[i].scale); + + mSurfaceUVs[i].horzFlip = stream->readFlag(); + mSurfaceUVs[i].vertFlip = stream->readFlag(); + + mSurfaceUVs[i].matID = stream->readInt(16); } + //now fetch our text coord mods to store into the geometry data + mSurfaceTextures.clear(); + const U32 surfaceTex = stream->readInt( 32 ); + + //next check for any texture coord or scale mods + for(U32 i=0; i < surfaceTex; i++) + { + mSurfaceTextures.increment(); + + stream->read( &mSurfaceTextures[i].materialName ); + } + + if (isProperlyAdded()) + _updateMaterial(); + if ( isProperlyAdded() ) _updateGeometry( true ); } @@ -492,6 +632,7 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream ) void ConvexShape::prepRenderImage( SceneRenderState *state ) { + /* if ( state->isDiffusePass() ) { ObjectRenderInst *ri2 = state->getRenderPass()->allocInst(); @@ -499,82 +640,95 @@ void ConvexShape::prepRenderImage( SceneRenderState *state ) ri2->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri2 ); } - - if ( mVertexBuffer.isNull() || !state) - return; + */ - // If we don't have a material instance after the override then - // we can skip rendering all together. - BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst ? mMaterialInst : MATMGR->getWarningMatInstance() ); - if ( !matInst ) - return; - - // Get a handy pointer to our RenderPassmanager - RenderPassManager *renderPass = state->getRenderPass(); - - // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager - MeshRenderInst *ri = renderPass->allocInst(); - - // Set our RenderInst as a standard mesh render - ri->type = RenderPassManager::RIT_Mesh; - - // Calculate our sorting point - if ( state ) + for (U32 i = 0; i < mSurfaceBuffers.size(); i++) { - // Calculate our sort point manually. - const Box3F& rBox = getRenderWorldBox(); - ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() ); - } - else - ri->sortDistSq = 0.0f; + if (mSurfaceBuffers[i].mPrimitiveBuffer.isNull()) + continue; - // Set up our transforms - MatrixF objectToWorld = getRenderTransform(); - objectToWorld.scale( getScale() ); + // If we don't have a material instance after the override then + // we can skip rendering all together. + BaseMatInstance *matInst; + if (i == 0) + { + matInst = state->getOverrideMaterial(mMaterialInst ? mMaterialInst : MATMGR->getWarningMatInstance()); + } + else + { + matInst = state->getOverrideMaterial(mSurfaceTextures[i - 1].materialInst ? mSurfaceTextures[i - 1].materialInst : MATMGR->getWarningMatInstance()); + } - ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld ); - ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); - ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); + if (!matInst) + continue; - // If we need lights then set them up. - if ( matInst->isForwardLit() ) - { - LightQuery query; - query.init( getWorldSphere() ); - query.getLights( ri->lights, 8 ); + // Get a handy pointer to our RenderPassmanager + RenderPassManager *renderPass = state->getRenderPass(); + + // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager + MeshRenderInst *ri = renderPass->allocInst(); + + // Set our RenderInst as a standard mesh render + ri->type = RenderPassManager::RIT_Mesh; + + // Calculate our sorting point + if (state) + { + // Calculate our sort point manually. + const Box3F& rBox = getRenderWorldBox(); + ri->sortDistSq = rBox.getSqDistanceToPoint(state->getCameraPosition()); + } + else + ri->sortDistSq = 0.0f; + + // Set up our transforms + MatrixF objectToWorld = getRenderTransform(); + objectToWorld.scale(getScale()); + + ri->objectToWorld = renderPass->allocUniqueXform(objectToWorld); + ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); + ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); + + // If we need lights then set them up. + if (matInst->isForwardLit()) + { + LightQuery query; + query.init(getWorldSphere()); + query.getLights(ri->lights, 8); + } + + // Make sure we have an up-to-date backbuffer in case + // our Material would like to make use of it + // NOTICE: SFXBB is removed and refraction is disabled! + //ri->backBuffTex = GFX->getSfxBackBuffer(); + + // Set our Material + ri->matInst = matInst; + if (matInst->getMaterial()->isTranslucent()) + { + ri->translucentSort = true; + ri->type = RenderPassManager::RIT_Translucent; + } + + // Set up our vertex buffer and primitive buffer + ri->vertBuff = &mSurfaceBuffers[i].mVertexBuffer; + ri->primBuff = &mSurfaceBuffers[i].mPrimitiveBuffer; + + ri->prim = renderPass->allocPrim(); + ri->prim->type = GFXTriangleList; + ri->prim->minIndex = 0; + ri->prim->startIndex = 0; + ri->prim->numPrimitives = mSurfaceBuffers[i].mPrimCount; + ri->prim->startVertex = 0; + ri->prim->numVertices = mSurfaceBuffers[i].mVertCount; + + // We sort by the material then vertex buffer. + ri->defaultKey = matInst->getStateHint(); + ri->defaultKey2 = (U32)ri->vertBuff; // Not 64bit safe! + + // Submit our RenderInst to the RenderPassManager + state->getRenderPass()->addInst(ri); } - - // Make sure we have an up-to-date backbuffer in case - // our Material would like to make use of it - // NOTICE: SFXBB is removed and refraction is disabled! - //ri->backBuffTex = GFX->getSfxBackBuffer(); - - // Set our Material - ri->matInst = matInst; - if ( matInst->getMaterial()->isTranslucent() ) - { - ri->translucentSort = true; - ri->type = RenderPassManager::RIT_Translucent; - } - - // Set up our vertex buffer and primitive buffer - ri->vertBuff = &mVertexBuffer; - ri->primBuff = &mPrimitiveBuffer; - - ri->prim = renderPass->allocPrim(); - ri->prim->type = GFXTriangleList; - ri->prim->minIndex = 0; - ri->prim->startIndex = 0; - ri->prim->numPrimitives = mPrimCount; - ri->prim->startVertex = 0; - ri->prim->numVertices = mVertCount; - - // We sort by the material then vertex buffer. - ri->defaultKey = matInst->getStateHint(); - ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe! - - // Submit our RenderInst to the RenderPassManager - state->getRenderPass()->addInst( ri ); } void ConvexShape::buildConvex( const Box3F &box, Convex *convex ) @@ -791,10 +945,21 @@ bool ConvexShape::castRay( const Point3F &start, const Point3F &end, RayInfo *in F32 t; F32 tmin = F32_MAX; S32 hitFace = -1; - Point3F pnt; + Point3F hitPnt, pnt; VectorF rayDir( end - start ); rayDir.normalizeSafe(); - + + if ( false ) + { + PlaneF plane( Point3F(0,0,0), Point3F(0,0,1) ); + Point3F sp( 0,0,-1 ); + Point3F ep( 0,0,1 ); + + F32 t = plane.intersect( sp, ep ); + Point3F hitPnt; + hitPnt.interpolate( sp, ep, t ); + } + for ( S32 i = 0; i < planeCount; i++ ) { // Don't hit the back-side of planes. @@ -1037,8 +1202,33 @@ void ConvexShape::getSurfaceLineList( S32 surfId, Vector< Point3F > &lineList ) void ConvexShape::_updateMaterial() { + //update our custom surface materials + for (U32 i = 0; igetMaterial()->getName(), String::NoCase)) + continue; + + Material *material; + + if (!Sim::findObject(mSurfaceTextures[i].materialName, material)) + //bail + continue; + + mSurfaceTextures[i].materialInst = material->createMatInstance(); + + FeatureSet features = MATMGR->getDefaultFeatures(); + + mSurfaceTextures[i].materialInst->init(features, getGFXVertexFormat()); + + if (!mSurfaceTextures[i].materialInst->isValid()) + { + SAFE_DELETE(mSurfaceTextures[i].materialInst); + } + } + // If the material name matches then don't bother updating it. - if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) ) + if (mMaterialInst && mMaterialName.equal(mMaterialInst->getMaterial()->getName(), String::NoCase)) return; SAFE_DELETE( mMaterialInst ); @@ -1074,34 +1264,85 @@ void ConvexShape::_updateGeometry( bool updateCollision ) for ( S32 i = 0; i < mSurfaces.size(); i++ ) mPlanes.push_back( PlaneF( mSurfaces[i].getPosition(), mSurfaces[i].getUpVector() ) ); - Vector< Point3F > tangents; - for ( S32 i = 0; i < mSurfaces.size(); i++ ) - tangents.push_back( mSurfaces[i].getRightVector() ); - - mGeometry.generate( mPlanes, tangents ); + Vector< Point3F > tangents; + for (S32 i = 0; i < mSurfaces.size(); i++) + tangents.push_back(mSurfaces[i].getRightVector()); - AssertFatal( mGeometry.faces.size() <= mSurfaces.size(), "Got more faces than planes?" ); + //prepping the texture info + Vector texOffset; + Vector texScale; + Vector horzFlip; + Vector vertFlip; + //step in here, and add new surfaceTextures if we don't match the count of surfaces, we use + //msurfaces as the counter, because we need to match it. + if (mSurfaceUVs.size() > mSurfaces.size()) + { + for (U32 x = mSurfaceUVs.size(); x > mSurfaces.size(); x--) + mSurfaceUVs.pop_front(); + } + else if (mSurfaceUVs.size() < mSurfaces.size()) + { + for (U32 x = mSurfaceUVs.size(); x <= mSurfaces.size(); x++) + { + mSurfaceUVs.increment(); + mSurfaceUVs[x].offset = Point2F(0, 0); + mSurfaceUVs[x].scale = Point2F(1, 1); + mSurfaceUVs[x].zRot = 0; + mSurfaceUVs[x].horzFlip = false; + mSurfaceUVs[x].vertFlip = false; + mSurfaceUVs[x].matID = 0; + } + } + + for (S32 i = 0; i < mSurfaceUVs.size(); i++) + { + //add our offsets/scales for passing to the geometry now + texOffset.push_back(mSurfaceUVs[i].offset); + texScale.push_back(mSurfaceUVs[i].scale); + horzFlip.push_back(mSurfaceUVs[i].horzFlip); + vertFlip.push_back(mSurfaceUVs[i].vertFlip); + } + + mGeometry.generate(mPlanes, tangents, mSurfaceTextures, texOffset, texScale, horzFlip, vertFlip); + + AssertFatal(mGeometry.faces.size() <= mSurfaces.size(), "Got more faces than planes?"); const Vector< ConvexShape::Face > &faceList = mGeometry.faces; const Vector< Point3F > &pointList = mGeometry.points; // Reset our surface center points. - for ( S32 i = 0; i < faceList.size(); i++ ) - mSurfaces[ faceList[i].id ].setPosition( faceList[i].centroid ); + for (S32 i = 0; i < faceList.size(); i++) + mSurfaces[faceList[i].id].setPosition(faceList[i].centroid); mPlanes.clear(); - for ( S32 i = 0; i < mSurfaces.size(); i++ ) - mPlanes.push_back( PlaneF( mSurfaces[i].getPosition(), mSurfaces[i].getUpVector() ) ); + for (S32 i = 0; i < mSurfaces.size(); i++) + mPlanes.push_back(PlaneF(mSurfaces[i].getPosition(), mSurfaces[i].getUpVector())); // Update bounding box. updateBounds( false ); - mVertexBuffer = NULL; - mPrimitiveBuffer = NULL; - mVertCount = 0; - mPrimCount = 0; + /*mVertexBuffer = NULL; + mPrimitiveBuffer = NULL; + mVertCount = 0; + mPrimCount = 0;*/ + + mSurfaceBuffers.clear(); + + //set up buffers based on how many materials we have, but we always have at least one for our default mat + mSurfaceBuffers.increment(); + mSurfaceBuffers[0].mVertexBuffer = NULL; + mSurfaceBuffers[0].mVertCount = 0; + mSurfaceBuffers[0].mPrimCount = 0; + + for (U32 i = 0; i < mSurfaceTextures.size(); i++) + { + mSurfaceBuffers.increment(); + mSurfaceBuffers[i+1].mVertexBuffer = NULL; + mSurfaceBuffers[i + 1].mVertCount = 0; + mSurfaceBuffers[i + 1].mPrimCount = 0; + } if ( updateCollision ) _updateCollision(); @@ -1113,59 +1354,173 @@ void ConvexShape::_updateGeometry( bool updateCollision ) if ( faceList.empty() ) return; + //We do this in 2 parts. First, going through and building the buffers for all faces with the default material(matID -1) + //After that, we then through and build buffers for all faces sharing materials. This means we can have a single buffer, + //or one for each face of the brush, depending on how it's textured // Get total vert and prim count. for ( S32 i = 0; i < faceList.size(); i++ ) { - U32 count = faceList[i].triangles.size(); - mPrimCount += count; - mVertCount += count * 3; + U32 count = faceList[i].triangles.size(); + + S32 matID = mSurfaceUVs[i].matID; + + mSurfaceBuffers[mSurfaceUVs[i].matID].mPrimCount += count; + mSurfaceBuffers[mSurfaceUVs[i].matID].mVertCount += count * 3; } - // Allocate VB and copy in data. - - mVertexBuffer.set( GFX, mVertCount, GFXBufferTypeStatic ); - VertexType *pVert = mVertexBuffer.lock(); - - for ( S32 i = 0; i < faceList.size(); i++ ) - { - const ConvexShape::Face &face = faceList[i]; - const Vector< U32 > &facePntMap = face.points; - const Vector< ConvexShape::Triangle > &triangles = face.triangles; - const ColorI &faceColor = sgConvexFaceColors[ i % sgConvexFaceColorCount ]; - - for ( S32 j = 0; j < triangles.size(); j++ ) - { - for ( S32 k = 0; k < 3; k++ ) - { - pVert->normal = face.normal; - pVert->tangent = face.tangent; - pVert->color = faceColor; - pVert->point = pointList[ facePntMap[ triangles[j][k] ] ]; - pVert->texCoord = face.texcoords[ triangles[j][k] ]; - - pVert++; - } - } - } - - mVertexBuffer.unlock(); - - // Allocate PB - - mPrimitiveBuffer.set( GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic ); - - U16 *pIndex; - mPrimitiveBuffer.lock( &pIndex ); - - for ( U16 i = 0; i < mPrimCount * 3; i++ ) + //Build the buffer for our default material + /*if (mVertCount > 0) { - *pIndex = i; - pIndex++; - } + mVertexBuffer.set(GFX, mVertCount, GFXBufferTypeStatic); + VertexType *pVert = mVertexBuffer.lock(); - mPrimitiveBuffer.unlock(); + for (S32 i = 0; i < faceList.size(); i++) + { + if (mSurfaceUVs[i].matID == -1) + { + const ConvexShape::Face &face = faceList[i]; + const Vector< U32 > &facePntMap = face.points; + const Vector< ConvexShape::Triangle > &triangles = face.triangles; + const ColorI &faceColor = sgConvexFaceColors[i % sgConvexFaceColorCount]; + + const Point3F binormal = mCross(face.normal, face.tangent); + + pVert++; + } + } + } + } + + mVertexBuffer.unlock(); + + // Allocate PB + + mPrimitiveBuffer.set(GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic); + + U16 *pIndex; + mPrimitiveBuffer.lock(&pIndex); + + for (U16 i = 0; i < mPrimCount * 3; i++) + { + *pIndex = i; + pIndex++; + } + + mPrimitiveBuffer.unlock(); + }*/ + + // + // + for (U32 i = 0; i < mSurfaceBuffers.size(); i++) + { + if (mSurfaceBuffers[i].mVertCount > 0) + { + U32 primCount = mSurfaceBuffers[i].mPrimCount; + U32 vertCount = mSurfaceBuffers[i].mVertCount; + + mSurfaceBuffers[i].mVertexBuffer.set(GFX, mSurfaceBuffers[i].mVertCount, GFXBufferTypeStatic); + VertexType *pVert = mSurfaceBuffers[i].mVertexBuffer.lock(); + + U32 vc = 0; + + for (S32 f = 0; f < faceList.size(); f++) + { + if (mSurfaceUVs[f].matID == i) + { + const ConvexShape::Face &face = faceList[f]; + const Vector< U32 > &facePntMap = face.points; + const Vector< ConvexShape::Triangle > &triangles = face.triangles; + const ColorI &faceColor = sgConvexFaceColors[f % sgConvexFaceColorCount]; + + const Point3F binormal = mCross(face.normal, face.tangent); + + for (S32 j = 0; j < triangles.size(); j++) + { + for (S32 k = 0; k < 3; k++) + { + pVert->normal = face.normal; + pVert->tangent = face.tangent; + pVert->color = faceColor; + pVert->point = pointList[facePntMap[triangles[j][k]]]; + pVert->texCoord = face.texcoords[triangles[j][k]]; + + pVert++; + vc++; + } + } + } + } + + mSurfaceBuffers[i].mVertexBuffer.unlock(); + + // Allocate PB + + mSurfaceBuffers[i].mPrimitiveBuffer.set(GFX, mSurfaceBuffers[i].mPrimCount * 3, mSurfaceBuffers[i].mPrimCount, GFXBufferTypeStatic); + + U16 *pIndex; + mSurfaceBuffers[i].mPrimitiveBuffer.lock(&pIndex); + + for (U16 p = 0; p < mSurfaceBuffers[i].mPrimCount * 3; p++) + { + *pIndex = p; + pIndex++; + } + + mSurfaceBuffers[i].mPrimitiveBuffer.unlock(); + } + } + // + // + + /*// Allocate VB and copy in data. + for (S32 i = 0; i < faceList.size(); i++) + { + mVertexBuffer.set(GFX, mVertCount, GFXBufferTypeStatic); + VertexType *pVert = mVertexBuffer.lock(); + + for (S32 i = 0; i < faceList.size(); i++) + { + const ConvexShape::Face &face = faceList[i]; + const Vector< U32 > &facePntMap = face.points; + const Vector< ConvexShape::Triangle > &triangles = face.triangles; + const ColorI &faceColor = sgConvexFaceColors[i % sgConvexFaceColorCount]; + + const Point3F binormal = mCross(face.normal, face.tangent); + + for (S32 j = 0; j < triangles.size(); j++) + { + for (S32 k = 0; k < 3; k++) + { + pVert->normal = face.normal; + pVert->tangent = face.tangent; + pVert->color = faceColor; + pVert->point = pointList[facePntMap[triangles[j][k]]]; + pVert->texCoord = face.texcoords[triangles[j][k]]; + + pVert++; + } + } + } + + mVertexBuffer.unlock(); + + // Allocate PB + + mPrimitiveBuffer.set(GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic); + + U16 *pIndex; + mPrimitiveBuffer.lock(&pIndex); + + for (U16 i = 0; i < mPrimCount * 3; i++) + { + *pIndex = i; + pIndex++; + } + + mPrimitiveBuffer.unlock(); + }*/ } void ConvexShape::_updateCollision() @@ -1488,7 +1843,7 @@ void ConvexShape::getSurfaceTriangles( S32 surfId, Vector< Point3F > *outPoints, objToWorld.mulP( (*outPoints)[i] ); } } -void ConvexShape::Geometry::generate( const Vector< PlaneF > &planes, const Vector< Point3F > &tangents ) +void ConvexShape::Geometry::generate(const Vector< PlaneF > &planes, const Vector< Point3F > &tangents, const Vector< surfaceMaterial > surfaceTextures, const Vector< Point2F > texOffset, const Vector< Point2F > texScale, const Vector< bool > horzFlip, const Vector< bool > vertFlip) { PROFILE_SCOPE( Geometry_generate ); @@ -1759,7 +2114,26 @@ void ConvexShape::Geometry::generate( const Vector< PlaneF > &planes, const Vect F32 x = planex.distToPlane( points[ newFace.points[ j ] ] ); F32 y = planey.distToPlane( points[ newFace.points[ j ] ] ); - newFace.texcoords[j].set( -x, -y ); + if (!texOffset.empty()) + { + x += texOffset[i].x; + y += texOffset[i].y; + } + + //now scale + if (!texScale.empty() && !texScale[i].isZero()) + { + x *= (texScale[i].x); + y *= (texScale[i].y); + } + + if (horzFlip.size() > 0 && horzFlip[i]) + x *= -1; + + if (vertFlip.size() > 0 && vertFlip[i]) + y *= -1; + + newFace.texcoords[j].set(-x, -y); } // Data verification tests. diff --git a/Engine/source/T3D/convexShape.h b/Engine/source/T3D/convexShape.h index 62b38f354..6145937b7 100644 --- a/Engine/source/T3D/convexShape.h +++ b/Engine/source/T3D/convexShape.h @@ -131,9 +131,46 @@ public: S32 id; }; + struct surfaceMaterial + { + // The name of the Material we will use for rendering + String materialName; + + // The actual Material instance + BaseMatInstance* materialInst; + + surfaceMaterial() + { + materialName = ""; + materialInst = NULL; + } + }; + + struct surfaceUV + { + S32 matID; + Point2F offset; + Point2F scale; + float zRot; + bool horzFlip; + bool vertFlip; + + surfaceUV() : matID(0), offset(Point2F(0.0f, 0.0f)), scale(Point2F(1.0f, 1.0f)), zRot(0.0f), horzFlip(false), vertFlip(false) {} + }; + + struct surfaceBuffers + { + // The GFX vertex and primitive buffers + GFXVertexBufferHandle< VertexType > mVertexBuffer; + GFXPrimitiveBufferHandle mPrimitiveBuffer; + + U32 mVertCount; + U32 mPrimCount; + }; + struct Geometry { - void generate( const Vector< PlaneF > &planes, const Vector< Point3F > &tangents ); + void generate(const Vector< PlaneF > &planes, const Vector< Point3F > &tangents, const Vector< surfaceMaterial > surfaceTextures, const Vector< Point2F > texOffset, const Vector< Point2F > texScale, const Vector< bool > horzFlip, const Vector< bool > vertFlip); Vector< Point3F > points; Vector< Face > faces; @@ -215,6 +252,9 @@ protected: static S32 QSORT_CALLBACK _comparePlaneDist( const void *a, const void *b ); static bool protectedSetSurface( void *object, const char *index, const char *data ); + + static bool protectedSetSurfaceTexture( void *object, const char *index, const char *data ); + static bool protectedSetSurfaceUV(void *object, const char *index, const char *data); protected: @@ -225,11 +265,11 @@ protected: BaseMatInstance* mMaterialInst; // The GFX vertex and primitive buffers - GFXVertexBufferHandle< VertexType > mVertexBuffer; + /*GFXVertexBufferHandle< VertexType > mVertexBuffer; GFXPrimitiveBufferHandle mPrimitiveBuffer; U32 mVertCount; - U32 mPrimCount; + U32 mPrimCount;*/ Geometry mGeometry; @@ -239,6 +279,11 @@ protected: Vector< Point3F > mFaceCenters; + //this is mostly for storage purposes, so we can save the texture mods + Vector< surfaceMaterial > mSurfaceTextures; + Vector< surfaceUV > mSurfaceUVs; + Vector< surfaceBuffers > mSurfaceBuffers; + Convex *mConvexList; PhysicsBody *mPhysicsRep; diff --git a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp index bcb53df80..5f1b32638 100644 --- a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp +++ b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp @@ -80,7 +80,8 @@ GuiConvexEditorCtrl::GuiConvexEditorCtrl() mHasCopied( false ), mLastUndo( NULL ), mUndoManager( NULL ), - mCtrlDown( false ) + mCtrlDown( false ), + mGridSnap(false) { mMaterialName = StringTable->insert("Grid512_OrangeLines_Mat"); } @@ -630,10 +631,44 @@ void GuiConvexEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event) submitUndo( ModifyShape, mConvexSEL ); } - if ( mGizmo->getMode() == ScaleMode ) + if ( mGizmo->getMode() == ScaleMode && !(event.modifier & SI_CTRL)) { scaleFace( mConvexSEL, mFaceSEL, mGizmo->getScale() ); } + + else if ( mGizmo->getMode() == ScaleMode && (event.modifier & SI_CTRL) ) + { + Point3F scale = mGizmo->getDeltaScale(); + + F32 scalar = 1; + mConvexSEL->mSurfaceUVs[mFaceSEL].scale += (Point2F(scale.x, scale.y) * scalar); + + if (mConvexSEL->mSurfaceUVs[mFaceSEL].scale.x < 0.01) + mConvexSEL->mSurfaceUVs[mFaceSEL].scale.x = 0.01; + + if (mConvexSEL->mSurfaceUVs[mFaceSEL].scale.y < 0.01) + mConvexSEL->mSurfaceUVs[mFaceSEL].scale.y = 0.01; + + if (mConvexSEL->mSurfaceUVs[mFaceSEL].scale.x > 100) + mConvexSEL->mSurfaceUVs[mFaceSEL].scale.x = 100; + + if (mConvexSEL->mSurfaceUVs[mFaceSEL].scale.y > 100) + mConvexSEL->mSurfaceUVs[mFaceSEL].scale.y = 100; + + Point2F test = mConvexSEL->mSurfaceUVs[mFaceSEL].scale; + mConvexSEL->setMaskBits( ConvexShape::UpdateMask ); + + updateShape( mConvexSEL, mFaceSEL ); + } + /*else if ( mGizmo->getMode() == MoveMode && event.modifier & SI_CTRL ) { + Point3F scale = mGizmo->getOffset(); + + F32 scalar = 0.8; + mConvexSEL->mSurfaceTextures[mFaceSEL].offset += (Point2F(-scale.x, scale.z) * scalar); + mConvexSEL->setMaskBits( ConvexShape::UpdateMask ); + + updateShape( mConvexSEL, mFaceSEL ); + }*/ else { // Why does this have to be so ugly. @@ -662,6 +697,20 @@ void GuiConvexEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event) // Clear out floating point errors. cleanMatrix( surfMat ); + if (mGizmo->getSelection() == Gizmo::Axis_Z) + { + MatrixF curSurfMat = mConvexSEL->mSurfaces[mFaceSEL]; + EulerF curSufRot = curSurfMat.toEuler(); + + EulerF newSufRot = surfMat.toEuler(); + + float zRot = mRadToDeg(newSufRot.z - curSufRot.z); + + float curZRot = mConvexSEL->mSurfaceUVs[mFaceSEL].zRot; + + mConvexSEL->mSurfaceUVs[mFaceSEL].zRot += zRot; + } + mConvexSEL->mSurfaces[mFaceSEL] = surfMat; updateShape( mConvexSEL, mFaceSEL ); @@ -699,7 +748,28 @@ void GuiConvexEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event) if ( mGizmo->getMode() == MoveMode ) { - mConvexSEL->setPosition( mGizmo->getPosition() ); + //mConvexSEL->setPosition( mGizmo->getPosition() ); + + //MatrixF mat = mGizmo->getTransform(); + Point3F wPos = mGizmo->getPosition(); + //mat.getColumn(3, &wPos); + + // adjust + //wPos += offset; + + if (mGridSnap && mGridPlaneSize != 0.f) + { + if (mGizmo->getSelection() == Gizmo::Selection::Axis_X || mGizmo->getSelection() == Gizmo::Selection::Plane_XY || mGizmo->getSelection() == Gizmo::Selection::Plane_XZ) + wPos.x -= mFmod(wPos.x, mGridPlaneSize); + + if (mGizmo->getSelection() == Gizmo::Selection::Axis_Y || mGizmo->getSelection() == Gizmo::Selection::Plane_XY || mGizmo->getSelection() == Gizmo::Selection::Plane_YZ) + wPos.y -= mFmod(wPos.y, mGridPlaneSize); + + if (mGizmo->getSelection() == Gizmo::Selection::Axis_Z || mGizmo->getSelection() == Gizmo::Selection::Plane_XZ || mGizmo->getSelection() == Gizmo::Selection::Plane_YZ) + wPos.z -= mFmod(wPos.z, mGridPlaneSize); + } + + mConvexSEL->setPosition(wPos); } else if ( mGizmo->getMode() == RotateMode ) { @@ -845,8 +915,10 @@ void GuiConvexEditorCtrl::updateGizmo() if ( mFaceSEL != -1 && mode == MoveMode ) { - if ( mCtrlDown ) - flags &= ~( GizmoProfile::CanTranslateX | GizmoProfile::CanTranslateY | GizmoProfile::PlanarHandlesOn ); + if ( mCtrlDown ) + //hijacking the CTRL modifier for texture offsetting control + //flags &= ~( GizmoProfile::CanTranslateX | GizmoProfile::CanTranslateY | GizmoProfile::PlanarHandlesOn ); + flags &= ~GizmoProfile::CanScaleZ; else flags |= ( GizmoProfile::CanTranslateX | GizmoProfile::CanTranslateY | GizmoProfile::PlanarHandlesOn ); } @@ -1201,13 +1273,51 @@ void GuiConvexEditorCtrl::translateFace( ConvexShape *shape, S32 faceId, const P AssertFatal( shape->mSurfaces[ face.id ].isAffine(), "ConvexShapeEditor - surface not affine." ); + Point3F modDisplace = Point3F(displace.x, displace.y, displace.z); + + //snapping + if (mGridSnap && mGridPlaneSize != 0) + { + Point3F faceCenter = Point3F::Zero; + + for (S32 i = 0; i < face.points.size(); i++) + { + Point3F &pnt = pointList[face.points[i]]; + faceCenter += pnt; + } + + faceCenter /= face.points.size(); + + // Transform displacement into object space. + MatrixF objToWorld(shape->getWorldTransform()); + objToWorld.scale(shape->getScale()); + objToWorld.inverse(); + + objToWorld.mulP(faceCenter); + + modDisplace = faceCenter + displace; + Point3F fMod = Point3F::Zero; + + if (!mIsZero(displace.x)) + fMod.x = mFmod(modDisplace.x - (displace.x > 0 ? mGridPlaneSize : -mGridPlaneSize), mGridPlaneSize); + + if (!mIsZero(displace.y)) + fMod.y = mFmod(modDisplace.y - (displace.y > 0 ? mGridPlaneSize : -mGridPlaneSize), mGridPlaneSize); + + if (!mIsZero(displace.z)) + fMod.z = mFmod(modDisplace.z - (displace.z > 0 ? mGridPlaneSize : -mGridPlaneSize), mGridPlaneSize); + + modDisplace -= fMod; + modDisplace -= faceCenter; + } + // Transform displacement into object space. MatrixF worldToObj( shape->getTransform() ); worldToObj.scale( shape->getScale() ); worldToObj.inverse(); Point3F displaceOS; - worldToObj.mulV( displace, &displaceOS ); + worldToObj.mulV(modDisplace, &displaceOS); for ( S32 i = 0; i < face.points.size(); i++ ) { @@ -1776,6 +1886,281 @@ bool GuiConvexEditorCtrl::getEdgesTouchingPoint( ConvexShape *shape, S32 faceId, return !edgeIdxList.empty(); } +Point2F GuiConvexEditorCtrl::getSelectedFaceUVOffset() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return Point2F(0, 0); + + return mConvexSEL->mSurfaceUVs[mFaceSEL].offset; +} + +Point2F GuiConvexEditorCtrl::getSelectedFaceUVScale() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return Point2F(0, 0); + + return mConvexSEL->mSurfaceUVs[mFaceSEL].scale; +} + +const char* GuiConvexEditorCtrl::getSelectedFaceMaterial() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return ""; + + if (mConvexSEL->mSurfaceUVs[mFaceSEL].matID == 0) + { + return mConvexSEL->mMaterialName; + } + else + { + return mConvexSEL->mSurfaceTextures[mConvexSEL->mSurfaceUVs[mFaceSEL].matID - 1].materialName; + } +} + +bool GuiConvexEditorCtrl::getSelectedFaceHorzFlip() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return false; + + return mConvexSEL->mSurfaceUVs[mFaceSEL].horzFlip; +} + +bool GuiConvexEditorCtrl::getSelectedFaceVertFlip() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return false; + + return mConvexSEL->mSurfaceUVs[mFaceSEL].vertFlip; +} + +float GuiConvexEditorCtrl::getSelectedFaceZRot() +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return false; + + return mConvexSEL->mSurfaceUVs[mFaceSEL].zRot; +} + +void GuiConvexEditorCtrl::setSelectedFaceUVOffset(Point2F offset) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + mConvexSEL->mSurfaceUVs[mFaceSEL].offset = offset; + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); +} + +void GuiConvexEditorCtrl::setSelectedFaceUVScale(Point2F scale) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + mConvexSEL->mSurfaceUVs[mFaceSEL].scale = scale; + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); +} + +void GuiConvexEditorCtrl::setSelectedFaceMaterial(const char* materialName) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + if (mConvexSEL->mSurfaceUVs.size() < mFaceSEL) + return; + + //first, see if the mat already exists in our list + bool found = false; + U32 oldmatID = mConvexSEL->mSurfaceUVs[mFaceSEL].matID; + + if (dStrcmp(materialName, mConvexSEL->getMaterialName().c_str())) + { + for (U32 i = 0; i < mConvexSEL->mSurfaceTextures.size(); i++) + { + if (!dStrcmp(mConvexSEL->mSurfaceTextures[i].materialName, materialName)) + { + //found a match + mConvexSEL->mSurfaceUVs[mFaceSEL].matID = i + 1; + found = true; + } + } + + if (!found) + { + //add a new one + ConvexShape::surfaceMaterial newMat; + newMat.materialName = materialName; + + mConvexSEL->mSurfaceTextures.push_back(newMat); + + mConvexSEL->mSurfaceUVs[mFaceSEL].matID = mConvexSEL->mSurfaceTextures.size(); + } + } + else + { + mConvexSEL->mSurfaceUVs[mFaceSEL].matID = 0; + } + + //run through and find out if there are any other faces still using the old mat texture + if (oldmatID != 0) + { + S32 curMatCount = mConvexSEL->mSurfaceTextures.size(); + + bool used = false; + for (U32 i = 0; i < mConvexSEL->mSurfaceUVs.size(); i++) + { + if (mConvexSEL->mSurfaceUVs[i].matID == oldmatID) + { + used = true; + break; + } + } + + if (!used) + { + //that was the last reference, so let's update the listings on the shape + if (mConvexSEL->mSurfaceTextures[oldmatID - 1].materialInst) + SAFE_DELETE(mConvexSEL->mSurfaceTextures[oldmatID - 1].materialInst); + + mConvexSEL->mSurfaceTextures.erase(oldmatID-1); + + for (U32 i = 0; i < mConvexSEL->mSurfaceUVs.size(); i++) + { + if (mConvexSEL->mSurfaceUVs[i].matID > oldmatID) + mConvexSEL->mSurfaceUVs[i].matID--; + } + } + } + + //mConvexSEL->mSurfaceUVs[mFaceSEL].materialName = materialName; + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); +} + +void GuiConvexEditorCtrl::setSelectedFaceHorzFlip(bool flipped) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + mConvexSEL->mSurfaceUVs[mFaceSEL].horzFlip = flipped; + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); +} + +void GuiConvexEditorCtrl::setSelectedFaceVertFlip(bool flipped) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + mConvexSEL->mSurfaceUVs[mFaceSEL].vertFlip = flipped; + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); +} + +void GuiConvexEditorCtrl::setSelectedFaceZRot(float degrees) +{ + if (mFaceSEL == -1 || mConvexSEL == NULL) + return; + + F32 oldRot = mDegToRad(mConvexSEL->mSurfaceUVs[mFaceSEL].zRot); + mConvexSEL->mSurfaceUVs[mFaceSEL].zRot = degrees; + + EulerF curEul = mConvexSEL->mSurfaces[mFaceSEL].toEuler(); + + MatrixF oldRotMat = MatrixF(EulerF(0, 0, -oldRot)); + + mConvexSEL->mSurfaces[mFaceSEL].mul(oldRotMat); + + MatrixF newRotMat = MatrixF(EulerF(0, 0, mDegToRad(mConvexSEL->mSurfaceUVs[mFaceSEL].zRot))); + + mConvexSEL->mSurfaces[mFaceSEL].mul(newRotMat); + + //Point3F curPos = mConvexSEL->mSurfaces[mFaceSEL].getPosition(); + + //we roll back our existing modified rotation before setting the new one, just to keep it consistent + //const MatrixF &gMat = MatrixF(EulerF(curEul.x, curEul.y, curEul.z - oldRot + mDegToRad(mConvexSEL->mSurfaceUVs[mFaceSEL].zRot)), curPos); + + //mConvexSEL->mSurfaces[mFaceSEL] = MatrixF(EulerF(curEul.x, curEul.y, mDegToRad(mConvexSEL->mSurfaceUVs[mFaceSEL].zRot)), curPos); + + /*MatrixF surfMat; + surfMat.mul(mConvexSEL->mWorldToObj, gMat); + + MatrixF worldToObj(mConvexSEL->getTransform()); + worldToObj.scale(mConvexSEL->getScale()); + worldToObj.inverse(); + + Point3F newPos; + newPos = gMat.getPosition(); + + worldToObj.mulP(newPos); + surfMat.setPosition(newPos); + + // Clear out floating point errors. + cleanMatrix(surfMat); + + mConvexSEL->mSurfaces[mFaceSEL] = surfMat;*/ + + updateShape(mConvexSEL, mFaceSEL); + + mConvexSEL->setMaskBits(ConvexShape::UpdateMask); + + /* + const MatrixF &gMat = mGizmo->getTransform(); + MatrixF surfMat; + surfMat.mul( mConvexSEL->mWorldToObj, gMat ); + + MatrixF worldToObj ( mConvexSEL->getTransform() ); + worldToObj.scale( mConvexSEL->getScale() ); + worldToObj.inverse(); + + Point3F newPos; + newPos = gMat.getPosition(); + + worldToObj.mulP( newPos ); + surfMat.setPosition( newPos ); + + // Clear out floating point errors. + cleanMatrix( surfMat ); + + if (mGizmo->getSelection() == Gizmo::Axis_Z) + { + MatrixF curSurfMat = mConvexSEL->mSurfaces[mFaceSEL]; + EulerF curSufRot = curSurfMat.toEuler(); + + EulerF newSufRot = surfMat.toEuler(); + + float zRot = mRadToDeg(newSufRot.z - curSufRot.z); + + float curZRot = mConvexSEL->mSurfaceTextures[mFaceSEL].zRot; + + mConvexSEL->mSurfaceTextures[mFaceSEL].zRot += zRot; + } + + mConvexSEL->mSurfaces[mFaceSEL] = surfMat; + + updateShape( mConvexSEL, mFaceSEL ); + */ +} + +void GuiConvexEditorCtrl::toggleGridSnapping() +{ + if (mGridSnap) + mGridSnap = false; + else + mGridSnap = true; +} + +void GuiConvexEditorCtrl::updateShape() +{ + if (mConvexSEL) + mConvexSEL->inspectPostApply(); +} + +void GuiConvexEditorCtrl::setGridSnapSize(float gridSize) +{ + mGridPlaneSize = gridSize; +} + void GuiConvexEditorUndoAction::undo() { ConvexShape *object = NULL; @@ -2514,3 +2899,188 @@ DefineEngineMethod( GuiConvexEditorCtrl, splitSelectedFace, void, (), , "" ) { object->splitSelectedFace(); } + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceUVOffset, Point2F, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + return object->getSelectedFaceUVOffset(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceUVScale, Point2F, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + return object->getSelectedFaceUVScale(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceUVOffset, void, ( Point2F offset ), ( Point2F(0,0) ), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + return object->setSelectedFaceUVOffset(offset); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceUVScale, void, (Point2F scale), (Point2F(0, 0)), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + return object->setSelectedFaceUVScale(scale); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceMaterial, void, (const char* materialName), (""), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + if (!dStrcmp(materialName, "")) + return; + + object->setSelectedFaceMaterial(materialName); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceMaterial, const char*, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + return object->getSelectedFaceMaterial(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceHorzFlip, void, (bool flipped), (false), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + object->setSelectedFaceHorzFlip(flipped); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceVertFlip, void, (bool flipped), (false), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + object->setSelectedFaceVertFlip(flipped); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceHorzFlip, bool, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + return object->getSelectedFaceHorzFlip(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceVertFlip, bool, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + return object->getSelectedFaceVertFlip(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setSelectedFaceZRot, void, (float degrees), (0.0), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + object->setSelectedFaceZRot(degrees); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getSelectedFaceZRot, float, (), , + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + return object->getSelectedFaceZRot(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, toggleGridSnapping, void, (),, + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + object->toggleGridSnapping(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, setGridSnapSize, void, (float gridSize), (1.0), + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + object->setGridSnapSize(gridSize); +} + +DefineEngineMethod(GuiConvexEditorCtrl, getGridSnapSize, float, (),, + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + return object->getGridSnapSize(); +} + +DefineEngineMethod(GuiConvexEditorCtrl, updateShape, void, (),, + "@brief Mount objB to this object at the desired slot with optional transform.\n\n" + + "@param objB Object to mount onto us\n" + "@param slot Mount slot ID\n" + "@param txfm (optional) mount offset transform\n" + "@return true if successful, false if failed (objB is not valid)") +{ + //return Point2F(0, 0); + return object->updateShape(); +} diff --git a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.h b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.h index dbf8f267f..3f4b91606 100644 --- a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.h +++ b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.h @@ -116,6 +116,25 @@ public: SceneObject* createPolyhedralObject(const char* className, SceneObject* geometryProvider); ConvexShape* createConvexShapeFrom(SceneObject* polyObject); + Point2F getSelectedFaceUVOffset(); + Point2F getSelectedFaceUVScale(); + const char* getSelectedFaceMaterial(); + bool getSelectedFaceHorzFlip(); + bool getSelectedFaceVertFlip(); + float getSelectedFaceZRot(); + + void setSelectedFaceUVOffset(Point2F offset); + void setSelectedFaceUVScale(Point2F offset); + void setSelectedFaceMaterial(const char* materialName); + void setSelectedFaceHorzFlip(bool flipped); + void setSelectedFaceVertFlip(bool flipped); + void setSelectedFaceZRot(float degrees); + void toggleGridSnapping(); + void setGridSnapSize(float gridSize); + + void updateShape(); + + float getGridSnapSize() { return mGridPlaneSize; } /// Interface with Tools. /// @{ @@ -158,6 +177,20 @@ protected: U32 mSavedGizmoFlags; + Vector> mSelectedBrushes; + struct selectedFace + { + SimObjectPtr mOwnerBrush; + U32 faceId; + }; + Vector mSelectedFaces; + + struct selectedVert + { + SimObjectPtr mOwnerBrush; + U32 vertId; + }; + Vector mSelectedVerts; /// The selected ConvexShape. SimObjectPtr mConvexSEL; @@ -183,6 +216,8 @@ protected: bool mHasCopied; RayInfo mLastRayInfo; + bool mGridSnap; + Gui3DMouseEvent mMouseDownEvent; Point3F mGizmoMatOffset; diff --git a/Engine/source/materials/processedShaderMaterial.cpp b/Engine/source/materials/processedShaderMaterial.cpp index b6c3d5fe0..420fccba0 100644 --- a/Engine/source/materials/processedShaderMaterial.cpp +++ b/Engine/source/materials/processedShaderMaterial.cpp @@ -1211,31 +1211,6 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons shaderConsts->set( handles->mAccuCoverageSC, mMaterial->mAccuCoverage[stageNum] ); if( handles->mAccuSpecularSC->isValid() ) shaderConsts->set( handles->mAccuSpecularSC, mMaterial->mAccuSpecular[stageNum] ); - - /*for (U32 i = 0; i < sgData.customShaderData.size(); i++) - { - //roll through and try setting our data! - for (U32 h = 0; h < handles->mCustomHandles.size(); ++h) - { - StringTableEntry handleName = sgData.customShaderData[i]->getHandleName(); - StringTableEntry rpdHandleName = handles->mCustomHandles[h].handleName; - if (handles->mCustomHandles[h].handleName == sgData.customShaderData[i]->getHandleName()) - { - if (handles->mCustomHandles[h].handle->isValid()) - { - if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float2) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat2()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float3) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat3()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float4) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat4()); - break; -} - } - } - }*/ } bool ProcessedShaderMaterial::_hasCubemap(U32 pass) @@ -1383,31 +1358,6 @@ void ProcessedShaderMaterial::setSceneInfo(SceneRenderState * state, const Scene for (U32 i = 0; i < rpd->featureShaderHandles.size(); i++) rpd->featureShaderHandles[i]->setConsts(state, sgData, shaderConsts); - /*for (U32 i = 0; i < sgData.customShaderData.size(); i++) - { - //roll through and try setting our data! - for (U32 h = 0; h < handles->mCustomHandles.size(); ++h) - { - StringTableEntry handleName = sgData.customShaderData[i]->getHandleName(); - StringTableEntry rpdHandleName = handles->mCustomHandles[h].handleName; - if (handles->mCustomHandles[h].handleName == sgData.customShaderData[i]->getHandleName()) - { - if (handles->mCustomHandles[h].handle->isValid()) - { - if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float2) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat2()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float3) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat3()); - else if (sgData.customShaderData[i]->getType() == CustomShaderBindingData::Float4) - shaderConsts->setSafe(handles->mCustomHandles[h].handle, sgData.customShaderData[i]->getFloat4()); - break; - } - } - } - }*/ - LIGHTMGR->setLightInfo(this, mMaterial, sgData, state, pass, shaderConsts); PROBEMGR->setProbeInfo(this, mMaterial, sgData, state, pass, shaderConsts); diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft index 8ac49b72a6b857b4d31e06e1b69c3fdff4d1c95c..acbb4bed2bb4953916f4db5059a890a1da98aabe 100644 GIT binary patch delta 1949 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 diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft index 8c6586e24b29c2cc61e38292839cb540b457a591..0e9d41ff3c834771d3e9021027bfa4cb612f581d 100644 GIT binary patch delta 1241 zcmX@Zvrk}x2BX|Y&FM_c3=Bn+85w06%O~qH$ud?=wq+D&=U@PVrit0IjO~;8nPk=b zzyb^mtU#I#h#8?Y3s`(Im}FpJpWMhO$~X(CL!6Og@?Ivbdgj}nE{-7;bKYJNoS+;n za_pl$ixd-Y+X5h6Zx~hp47A8Yus)A{^Jb=uLE=cIsA9Ds#v`D_}fDF zZ`TtTc5?R#EU`Ir;LjPxBl--VA0}{~WXMTRQ-3D-aGFY!+qoo;DJm0BXHH2-b69TU ze}MVkL=~mZ(`@I3^P>9eqr0RZ=+!abh`)T(N$BCx-S!`tFFmL_Ug0-IK-b{K8-}zr z!zGNfC%75f&cCO{GQ;NI3x{Vf-tjcdy{V~C+)$YDh+jNKuPSv%%QdkdX@=~^#_Tn3 zCtDhA|8uB1eHM?{cb+a+_P8X5=8HT=o3pO|`}2=o^Iqq5K~EPWwfDa>dFok=_3sET z2{3!HH;;+o{R_qxSEh5z{#EVSpS|X|UUR{98-}{4XWr~svAgF9_h&;Nd4@%MPwQEq zQ`^Ba-7xAp-<)-aPBq$F@^~^gtf}A1UnqI^{k`Yk&tE(9MyvR_^TO%j{yXOMwwEjM z9!M}-QPWVs>hStXQ-+!4v6f0hMXv+a^}ON^8#;v;7PXw2xb?wa)(4@}J8xxk1UgL# z&_Aqd96jx8Fz>oP5#EN~S+Q3;C-qBz+{xyhaQC<7JpQcy`%NN0F77_}`uXZQ%@+^# z&-ov46?$m9@9gmdHM3mgH*Ws5&`qw&|NHb4B~|l$l_K(%Jzw%==ewi!=N_+$-5ozy z{6$WEefaGE@2a_H^w)RYf3`f-n71LWkmKZRhTmciTh}q)ylTI5=FGLTcbn~a^C_z6 zXT$vEcixq+?f1wFi^-E#em!q;)aq4HThBe-v0+PTWJ2+0>FB@yaqj!4YR81 z!r!TDo}W~ouBe0y)Z>z%n)v)z`3JohcJNNRzYSCfc)I$ztaD0eS_ml-^1+k>kgNpa zI3TXLHMKXA>wp4}%jMejcfa5JKckH6vtm*!pG}-kPnX9UTfvDkEBYh3jIMFdkSQ0k z`t;}HvW-=n1K0P>?S1z`T4uoo`{ucKt*(D@{eEl>E2D%1ht@a$s**kNb{CXC9035f CO#n*( delta 892 zcmdldaE51s2BX+U&FM^&H!!Q$Gd=TkaSW-L^Y)5hfl9PU`$v8z=Ek-I2b>N&C-L(Z%0Sh_T{_gI{nt{ zoSZUw&OOz`QVCc6%^jwe&Td}JdYEg$c9tKX=B<}MA-}7+tY~BPhDSS8?oOKi;p3zv zwsu_yTc1}fQDvLv{%cG6X7%^4S6FXe{muAEdY;#H_!SstnM6B>6e;t`#pOSf9!tNlWw>sbCMq~_ zpId$R|ICn!H;aBwG+M5c(dKE&wkb1xgUafJ&F=p{*)hLZW6jXKt;NJ|Qsu@!$@y_h zOnJoaicYXuCb)6mE#K@@_A^Bbinu1|U;Y*P>-W<3j*jxuQOzGs@=g`*l>J;qv}UDaP}s=A66vb`3+Cdg?#_Zz<(losD12ssA-` zk8XVRfi*ug?X$L(-_>IN^)}1lGHb*)2D#_E9sa&^&y^MY{4PoU(yz*>PkS6Mg~;fN z@2#Kwf9dJ|{h?;^_4_{9#`%W*^}G7~BzL^?Bo$9up)ZT}F;DGRi1`pVcRvFVc)I$z ztaHjvXet8npg;jgR|0V$5LetvPDn`j+0SlZU{JtdXwPS9rjX|Ts5>F>FxS$VA8#-+ z?a4@5^uLqAp_D13=G=b~rUjBV88wb7X7U2YOdACRj2R8hXGJCIJS${mnD>|eIRG#z BgMt76 diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Lucida Console 12 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Lucida Console 12 (ansi).uft index e06fa806cc3b4859066a167838ac4c392dfd0e32..b3a06bb07490b0e5a607997f6ce1d1bc82782d69 100644 GIT binary patch delta 2414 zcmb`J`#;l*AICp)HKa@a09t7y z63Q?pZB$HIt_J{sJ-dkRBEAc37fBi!jsPVrElkhbk~3!qj`~k`sdOxs{c+Cp$bJb^ zQ6by`>bZZ6`uvB8r{1C)(hll|fz{m&3Fdx-yc_;b(FeAUp)kH) z@|_6pO8q8=j5m`gMu@|bUvq}x5aiwGQKsc!z5?L%_F&)j`WeJYg_I+d2zhDRtx#M)o6HR5TDelXO2y{sH6R?Y_^j?}af&7gJ+ z5&+E;t(XwOK39AC97)%^fYW6L_|?d6ttNiV?~A{S`E&(vG#|1fdwzgdaOiY)G2X?GfLM-Pe{Y={(R}4^~d@m ze)RF>f;&r>9;vTjGky#0`b&LswJx$0+bFg`VMngv?r7Aoohp2B8<;ZKcVfT9M5|ss zUMKLDi~*j?t5wlQ*J_1X!|tjBq-z5PidO}o zmd->t1O_xeNN1%}51D#-c<@Ikwn(8VtIiPlK5Llm%52d_z@6U1{`G?swML~b^m0}2 zE?3P4Rudy&ASJBIZM>T4i0-_IUr2f8#`u(NtWyMFI|4+fjnmB6&^QY+JZIU)vtiiq zew%F{CkPnAZx06U{L+?o2hDC_Nu5d{6|hM?37Uo@jS%mh?yW{(F(&1FJk+^OG)HO!Je z(xi8mRd)HGC1px=_J2ht3Q4e_RCQYFQo(3MC3ZG)!H`3N=Tw4whdPc&eLsPYJ+^4l z*%0fh(|Cn_p+)7L&!9Ki$*q~Ir_0C|2FS*#F5)pgZF_m1kEw@dY^v55VC!YMEg`i) z$HYq}koPQv7{y|D#-E*iQI;GB9Ep5?n8iyyoui{4HCUX>6QtLC+uL~ha(_yZt4n(F z`vG@q?!*Hw8cMfva&!GQrq|Z>?bnbr&H75-?qqfDren$4* zw3DvaRY=U>B`+p#C-?Egkxk{KTD`_a&!njNo>yEK(Q@5J{!^H2BzxyPzzn@bm{53N zoXbpsAVztmd-KUM%?KNT55DVHAIF?(v{>JGmWQYM7+9V7SQTGE5V!;RF`)Z#A@Ljte(fd zBSYihnPra_M>#5|7pkU{#nZ>BxC2vl)+GRsF!`!kPk2ctkNyJGW{1GuocFg5YV_+> z3Jh>Y#cX053pux{lzP^kf#N~E5l&TA41S`?>t0Pjt~Mp#faNxEQ+Uda&erPL`lw9O z8AHhGx92fgC_o0V%L+IfZkaA=YQqA zoDTkSFvNA>VFo$Jeg?Mu>E>f@+nVbznL?Pq{gu1EGx?|>eC z&K4q^z7E(^4lCKC!a|qL08n3*t){!Ok(2zyH7UD@>f@XJfYij$-5>&0Ey{`|Z<=|N zd-5<(jGV-hltwOW7#-}nCLX_poyr!TGNzv8=NUuZH!Lns8~KIA+XiLv*A`QS;C29c zI_PWPPbd9=Gw#k=OR+z}DxQFDEChApvV|S~Z@@!)ZhXwpZaACuU}h65J#1I9 zyhDp8P;zGPM8?h1Iwaggx^7J2 z-i|HMz2zIWQ|~9a7=Up`Tuf#Z~V+N8HNioA*yvj?J66FOPz*t?dT%tsUTKHOo(OOH!2KpKe8X5*1w^*f)@W&z1C1_bT`=Go`F) delta 2293 zcmchQ`!~}M1IItx%(cPbvX!mUL19}vXz_7yyp__yWKjX|g@4Mvv$Jb^AZiOO2EQ); zuiM}L_|KZ0ER4dvvImDRZ#0e1-{BnQZ7~+YbHi@)PtE4ZeP%&DPrfdUpW{$zeJYJY zU4Mz|pajz@@$b-A5YNaV8_FhHEy?`HIdVqsDS^^PW3qlj;zr6RA=P%UMz5tvC<;Zb zqOr6+5j^06;Rc-WYYjFaG~9G^ypBeM&TSpb^U++OeYh}C_@?zHy9??#9>rvQ)j-3V zKGZ6IzC|raKr3XAZfi$^tJi@zC0Yv#%4mn{0CjNsiN58!3x5S(LktLi`)K&iUH^8uq!}`Pfi7h{(ySiw5OmKDKvURo zne$w{$W&3(o1aqmab{_hZ#Ph=RW&99zo12+BZ4JaI`D=mTPBM69#(8x3KNmxBD!t);-hir`DmV$-nQ zV(sR}S&Y!pvy(nkbL}V?$6vrG7IOpvBZ8z*hNT|Y_8C5^6Be@bY(5#(tG z1y<^fn*{}nQjU(yoPZ1u6$QMRHeb)TA-=?b9x`(|AX~?uAAwvNNp*w%(t`X2Ojx%F z)2+2>CvYbKRLA|AT+PeRhj)@Ll+>RR-=3(jZ|@dcX#G;M9E69()b_WnJvpFa9;%8g z;NXJs{m*|}1oe7f+;B2>x0sw3>^Q4zii_{Asabvw&ke2dX!nSfc5Yo3C-@IzUgCCJ zl|byG;3PJ*+Ms!J91v|<MaJ+0F05O- z!`I*c?(l!SoACf!i?-w^@eKe@fx@RfW;3sLueinV{84Yo5G1%pGOuCr$56|>&}qxq z)zl5D8lv=BL+5Na$QywR?oZ9hxe0o44tC^jve8?7g!UK)300yQ)H<25;#J7+UjTJi zN)H3n>Ikoyry#OqF{PYlJRS*{p2nQHO1se`cRTX(cH-{BatX>KI&7FFUvWw(zpF8I zZEIDG60CA^S;orj=R^phJH6W^LpG|g+DJ;issP9as=28z{p-pPlu}dbzgs|PzOCv+ zEdJFXjdDRSV*Grpb}%wIx?Tu;7!k4{IJ+U11r(i zcN{~I9od7QT*{d8m~U@r;6p4@TtDa%Bk%ihujZg^hz>9TF(77d%Tdnh*+YBJWQz2y zfS&ZgZDYbfuHxi%2*e=_uIe&`!9`~Z^X@Bqyr@_zT5n|%?J_TUH=aAzB~J?DCW zhRgn$Yzj8#yJxt$AtyRqP%uijQ}qf~Wmtw^=_Z`MSh6Fwpl-t*`eMQRN*exa(1Wpn z`E?ACdIrTzcNAgu!qCzM0+?N@y46*h*i#2tLGs$VF~=nWFVFV;wi*X?UDIOvIO8^=pL`UiUU%e3I2P6k zdXi;MU0zBN=s6JC(5?qWJ>FZ|(NTdn6E673W>&_ab9>3_iTZsd|hjo0hWc9tT;WriT&Rj{FK5=IZ!tJ*)ncN^UzdOmW z`IgZzK7uQ?+2_=Y#I3iTHY65g?acYi8pm#3U4>6+cJp1KcBOQF09kW6BcTVfyy7rz zd6*DJn`GTx#4nnfvs0f?cgJQRS@Wt;O66!1&!MP$`}qGS`2W4(y8M>dH4+FgDm%0Z z?8m{**|y5sFX7{UKk$#(kJ3K4eM4ev+ywm>k-bD>H~hK5X|`n*E-$3>Qm1wNj9)s-SsL3EUo2=PWE8Y z=cd`s=1ZQ%=aL{sYIWu2wu!Vw$ub n&~FEZXR`xxa0q)n2SqQ0!|ikV(C4GG6rK8tU9e`f#^}ERbJ9n4 diff --git a/Templates/BaseGame/game/tools/MainEditor/MainEditor.cs b/Templates/BaseGame/game/tools/MainEditor/MainEditor.cs index f81e7648b..5b41705f7 100644 --- a/Templates/BaseGame/game/tools/MainEditor/MainEditor.cs +++ b/Templates/BaseGame/game/tools/MainEditor/MainEditor.cs @@ -99,7 +99,7 @@ function togglePanelLayout() } EditorTree.open($scenesRootGroup,true); - + Editor_PropertiesPanel.add(EWInspectorWindow); EWInspectorWindow.resize(0,0, Editor_PropertiesPanel.extent.x, Editor_PropertiesPanel.extent.y); EWInspectorWindow.horizSizing = "width"; diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs index 1cda5416c..e2351dde5 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs @@ -22,6 +22,19 @@ function ConvexEditorGui::onWake( %this ) { + convexEditorToolbar-->gridSnapSizeEdit.setText(%this.getGridSnapSize()); + + if(ConvexEditorOptionssWindow-->matPreviewBtn.bitmap $= "") + { + //no active material, so set one + ConvexEditorOptionssWindow-->matPreviewBtn.setText(""); + + %mat = EditorSettings.Value("ConvexEditor/MaterialName"); + + ConvexEditorOptionssWindow-->matPreviewBtn.setBitmap(%mat.diffuseMap[0]); + + ConvexEditorOptionssWindow.activeMaterial = %mat; + } } function ConvexEditorGui::onSleep( %this ) @@ -45,18 +58,159 @@ function ConvexEditorGui::onSelectionChanged( %this, %shape, %face ) ConvexEditorDeleteFaceBtn.setActive( false ); ConvexEditorDeleteFaceBtn.ToolTip = "Delete selection [Disabled] (Delete)"; - if ( !isObject( %shape ) ) + if ( !isObject( %shape ) ) + { + ConvexEditorOptionssWindow-->defMatPreviewBtn.setText("No Brush Selected"); + ConvexEditorOptionssWindow.activeShape = ""; return; + } ConvexEditorDeleteFaceBtn.setActive( true ); + + ConvexEditorOptionssWindow-->defMatPreviewBtn.setText(""); + ConvexEditorOptionssWindow-->defMatPreviewBtn.setBitmap(%shape.material.diffuseMap[0]); + + ConvexEditorOptionssWindow.activeShape = %shape; if ( %face == -1 ) + { ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected ConvexShape (Delete)"; + + ConvexEditorOptionssWindow-->UOffset.setText(""); + ConvexEditorOptionssWindow-->VOffset.setText(""); + + ConvexEditorOptionssWindow-->UScale.setText(""); + ConvexEditorOptionssWindow-->VScale.setText(""); + + ConvexEditorOptionssWindow-->ZRotation.setText(""); + } else { ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected Face (Delete)"; ConvexEditorSplitFaceBtn.ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control"; ConvexEditorSplitFaceBtn.setActive( true ); + + %UVOffset = %this.getSelectedFaceUVOffset(); + + ConvexEditorOptionssWindow-->UOffset.setText(%UVOffset.x); + ConvexEditorOptionssWindow-->VOffset.setText(%UVOffset.y); + + %UVScale = %this.getSelectedFaceUVScale(); + + ConvexEditorOptionssWindow-->UScale.setText(%UVScale.x); + ConvexEditorOptionssWindow-->VScale.setText(%UVScale.y); + + ConvexEditorOptionssWindow-->ZRotation.setText(ConvexEditorGui.getSelectedFaceZRot()); } +} + +function ConvexEditorUVFld::onReturn(%this) +{ + EWorldEditor.isDirty = true; + + %offset = "0 0"; + %offset.x = ConvexEditorOptionssWindow-->UOffset.getText(); + %offset.y = ConvexEditorOptionssWindow-->VOffset.getText(); + + %scale = "0 0"; + %scale.x = ConvexEditorOptionssWindow-->UScale.getText(); + %scale.y = ConvexEditorOptionssWindow-->VScale.getText(); + + %rot = ConvexEditorOptionssWindow-->ZRotation.getText(); + + ConvexEditorGui.setSelectedFaceUVOffset(%offset); + ConvexEditorGui.setSelectedFaceUVScale(%scale); + ConvexEditorGui.setSelectedFaceZRot(%rot); +} + +function ConvexEditorUVHorzFlipBtn::onClick(%this) +{ + EWorldEditor.isDirty = true; + %current = ConvexEditorGui.getSelectedFaceHorzFlip(); + ConvexEditorGui.setSelectedFaceHorzFlip(!%current); +} + +function ConvexEditorUVVertFlipBtn::onClick(%this) +{ + EWorldEditor.isDirty = true; + %current = ConvexEditorGui.getSelectedFaceVertFlip(); + ConvexEditorGui.setSelectedFaceVertFlip(!%current); +} + +function ConvexEditorMaterialBtn::onClick(%this) +{ + %this.getMaterialName(); +} + +function ConvexEditorMaterialBtn::getMaterialName(%this) +{ + materialSelector.showDialog(%this @ ".gotMaterialName", "name"); +} + +function ConvexEditorMaterialBtn::gotMaterialName(%this, %name) +{ + //eval(%this.object @ "." @ %this.targetField @ " = " @ %name @ ";"); + //%this.object.changeMaterial(getTrailingNumber(%this.targetField), %name); + //%this.object.inspectorApply(); + %diffusemap = %name.diffuseMap[0]; + + ConvexEditorOptionssWindow-->matPreviewBtn.setBitmap(%diffusemap); + + ConvexEditorOptionssWindow.activeMaterial = %name; +} + +function ConvexEditorMaterialApplyBtn::onClick(%this) +{ + EWorldEditor.isDirty = true; + ConvexEditorGui.setSelectedFaceMaterial(ConvexEditorOptionssWindow.activeMaterial); + ConvexEditorGui.updateShape(); +} + +function ConvexEditorMaterialLiftBtn::onClick(%this) +{ + %mat = ConvexEditorGui.getSelectedFaceMaterial(); + ConvexEditorOptionssWindow.activeMaterial = %mat; + ConvexEditorOptionssWindow-->matPreviewBtn.setBitmap(%mat.diffuseMap[0]); +} + +function ConvexEditorMaterialResetBtn::onClick(%this) +{ + EWorldEditor.isDirty = true; + ConvexEditorGui.setSelectedFaceMaterial(ConvexEditorOptionssWindow.activeShape.material); + ConvexEditorGui.updateShape(); +} + +function ConvexEditorGui::toggleGridSnap(%this) +{ + %this.toggleGridSnapping(); +} + +function ConvexEditorGridSnapSizeFld::onReturn(%this) +{ + ConvexEditorGui.setGridSnapSize(%this.getText()); +} + +function ConvexEditorDefaultMaterialBtn::onClick(%this) +{ + %this.getMaterialName(); +} + +function ConvexEditorDefaultMaterialBtn::getMaterialName(%this) +{ + materialSelector.showDialog(%this @ ".gotMaterialName", "name"); +} + +function ConvexEditorDefaultMaterialBtn::gotMaterialName(%this, %name) +{ + //eval(%this.object @ "." @ %this.targetField @ " = " @ %name @ ";"); + //%this.object.changeMaterial(getTrailingNumber(%this.targetField), %name); + //%this.object.inspectorApply(); + %diffusemap = %name.diffuseMap[0]; + + ConvexEditorOptionssWindow-->defMatPreviewBtn.setBitmap(%diffusemap); + + ConvexEditorOptionssWindow.activeShape.material = %name; + + ConvexEditorGui.updateShape(); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui b/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui index 575907d81..bd76a265e 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui @@ -21,6 +21,95 @@ EdgeSnap = "0"; text =""; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "15 7"; + extent = "86 16"; + minExtent = "8 8"; + visible = "1"; + text = "Sketch Tool"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "94 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl(ConvexEditorCreateBoxBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "100 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.createConvexBox();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create ConvexShape Box" NL "Use Alt + Click-Drag instead of this for more control of starting placement."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/convex-editor-btn"; + text = ""; + groupNum = "-1"; + buttonType = "pushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorSplitFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "134 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.splitSelectedFace();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/split-face-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorDeleteFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "166 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.handleDelete();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete selected face" NL "(Delete)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/delete-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "190 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; new GuiContainer() { canSaveDynamicFields = "0"; Enabled = "1"; @@ -28,94 +117,87 @@ Profile = "menubarProfile"; HorizSizing = "width"; VertSizing = "bottom"; - Position = "0 0"; - Extent = "800 32"; + Position = "195 0"; + Extent = "190 32"; MinExtent = "8 8"; canSave = "1"; Visible = "1"; hovertime = "1000"; - + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectGridSnapBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.toggleGridSnap();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles grid snapping (G)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-grid"; + textMargin = "4"; + }; new GuiTextCtrl() { - profile = "ToolsGuiTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "15 7"; - extent = "86 16"; - minExtent = "8 8"; - visible = "1"; - text = "Sketch Tool"; - maxLength = "255"; - helpTag = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 10"; + Extent = "108 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Grid snap size(m)"; + maxLength = "1024"; }; - new GuiBitmapCtrl() { - Profile = "ToolsGuiDefaultProfile"; - position = "94 3"; - Extent = "2 26"; - MinExtent = "1 1"; - bitmap = "tools/gui/images/separator-h.png"; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "gridSnapSizeEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "130 6"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + class = "ConvexEditorGridSnapSizeFld"; + hovertime = "1000"; + text = "1"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; }; - new GuiBitmapButtonCtrl(ConvexEditorCreateBoxBtn) { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "100 3"; - Extent = "29 27"; - MinExtent = "8 8"; - canSave = "1"; - Visible = "1"; - Command = "ConvexEditorGui.createConvexBox();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - ToolTip = "Create ConvexShape Box" NL "Use Alt + Click-Drag instead of this for more control of starting placement."; - hovertime = "1000"; - bitmap = "tools/convexEditor/images/convex-editor-btn"; - text = ""; - groupNum = "-1"; - buttonType = "pushButton"; - useMouseEvents = "0"; - }; - new GuiBitmapButtonCtrl(ConvexEditorSplitFaceBtn) { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "134 3"; - Extent = "29 27"; - MinExtent = "8 8"; - canSave = "1"; - Visible = "1"; - Command = "ConvexEditorGui.splitSelectedFace();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control."; - hovertime = "1000"; - bitmap = "tools/convexEditor/images/split-face-btn"; - text = ""; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiBitmapButtonCtrl(ConvexEditorDeleteFaceBtn) { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "166 3"; - Extent = "29 27"; - MinExtent = "8 8"; - canSave = "1"; - Visible = "1"; - Command = "ConvexEditorGui.handleDelete();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - ToolTip = "Delete selected face" NL "(Delete)"; - hovertime = "1000"; - bitmap = "tools/gui/images/menubar/delete-btn"; - text = ""; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "380 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; }; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/main.cs b/Templates/BaseGame/game/tools/convexEditor/main.cs index 4577f20e2..c5a320898 100644 --- a/Templates/BaseGame/game/tools/convexEditor/main.cs +++ b/Templates/BaseGame/game/tools/convexEditor/main.cs @@ -28,16 +28,20 @@ function initializeConvexEditor() exec( "./convexEditorGui.gui" ); exec( "./convexEditorToolbar.ed.gui" ); exec( "./convexEditorGui.cs" ); - + exec( "./convexEditorSidebarGui.gui" ); + exec( "./materials.cs" ); + ConvexEditorGui.setVisible( false ); ConvexEditorOptionsWindow.setVisible( false ); ConvexEditorTreeWindow.setVisible( false ); ConvexEditorToolbar.setVisible( false ); + ConvexEditorOptionssWindow.setVisible( false ); EditorGui.add( ConvexEditorGui ); EditorGui.add( ConvexEditorOptionsWindow ); EditorGui.add( ConvexEditorTreeWindow ); EditorGui.add( ConvexEditorToolbar ); + EditorGui.add( ConvexEditorOptionssWindow ); new ScriptObject( ConvexEditorPlugin ) { @@ -98,6 +102,7 @@ function ConvexEditorPlugin::onActivated( %this ) EditorGui.bringToFront( ConvexEditorGui ); ConvexEditorGui.setVisible( true ); ConvexEditorToolbar.setVisible( true ); + ConvexEditorOptionssWindow.setVisible( true ); ConvexEditorGui.makeFirstResponder( true ); %this.map.push(); @@ -132,6 +137,7 @@ function ConvexEditorPlugin::onDeactivated( %this ) ConvexEditorGui.setVisible( false ); ConvexEditorOptionsWindow.setVisible( false ); ConvexEditorTreeWindow.setVisible( false ); + ConvexEditorOptionssWindow.setVisible( false ); ConvexEditorToolbar.setVisible( false ); %this.map.pop(); diff --git a/Templates/BaseGame/game/tools/main.cs b/Templates/BaseGame/game/tools/main.cs index 9f53adaca..23e0ee4b0 100644 --- a/Templates/BaseGame/game/tools/main.cs +++ b/Templates/BaseGame/game/tools/main.cs @@ -153,7 +153,6 @@ package Tools popInstantGroup(); $instantGroup = MissionCleanup; pushInstantGroup(); - } function startToolTime(%tool) diff --git a/Templates/BaseGame/game/tools/settings.xml b/Templates/BaseGame/game/tools/settings.xml index e099e13cf..2f8de41ac 100644 --- a/Templates/BaseGame/game/tools/settings.xml +++ b/Templates/BaseGame/game/tools/settings.xml @@ -1,65 +1,45 @@ - 100 - 0.8 - 15 0 - 0 1 + 100 + 15 + 0 0.8 + 0.8 - 500 - 255 255 255 20 - 0 + 0 10 10 10 0 - 0 + 0 + 255 255 255 20 + 500 - 6 - screenCenter - 50 - 40 - 1 0 + 6 + 50 + 1 WorldEditorInspectorPlugin - - 0 - 51 51 51 100 - 102 102 102 100 - 1 - 255 255 255 100 - - - http://www.garagegames.com/products/torque-3d/forums - http://www.garagegames.com/products/torque-3d/documentation/user - ../../../Documentation/Torque 3D - Script Manual.chm - ../../../Documentation/Official Documentation.html - - - 1 - 1 - 1 - 1 - 1 - + screenCenter + 40 - 255 0 0 255 - 255 255 0 255 - 255 255 255 255 100 100 100 255 0 0 255 255 255 255 0 255 + 255 255 255 255 + 255 0 0 255 + 255 255 0 255 0 255 0 255 - 1 - 0 255 20 8 + 1 + 0 tools/worldEditor/images/SelectHandle @@ -67,17 +47,68 @@ tools/worldEditor/images/DefaultHandle - 1 - 0 - 0 - 0 2 + 0 100 + 1 + 0 1 + 0 + + + 1 + 1 + 1 + 1 + 1 + + + 51 51 51 100 + 0 + 255 255 255 100 + 1 + 102 102 102 100 + + + http://www.garagegames.com/products/torque-3d/forums + http://www.garagegames.com/products/torque-3d/documentation/user + ../../../Documentation/Official Documentation.html + ../../../Documentation/Torque 3D - Script Manual.chm - - AIPlayer + + tools/materialEditor/gui + 1024 768 + + 1 + 2 + 1 + 1 + 8 + 1 + 0 + 1 + + + 1 + 1 + + + http://www.garagegames.com/products/torque-3d/documentation/user + ../../../Documentation/Torque 3D - Script Manual.chm + ../../../Documentation/Official Documentation.html + + + Categorized + + + 0 + 0 + 0 + + + 0 + data/FPSGameplay/levels @@ -87,4 +118,10 @@ + + AIPlayer + + + Grid_512_Orange + diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui index fce36e940..ef7ff4dca 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -877,6 +877,24 @@ function ObjectBuilderGui::buildParticleSimulation(%this) %this.process(); } +function ObjectBuilderGui::buildReflectionProbe(%this) +{ + %this.objectClassName = "ReflectionProbe"; + %this.process(); + + %defaultPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + %this.addField("reflectionPath", "TypeFilepath", "reflectionPath", %defaultPath); +} + +function ObjectBuilderGui::buildSkylight(%this) +{ + %this.objectClassName = "Skylight"; + %this.process(); + + %defaultPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + %this.addField("reflectionPath", "TypeFilepath", "reflectionPath", %defaultPath); +} + //------------------------------------------------------------------------------ // Mission //------------------------------------------------------------------------------ diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs index 912ff7a35..ff1aba119 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -55,6 +55,11 @@ function EWCreatorWindow::init( %this ) %this.registerMissionObject( "PointLight", "Point Light" ); %this.registerMissionObject( "SpotLight", "Spot Light" ); + + %this.registerMissionObject( "BoxEnvironmentProbe", "Box Environment Probe" ); + %this.registerMissionObject( "SphereEnvironmentProbe", "Sphere Environment Probe" ); + %this.registerMissionObject( "Skylight", "Skylight" ); + %this.registerMissionObject( "GroundCover", "Ground Cover" ); %this.registerMissionObject( "TerrainBlock", "Terrain Block" ); %this.registerMissionObject( "GroundPlane", "Ground Plane" ); @@ -85,6 +90,8 @@ function EWCreatorWindow::init( %this ) %this.registerMissionObject( "SFXSpace", "Sound Space" ); %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" ); %this.registerMissionObject( "AccumulationVolume", "Accumulation Volume" ); + %this.registerMissionObject("NavMesh", "Navigation mesh"); + %this.registerMissionObject("NavPath", "Path"); %this.registerMissionObject( "Entity", "Entity" ); %this.endGroup(); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs index 8886b8eb9..180504f38 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs @@ -61,3 +61,8 @@ function EditorLightingMenu::onMenuSelect( %this ) //%selSize = EWorldEditor.getSelectionSize(); %this.enableItem( 1, true /*%selSize == 1*/ ); } + +function updateReflectionProbes() +{ + Canvas.pushDialog(ProbeBakeDlg); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs index bb5f9cf4d..7f87df251 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs @@ -322,6 +322,8 @@ function EditorGui::buildMenus(%this) item[0] = "Full Relight" TAB "Alt L" TAB "Editor.lightScene(\"\", forceAlways);"; item[1] = "Toggle ShadowViz" TAB "" TAB "toggleShadowViz();"; item[2] = "-"; + item[3] = "Update Reflection Probes" TAB "" TAB "updateReflectionProbes();"; + item[4] = "-"; // NOTE: The light managers will be inserted as the // last menu items in EditorLightingMenu::onAdd().