using System;
using System.Xml;
using System.Collections;
using CDAColladaNET.Import.Attributes;
// Copyright (c) 2005 Accelerated Pictures, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace ColladaNET.Import{
public class Mesh : NamedNode
{
#region Constants
private static readonly string kSources = "dae:source";
private static readonly string kVertexSource = "dae:vertices/dae:input[@semantic=\"POSITION\"]/@source";
private static readonly string kPolygonGroups = "dae:polygons";
private static readonly string kUrlIdHead = "descendant::*[@id=\"";
private static readonly string kUrlIdTail = "\"]";
#endregion
#region Accessors
private CDA.ResolverAttr mResolver;
public CDA.ResolverAttr Resolver { get { return mResolver; } }
private CDA.SourcesAttr mSources;
public CDA.SourcesAttr Sources { get { return mSources; } }
#region Vertices
private bool mbVertices = false;
private float [][] mVertices;
public float [][] Vertices
{
get
{
if ( mbVertices == false )
{
XmlNode vertexXmlSource = GetChildNodeByUrl( XmlSource.SelectSingleNode( kVertexSource , Collada.NS ).Value );
Source vertexSource = new Source( vertexXmlSource );
int stride = vertexSource.Techniques.GetByProfile( Collada.kCommon )[0].Accessors[0].Stride; // HACK: spec allows multiple accessors but doesn't say how to select which one
if ( stride != 3 )
{
throw new System.NotSupportedException( "Strides other than 3 are not supported at this time" );
}
mVertices = new float[vertexSource.Floats.Length/stride][];
int rawIndex = 0;
for( int vertIndex = 0 ; vertIndex < mVertices.Length ; vertIndex++ )
{
float [] vertex = new float[stride];
for ( int strideIndex = 0 ; strideIndex < stride ; strideIndex++ )
{
vertex[strideIndex] = vertexSource.Floats[rawIndex++];
}
mVertices[vertIndex] = vertex;
}
mbVertices = true;
}
return mVertices;
}
}
#endregion
#region PolygonGroups
private bool mbPolygonGroups = false;
private PolygonGroup [] mPolygonGroups;
public PolygonGroup [] PolygonGroups
{
get
{
if ( mbPolygonGroups == false )
{
XmlNodeList nodes = XmlSource.SelectNodes( kPolygonGroups , Collada.NS );
mPolygonGroups = new PolygonGroup[ nodes.Count ];
for ( int index = 0 ; index < nodes.Count ; index++ )
{
mPolygonGroups[index] = new PolygonGroup( nodes[index] , this );
}
mbPolygonGroups = true;
}
return mPolygonGroups;
}
}
#endregion
#endregion
#region Constructors
public Mesh( XmlNode xmlSource ) : base( xmlSource )
{
mSources = new CDA.SourcesAttr( xmlSource , kSources );
mResolver = new CDA.ResolverAttr();
//
// prepare to resolve sources
//
for( int sourceIndex = 0 ; sourceIndex < Sources.Values.Length ; sourceIndex++ )
{
Source source = Sources.Values[sourceIndex];
Resolver.Add( source );
}
}
#endregion
#region Private Methods
private XmlNode GetChildNodeByUrl( string url )
{
if ( url.StartsWith( "#" ) != true )
{
throw new System.NotImplementedException( "URLs currently need to start with #" );
}
string id = url.Remove( 0 , 1 );
string xpath = kUrlIdHead+id+kUrlIdTail;
XmlNode result = XmlSource.SelectSingleNode( xpath , Collada.NS );
if ( result == null )
{
throw new System.NotImplementedException( "Simple resolver unable to find child node" );
}
return result;
}
#endregion
}
}
|