Something went wrong on our end
-
stefan authored
-Enable/Disable a rendermode -Get RenderMode name Added RenderModes to Scene Win git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1761 5a81b35b-ba03-0410-adc8-b2c5c5119f08
stefan authored-Enable/Disable a rendermode -Get RenderMode name Added RenderModes to Scene Win git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1761 5a81b35b-ba03-0410-adc8-b2c5c5119f08
trace_renderer.cc 7.56 KiB
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#include <ost/gfx/entity.hh>
#include "trace_renderer.hh"
namespace ost { namespace gfx { namespace impl {
TraceRenderer::TraceRenderer(BackboneTrace& trace):
TraceRendererBase(trace, 1), options_(new TraceRenderOptions())
{
this->SetName("Trace");
}
void TraceRenderer::PrepareRendering()
{
TraceRendererBase::PrepareRendering();
va_.Clear();
this->PrepareRendering(trace_subset_, va_, false);
sel_va_.Clear();
if (this->HasSelection()) {
this->PrepareRendering(sel_subset_, sel_va_, true);
sel_va_.SetLighting(false);
}
}
void TraceRenderer::PrepareRendering(TraceSubset& trace_subset,
IndexedVertexArray& va, bool is_sel)
{
const Color& sel_clr=this->GetSelectionColor();
float radius=options_->GetTubeRadius();
if (is_sel) {
radius+=0.1;
}
int n=8*options_->GetArcDetail();
if(options_!=NULL) {
va.SetLighting(true);
va.SetCullFace(false);
for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
const NodeListSubset& nl=trace_subset[node_list];
geom::Vec3 cursor_pos;
geom::Mat3 cursor_ori;
if (nl.GetSize()==2) {
VertexID p0, p1;
if (nl.AtStart()==0) {
p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
is_sel ? sel_clr : nl[0].color1);
p1=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2,
geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
} else {
p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2,
geom::Vec3(), is_sel ? sel_clr : nl[0].color1);
p1=va.Add(nl[1].atom.GetPos(),
geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
}
va.AddLine(p0, p1);
continue;
}
if (nl.GetSize()<3) {
continue;
}
VertexID p0;
geom::Vec3 z=geom::Normalize(nl[1].atom.GetPos()-nl[0].atom.GetPos());
geom::Vec3 y=geom::OrthogonalVector(z);
geom::Vec3 x=geom::Cross(y, z);
cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1],
x[2], y[2], z[2]);
if (nl.AtStart()==0) {
cursor_pos=nl[0].atom.GetPos();
} else {
cursor_pos=(nl[0].atom.GetPos()+nl[1].atom.GetPos())/2;
}
p0=this->AddCappedProfile(va, is_sel? sel_clr : nl[0].color1,
cursor_pos, cursor_ori, radius, true, n);
for (int i=1; i<nl.GetSize()-1;++i) {
const NodeEntry& entry=nl[i];
geom::Vec3 old_dir=geom::Normalize(entry.atom.GetPos()-cursor_pos);
cursor_pos=entry.atom.GetPos();
geom::Vec3 z=geom::Normalize(nl[i+1].atom.GetPos()-cursor_pos);
geom::Vec3 y=geom::Normalize(geom::Cross(z, cursor_ori.GetCol(0)));
geom::Vec3 x=geom::Normalize(geom::Cross(y, z));
geom::Vec3 iz=geom::Normalize(cursor_ori.GetCol(2)+z);
geom::Vec3 iy=geom::Normalize(geom::Cross(cursor_ori.GetCol(2), z));
geom::Vec3 ix=geom::Normalize(geom::Cross(iy, iz));
geom::Mat3 i_ori=geom::Mat3(ix[0], iy[0], iz[0], ix[1], iy[1], iz[1],
ix[2], iy[2], iz[2]);
cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1],
x[2], y[2], z[2]);
// TODO. The intersection of two cylinders is an ellipse. Use an
// elliptic profile instead of a circular profile.
VertexID p1=this->AddCircularProfile(va, is_sel ? sel_clr : entry.color1,
cursor_pos, i_ori, radius, n);
this->ConnectProfiles(p0, p1, n, old_dir, va);
p0=p1;
}
const NodeEntry& entry=nl[nl.GetSize()-1];
if (nl.AtEnd()==0) {
cursor_pos=entry.atom.GetPos();
} else {
cursor_pos=(entry.atom.GetPos()+nl[nl.GetSize()-2].atom.GetPos())*0.5;
}
VertexID p1 =this->AddCappedProfile(va, is_sel ? sel_clr : entry.color1,
cursor_pos, cursor_ori,
radius, false, n);
this->ConnectProfiles(p0, p1, n, cursor_ori.GetCol(2), va);
}
}
sel_state_=0;
state_=0;
}
VertexID TraceRenderer::AddCappedProfile(IndexedVertexArray& va,
const Color& color,
const geom::Vec3& center,
const geom::Mat3& ori, float radius,
bool flip_normal,
int n)
{
VertexID center_id=va.Add(center, geom::Vec3(), color);
VertexID first=this->AddCircularProfile(va, color, center, ori, radius, n);
for (int i=0; i<n; ++i) {
va.AddTriN(center_id, first+i, first+((i+1) % n));
}
return first;
}
VertexID TraceRenderer::AddCircularProfile(IndexedVertexArray& va,
const Color& color,
const geom::Vec3& center,
const geom::Mat3& ori,
float radius,
int n)
{
float delta_angle=2*M_PI/n;
VertexID f=0;
geom::Vec3 normal=ori.GetRow(2);
for (int i=0; i<n; ++i) {
geom::Vec3 normal=ori*geom::Vec3(cos(i*delta_angle),
sin(i*delta_angle), 0.0);
VertexID x=va.Add(center+normal*radius, normal, color);
if (i==0) {
f=x;
}
}
return f;
}
void TraceRenderer::ConnectProfiles(VertexID prof0, VertexID prof1, int n,
const geom::Vec3& dir,
IndexedVertexArray& va)
{
// avoid twisting
int off=0;
float best=0.0;
geom::Vec3 pp=va.GetVert(prof0);
for (int i=0; i<n; ++i) {
geom::Vec3 dir2=geom::Normalize(va.GetVert(prof1+i)-pp);
float dot=fabs(geom::Dot(dir, dir2));
if (best<dot) {
best=dot;
off=i;
}
}
for (int i=0; i<n; ++i) {
VertexID i1=prof1+((i+off) % n), i2=prof1+((i+off+1) % n);
VertexID i3=prof0+i, i4=prof0+((i+1)%n);
va.AddTriN(i1, i2, i3);
va.AddTriN(i2, i3, i4);
}
}
void TraceRenderer::Render()
{
}
bool TraceRenderer::CanSetOptions(RenderOptionsPtr& render_options)
{
return render_options.get()->GetRenderMode()==RenderMode::TRACE;
}
void TraceRenderer::SetOptions(RenderOptionsPtr& render_options)
{
options_=boost::static_pointer_cast<TraceRenderOptions>(render_options);
}
RenderOptionsPtr TraceRenderer::GetOptions()
{
return options_;
}
TraceRenderer::~TraceRenderer()
{
}
}}}