-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix 208, fix vertex click, misc. upgrades #209
base: develop
Are you sure you want to change the base?
Changes from 8 commits
da5a468
3b158f2
535f4c3
c108c32
6099356
a56e884
a22cff9
4903dea
d3d9613
1cd3d8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -357,13 +357,13 @@ void BSShape::drawShapes( NodeList * secondPass, bool presort ) | |
return; | ||
|
||
auto nif = static_cast<const NifModel *>(iBlock.model()); | ||
|
||
bool drawPolygons = true; | ||
if ( Node::SELECTING ) { | ||
if ( scene->selMode & Scene::SelObject ) { | ||
if ( scene->actionMode & Scene::Object ) { | ||
int s_nodeId = ID2COLORKEY( nodeId ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting seems to be all over the shop here. |
||
glColor4ubv( (GLubyte *)&s_nodeId ); | ||
} else { | ||
glColor4f( 0, 0, 0, 1 ); | ||
} else { | ||
drawPolygons = false; | ||
} | ||
} | ||
|
||
|
@@ -384,85 +384,87 @@ void BSShape::drawShapes( NodeList * secondPass, bool presort ) | |
glMultMatrix( viewTrans() ); | ||
} | ||
|
||
// Render polygon fill slightly behind alpha transparency and wireframe | ||
if ( !drawSecond ) { | ||
glEnable( GL_POLYGON_OFFSET_FILL ); | ||
glPolygonOffset( 1.0f, 2.0f ); | ||
} | ||
|
||
glEnableClientState( GL_VERTEX_ARRAY ); | ||
glVertexPointer( 3, GL_FLOAT, 0, transVerts.constData() ); | ||
|
||
if ( !Node::SELECTING ) { | ||
glEnableClientState( GL_NORMAL_ARRAY ); | ||
glNormalPointer( GL_FLOAT, 0, transNorms.constData() ); | ||
|
||
bool doVCs = (bssp && (bssp->getFlags2() & ShaderFlags::SLSF2_Vertex_Colors)); | ||
// Always do vertex colors for FO4 if colors present | ||
if ( nifVersion == 130 && hasVertexColors && colors.count() ) | ||
doVCs = true; | ||
|
||
if ( transColors.count() && (scene->options & Scene::DoVertexColors) && doVCs ) { | ||
glEnableClientState( GL_COLOR_ARRAY ); | ||
glColorPointer( 4, GL_FLOAT, 0, transColors.constData() ); | ||
} else if ( !hasVertexColors && (bslsp && bslsp->hasVertexColors) ) { | ||
// Correctly blacken the mesh if SLSF2_Vertex_Colors is still on | ||
// yet "Has Vertex Colors" is not. | ||
glColor( Color3( 0.0f, 0.0f, 0.0f ) ); | ||
} else { | ||
glColor( Color3( 1.0f, 1.0f, 1.0f ) ); | ||
} | ||
} | ||
|
||
|
||
if ( !Node::SELECTING ) | ||
shader = scene->renderer->setupProgram( this, shader ); | ||
|
||
if ( isDoubleSided ) { | ||
glCullFace( GL_FRONT ); | ||
glDrawElements( GL_TRIANGLES, triangles.count() * 3, GL_UNSIGNED_SHORT, triangles.constData() ); | ||
glCullFace( GL_BACK ); | ||
} | ||
|
||
if ( !isLOD ) { | ||
glDrawElements( GL_TRIANGLES, triangles.count() * 3, GL_UNSIGNED_SHORT, triangles.constData() ); | ||
} else if ( triangles.count() ) { | ||
auto lod0 = nif->get<uint>( iBlock, "LOD0 Size" ); | ||
auto lod1 = nif->get<uint>( iBlock, "LOD1 Size" ); | ||
auto lod2 = nif->get<uint>( iBlock, "LOD2 Size" ); | ||
|
||
auto lod0tris = triangles.mid( 0, lod0 ); | ||
auto lod1tris = triangles.mid( lod0, lod1 ); | ||
auto lod2tris = triangles.mid( lod0 + lod1, lod2 ); | ||
|
||
// If Level2, render all | ||
// If Level1, also render Level0 | ||
switch ( scene->lodLevel ) { | ||
case Scene::Level2: | ||
if ( lod2tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod2tris.count() * 3, GL_UNSIGNED_SHORT, lod2tris.constData() ); | ||
case Scene::Level1: | ||
if ( lod1tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod1tris.count() * 3, GL_UNSIGNED_SHORT, lod1tris.constData() ); | ||
case Scene::Level0: | ||
default: | ||
if ( lod0tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod0tris.count() * 3, GL_UNSIGNED_SHORT, lod0tris.constData() ); | ||
break; | ||
} | ||
} | ||
|
||
if ( !Node::SELECTING ) | ||
scene->renderer->stopProgram(); | ||
|
||
glDisableClientState( GL_VERTEX_ARRAY ); | ||
glDisableClientState( GL_NORMAL_ARRAY ); | ||
glDisableClientState( GL_COLOR_ARRAY ); | ||
|
||
glDisable( GL_POLYGON_OFFSET_FILL ); | ||
|
||
|
||
if ( scene->selMode & Scene::SelVertex ) { | ||
if (drawPolygons) { | ||
|
||
// Render polygon fill slightly behind alpha transparency and wireframe | ||
if ( !drawSecond ) { | ||
glEnable( GL_POLYGON_OFFSET_FILL ); | ||
glPolygonOffset( 1.0f, 2.0f ); | ||
} | ||
|
||
glEnableClientState( GL_VERTEX_ARRAY ); | ||
glVertexPointer( 3, GL_FLOAT, 0, transVerts.constData() ); | ||
|
||
if ( !Node::SELECTING ) { | ||
glEnableClientState( GL_NORMAL_ARRAY ); | ||
glNormalPointer( GL_FLOAT, 0, transNorms.constData() ); | ||
|
||
bool doVCs = (bssp && (bssp->getFlags2() & ShaderFlags::SLSF2_Vertex_Colors)); | ||
// Always do vertex colors for FO4 if colors present | ||
if ( nifVersion == 130 && hasVertexColors && colors.count() ) | ||
doVCs = true; | ||
|
||
if ( transColors.count() && (scene->options & Scene::DoVertexColors) && doVCs ) { | ||
glEnableClientState( GL_COLOR_ARRAY ); | ||
glColorPointer( 4, GL_FLOAT, 0, transColors.constData() ); | ||
} else if ( !hasVertexColors && (bslsp && bslsp->hasVertexColors) ) { | ||
// Correctly blacken the mesh if SLSF2_Vertex_Colors is still on | ||
// yet "Has Vertex Colors" is not. | ||
glColor( Color3( 0.0f, 0.0f, 0.0f ) ); | ||
} else { | ||
glColor( Color3( 1.0f, 1.0f, 1.0f ) ); | ||
} | ||
} | ||
|
||
|
||
if ( !Node::SELECTING ) | ||
shader = scene->renderer->setupProgram( this, shader ); | ||
|
||
if ( isDoubleSided ) { | ||
glCullFace( GL_FRONT ); | ||
glDrawElements( GL_TRIANGLES, triangles.count() * 3, GL_UNSIGNED_SHORT, triangles.constData() ); | ||
glCullFace( GL_BACK ); | ||
} | ||
|
||
if ( !isLOD ) { | ||
glDrawElements( GL_TRIANGLES, triangles.count() * 3, GL_UNSIGNED_SHORT, triangles.constData() ); | ||
} else if ( triangles.count() ) { | ||
auto lod0 = nif->get<uint>( iBlock, "LOD0 Size" ); | ||
auto lod1 = nif->get<uint>( iBlock, "LOD1 Size" ); | ||
auto lod2 = nif->get<uint>( iBlock, "LOD2 Size" ); | ||
|
||
auto lod0tris = triangles.mid( 0, lod0 ); | ||
auto lod1tris = triangles.mid( lod0, lod1 ); | ||
auto lod2tris = triangles.mid( lod0 + lod1, lod2 ); | ||
|
||
// If Level2, render all | ||
// If Level1, also render Level0 | ||
switch ( scene->lodLevel ) { | ||
case Scene::Level2: | ||
if ( lod2tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod2tris.count() * 3, GL_UNSIGNED_SHORT, lod2tris.constData() ); | ||
case Scene::Level1: | ||
if ( lod1tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod1tris.count() * 3, GL_UNSIGNED_SHORT, lod1tris.constData() ); | ||
case Scene::Level0: | ||
default: | ||
if ( lod0tris.count() ) | ||
glDrawElements( GL_TRIANGLES, lod0tris.count() * 3, GL_UNSIGNED_SHORT, lod0tris.constData() ); | ||
break; | ||
} | ||
} | ||
|
||
if ( !Node::SELECTING ) | ||
scene->renderer->stopProgram(); | ||
|
||
glDisableClientState( GL_VERTEX_ARRAY ); | ||
glDisableClientState( GL_NORMAL_ARRAY ); | ||
glDisableClientState( GL_COLOR_ARRAY ); | ||
|
||
glDisable( GL_POLYGON_OFFSET_FILL ); | ||
} | ||
|
||
if ( scene->actionMode & Scene::Vertex ) { | ||
drawVerts(); | ||
} | ||
|
||
|
@@ -515,7 +517,7 @@ void BSShape::drawSelection() const | |
if ( scene->options & Scene::ShowNodes ) | ||
Node::drawSelection(); | ||
|
||
if ( isHidden() || !(scene->selMode & Scene::SelObject) ) | ||
if ( isHidden() || !(scene->actionMode & Scene::Object) ) | ||
return; | ||
|
||
auto idx = scene->currentIndex; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -384,23 +384,37 @@ template <typename T> bool interpolate( T & value, const QModelIndex & array, fl | |
{ | ||
// Quadratic | ||
/* | ||
In general, for keyframe values v1 = 0, v2 = 1 it appears that | ||
setting v1's corresponding "Backward" value to 1 and v2's | ||
corresponding "Forward" to 1 results in a linear interpolation. | ||
*/ | ||
Interpolate X, Y, and Z values independently, along a segment between | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 for improving docs |
||
two points, at an arbitrary time "x", using an Hermite Cubic spline. | ||
* The "v1" keyframe is the one previous in time to "x", | ||
* The "v2" keyframe is the next one, | ||
* The segment's backward derivative, "tangent 1" is stored as part of "v1" | ||
* The segment's forward derivative, "tangent 2" is stored as part of "v2" | ||
N.B. v2's backward derivate does not "belong" to the segment with v1, | ||
but rather to the segment with v3. Otherwise said, the key at t=0.0 | ||
can have a forward derivative, but it will not be used; the final key's | ||
backward derivative will also not be used. The segment between time 1 and 2 | ||
uses time 1's backward derivative and 2's forward derivative, not the 1's | ||
forward derivative and 2's backward derivative. | ||
|
||
The XYZ vectors used in the derivatives, if directed from V1 to V2, can appear | ||
as linear interpolation, however if their magnitude is not correct, then | ||
temporally there will be a speed up/down, even if the spacial trajectory is | ||
a straight line. | ||
*/ | ||
|
||
// Tangent 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
float t1 = nif->get<float>( frames.child( last, 0 ), "Backward" ); | ||
T t1 = nif->get<T>( frames.child( last, 0 ), "Backward" ); | ||
// Tangent 2 | ||
float t2 = nif->get<float>( frames.child( next, 0 ), "Forward" ); | ||
T t2 = nif->get<T>( frames.child( next, 0 ), "Forward" ); | ||
|
||
float x2 = x * x; | ||
float x3 = x2 * x; | ||
|
||
// Cubic Hermite spline | ||
// x(t) = (2t^3 - 3t^2 + 1)P1 + (-2t^3 + 3t^2)P2 + (t^3 - 2t^2 + t)T1 + (t^3 - t^2)T2 | ||
|
||
value = v1 * (2.0f * x3 - 3.0f * x2 + 1.0f) + v2 * (-2.0f * x3 + 3.0f * x2) + t1 * (x3 - 2.0f * x2 + x) + t2 * (x3 - x2); | ||
value = v1 * (2.0f * x3 - 3.0f * x2 + 1.0f) + v2 * (-2.0f * x3 + 3.0f * x2) + t1 * (x3 - 2.0f * x2 + x) + t2 * (x3 - x2); | ||
|
||
} return true; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting issue here