Index: source/blender/modifiers/intern/MOD_util.c
===================================================================
--- source/blender/modifiers/intern/MOD_util.c	(Revision 33344)
+++ source/blender/modifiers/intern/MOD_util.c	(Arbeitskopie)
@@ -182,5 +182,6 @@
 	INIT_TYPE(ShapeKey);
 	INIT_TYPE(Solidify);
 	INIT_TYPE(Screw);
+	INIT_TYPE(MeshCache);
 #undef INIT_TYPE
 }
Index: source/blender/modifiers/intern/MOD_meshcache.c
===================================================================
--- source/blender/modifiers/intern/MOD_meshcache.c	(Revision 0)
+++ source/blender/modifiers/intern/MOD_meshcache.c	(Revision 0)
@@ -0,0 +1,415 @@
+/*
+* $Id: MOD_meshcache.c by Ivo Grigull (Loolarge)
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software  Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2005 by the Blender Foundation.
+* All rights reserved.
+*
+* Contributor(s): Daniel Dunbar
+*                 Ton Roosendaal,
+*                 Ben Batt,
+*                 Brecht Van Lommel,
+*                 Campbell Barton
+*
+*		  Mesh-cache modifier by Ivo Grigull (Loolarge)
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
+
+
+
+#include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_lattice.h"
+#include "BKE_modifier.h"
+#include "BKE_deform.h"
+#include "BKE_utildefines.h"
+#include "BKE_scene.h"
+
+#include "depsgraph_private.h"
+
+#include "MOD_util.h"
+
+
+static int dependsOnTime(ModifierData *UNUSED(md))
+{
+	return 1;
+}
+
+
+
+void MeshCacheModifier_do(MeshCacheModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, float frame)
+{
+	//char filename[] = "//home//ivo/mdd//test.mdd";
+	FILE *f;
+
+	int i, n;
+	int file_vertex_count, num_frames;
+	//float time;
+	float size[3] = {1,1,-1};	
+		
+	float mat[4][4] = MAT4_UNITY;
+	float sizemat[4][4];
+	float matfinal[4][4];
+	float interpolate_factor;	
+	float tmp;	
+	float thispos[3], nextpos[3];	
+	
+	
+	// Try finding a mdd or pc2 file-extension
+	if( strstr( smd->filepath, ".mdd" ) != NULL)
+	    smd->type = MOD_MESHCACHE_TYPE_MDD;
+	
+	else if ( strstr( smd->filepath, ".pc2") != NULL)
+	    smd->type = MOD_MESHCACHE_TYPE_PC2;
+	
+	else{
+	    printf("No recognized file extension found in '%s'", smd->filepath );
+	    return;
+	}
+	
+
+
+	// Load file and read header infos
+	f = fopen( smd->filepath, "rb");
+	if( f == NULL ) 
+	{
+	    printf("Could not load file '%s'\n", smd->filepath);
+	    return;
+	}
+	
+	
+	
+	if( smd->type == MOD_MESHCACHE_TYPE_MDD	)
+	{
+	    fread( &num_frames, sizeof(int), 1, f);
+	    SWITCH_INT( num_frames );
+	    smd->numframes = num_frames;
+	    
+	    fread( &file_vertex_count, sizeof(int), 1, f);
+	    SWITCH_INT( file_vertex_count );
+	    smd->vertcount = file_vertex_count;
+	    
+	    
+	    // not sure what is is for really, but its part of the file format
+	    // Skipping it for now.
+	    // supposedly it is the time for each frame, but i get weird results
+	    //for( i=0; i<num_frames; i++) fread( &time, sizeof(float), 1, f );
+	    //SWITCH_INT(time);
+	    //printf("Time: %f\n", time);
+	    fseek( f, num_frames*sizeof(int), SEEK_CUR );
+	    
+	}
+	
+	
+	else if( smd->type == MOD_MESHCACHE_TYPE_PC2 )
+	{
+	    char header[12];
+	    int huh;
+    	    float start, sampling;
+	    
+	    
+	    fread( &header, 12, 1, f);
+	    fread( &huh, sizeof(int), 1, f);
+	    fread( &file_vertex_count, sizeof(int), 1, f);
+	    fread( &start, sizeof(float), 1, f);
+	    fread( &sampling, sizeof(float), 1, f);
+	    fread( &num_frames, sizeof(int), 1, f);
+	    
+	    //smd->start_offset = (float)start; // is being reset all the time, gotta fix it later
+	    smd->offset_internal = start;
+	    smd->numframes = num_frames;
+	    smd->vertcount = file_vertex_count;
+	    
+	    //printf("%s\n", header);
+	    //printf("%i %i %f %f %i\n", huh, file_vertex_count, start, sampling, num_frames);
+	    
+	}
+	
+	
+	
+	if( file_vertex_count != numVerts )
+	{
+	    printf( "MeshCache_Modifier: Wrong vertex count. Object: %d File: %d %s\n", numVerts, file_vertex_count, smd->filepath);
+	    fclose(f);
+	    return;
+	}
+
+	// Add
+	if( smd->flag & MOD_MESHCACHE_FRAME_ABSOLUTE)
+	
+	    frame = smd->start_offset;
+	else 
+	    frame += smd->start_offset;	
+	
+	// Add internal offset
+	frame += (float)smd->offset_internal;
+	
+	//frame *= smd->time_scale_factor;
+	
+	interpolate_factor = (frame - (int) frame);
+	//printf("Factor: %f\n", interpolate_factor);
+	frame = (int)frame;
+	
+	// if out of range, do nothing
+	if( frame-smd->offset_internal >= num_frames || frame-smd->offset_internal < 0.0f) 
+	{
+	    fclose(f);
+	    return;
+	}
+
+	
+	if( smd->type == MOD_MESHCACHE_TYPE_MDD	)
+	{
+	    // Transform offset Matrix to fit with Lightwave 3D
+	    rotate_m4( mat, 'X', DEG2RAD(90.0f) );		
+	    size_to_mat4(sizemat, size );
+	    mul_m4_m4m4( matfinal, sizemat, mat );
+	}
+	else if( smd->type == MOD_MESHCACHE_TYPE_PC2	)
+	{
+	    // Transform offset Matrix to fit with pepeland's maya file
+	    rotate_m4( mat, 'X', DEG2RAD(90.0f) );
+	    rotate_m4( mat, 'Y', DEG2RAD(0.0f) );
+	    rotate_m4( mat, 'Z', DEG2RAD(0.0f) );
+	    size[0]=1.0f; size[1]=1.0f; size[2]=1.0f; // This is the scaling, x,y,z
+	    size_to_mat4(sizemat, size );
+	    mul_m4_m4m4( matfinal, sizemat, mat );	    
+	}
+
+	
+	// seek desired frame
+	fseek( f, frame*file_vertex_count*sizeof(float)*3, SEEK_CUR );
+
+	
+	// Read vertices for current frame
+	{
+	    static float pos[3], out[3];
+	    for( i=0; i<numVerts; i++)
+	    {
+		for( n=0; n<3; n++)
+		{
+		    fread( &tmp, sizeof(float), 1, f);
+		    if( smd->type == MOD_MESHCACHE_TYPE_MDD	)
+			SWITCH_INT(tmp); // Endianness - not sure what happens on other OS/CPUs
+		    pos[n] = tmp;
+		}
+		
+		if( smd->type == MOD_MESHCACHE_TYPE_MDD	)
+		{
+		    mul_v3_m4v3( out, matfinal, pos );
+		    VECCOPY( pos, out )
+		}
+		else if( smd->type == MOD_MESHCACHE_TYPE_PC2	)
+		{
+		    mul_v3_m4v3( out, matfinal, pos );
+		    VECCOPY( pos, out )
+		}		
+		
+		
+		if( smd->flag & MOD_MESHCACHE_INTERPOLATE)		
+		    VECCOPY( vertexCos[i], pos)
+		else
+		{ // In order to be able to work additively with shape keys,
+		  // we substract the basemesh's verts from the results
+		    Mesh *me = ob->data;
+		    
+		    add_v3_v3( vertexCos[i], pos );
+		    
+		    sub_v3_v3( vertexCos[i], me->mvert[i].co );
+		}
+	    }
+	}
+
+	// Read next frame and do linear interpolation
+	if( smd->flag & MOD_MESHCACHE_INTERPOLATE)
+	{
+	    
+	    // Read vertices for current frame
+	    {
+		float pos[3], out[3], tmp;
+		for( i=0; i<numVerts; i++)
+		{
+		    for( n=0; n<3; n++)
+		    {
+			fread( &tmp, sizeof(float), 1, f);
+			if( smd->type == MOD_MESHCACHE_TYPE_MDD	)
+			    SWITCH_INT(tmp); // Endianness - not sure what happens on other OS/CPUs
+			pos[n] = tmp;
+		    }
+		    
+		    // if mdd, apply offset transform to next frame too
+		    if( smd->type == MOD_MESHCACHE_TYPE_MDD )
+		    {
+			mul_v3_m4v3( out, matfinal, pos );
+			VECCOPY(pos, out);
+		    }
+
+		    
+		    { // interpolate (linear)
+						
+			VECCOPY( thispos, vertexCos[i]);			
+			VECCOPY( nextpos, pos );
+			sub_v3_v3( nextpos, thispos );
+			mul_v3_fl( nextpos, interpolate_factor );
+			add_v3_v3( nextpos, thispos );			
+			
+			VECCOPY( vertexCos[i], nextpos);
+			//add_v3_v3( vertexCos[i], nextpos );
+			
+			
+			// Shape key stuff not working yet when interpolating -
+			{ // In order to be able to work additively with shape keys,
+			  // we substract the basemesh's verts from the results
+			    //Mesh *me = ob->data;
+			    //sub_v3_v3( vertexCos[i], me->mvert[i].co );
+			}
+			
+		    }
+		    
+		}
+	    }
+    
+	    
+	}
+	
+	
+	fclose(f);
+}
+
+
+
+
+/* MeshCache */
+static void initData(ModifierData *md)
+{
+	MeshCacheModifierData *smd = (MeshCacheModifierData*) md;
+
+	smd->start_offset = 0;
+	//smd->filepath = "";
+	smd->time_scale_factor = 1.0f;
+	smd->flag = 0;
+	smd->offset_internal = 0;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+	MeshCacheModifierData *smd  = (MeshCacheModifierData*)md;
+	MeshCacheModifierData *tsmd = (MeshCacheModifierData*)target;
+
+	strcpy( tsmd->filepath, smd->filepath );
+	tsmd->flag = smd->flag;
+	tsmd->start_offset = smd->start_offset;
+	//tsmd->time_scale_factor = smd->time_scale_factor;
+}
+
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+	//MeshCacheModifierData *smd = (MeshCacheModifierData *)md;
+	CustomDataMask dataMask = 0;
+
+	return dataMask;
+}
+
+static void deformVerts(ModifierData *md, Object *ob,
+						DerivedMesh *derivedData,
+						float (*vertexCos)[3],
+						int numVerts,
+						int UNUSED(useRenderParams),
+						int UNUSED(isFinalCalc))
+{
+	DerivedMesh *dm = derivedData;
+	CustomDataMask dataMask = requiredDataMask(ob, md);
+	static float curfra;
+	
+	curfra = BKE_curframe(md->scene);
+
+	/* we implement requiredDataMask but thats not really usefull since
+	   mesh_calc_modifiers pass a NULL derivedData */
+	
+	if(dataMask)
+		dm= get_dm(ob, NULL, dm, NULL, 0);
+	
+	MeshCacheModifier_do((MeshCacheModifierData*)md, ob, dm, vertexCos, numVerts, curfra );
+
+	if(dm != derivedData)
+		dm->release(dm);
+}
+
+static void deformVertsEM(ModifierData *md, Object *ob,
+						struct EditMesh *editData,
+						DerivedMesh *derivedData,
+						float (*vertexCos)[3],
+						int numVerts)
+{
+	DerivedMesh *dm = derivedData;
+	CustomDataMask dataMask = requiredDataMask(ob, md);
+
+	static float curfra;
+	
+	curfra = BKE_curframe(md->scene);
+	
+	/* we implement requiredDataMask but thats not really usefull since
+	   mesh_calc_modifiers pass a NULL derivedData */
+	if(dataMask)
+		dm= get_dm(ob, editData, dm, NULL, 0);
+	
+	MeshCacheModifier_do((MeshCacheModifierData*)md, ob, dm, vertexCos, numVerts, curfra);
+
+	if(dm != derivedData)
+		dm->release(dm);
+}
+
+
+ModifierTypeInfo modifierType_MeshCache = {
+	/* name */              "MeshCache",
+	/* structName */        "MeshCacheModifierData",
+	/* structSize */        sizeof(MeshCacheModifierData),
+	/* type */              eModifierTypeType_OnlyDeform,
+
+	/* flags */             eModifierTypeFlag_AcceptsMesh
+							| eModifierTypeFlag_SupportsEditmode,
+//	/* flags */             eModifierTypeFlag_AcceptsMesh
+//							| eModifierTypeFlag_AcceptsCVs
+//							| eModifierTypeFlag_SupportsEditmode
+//							| eModifierTypeFlag_EnableInEditmode,
+
+	/* copyData */          copyData,
+	/* deformVerts */       deformVerts,
+	/* deformVertsEM */     deformVertsEM,
+	/* deformMatricesEM */  0,
+	/* applyModifier */     0,
+	/* applyModifierEM */   0,
+	/* initData */          initData,
+	/* requiredDataMask */  0,
+	/* freeData */          0,
+	/* isDisabled */        0,
+	/* updateDepgraph */    0,
+	/* dependsOnTime */     dependsOnTime,
+	/* dependsOnNormals */	0,
+	/* foreachObjectLink */ 0,
+	/* foreachIDLink */     0,
+};
Index: source/blender/modifiers/MOD_modifiertypes.h
===================================================================
--- source/blender/modifiers/MOD_modifiertypes.h	(Revision 33344)
+++ source/blender/modifiers/MOD_modifiertypes.h	(Arbeitskopie)
@@ -67,6 +67,7 @@
 extern ModifierTypeInfo modifierType_ShapeKey;
 extern ModifierTypeInfo modifierType_Solidify;
 extern ModifierTypeInfo modifierType_Screw;
+extern ModifierTypeInfo modifierType_MeshCache;
 
 /* MOD_util.c */
 void modifier_type_init(ModifierTypeInfo *types[]);
Index: source/blender/modifiers/CMakeLists.txt
===================================================================
--- source/blender/modifiers/CMakeLists.txt	(Revision 33344)
+++ source/blender/modifiers/CMakeLists.txt	(Arbeitskopie)
@@ -56,6 +56,7 @@
 	intern/MOD_lattice.c
 	intern/MOD_mask.c
 	intern/MOD_meshdeform.c
+	intern/MOD_meshcache.c	
 	intern/MOD_mirror.c
 	intern/MOD_multires.c
 	intern/MOD_none.c
Index: source/blender/makesrna/intern/rna_modifier.c
===================================================================
--- source/blender/makesrna/intern/rna_modifier.c	(Revision 33344)
+++ source/blender/makesrna/intern/rna_modifier.c	(Arbeitskopie)
@@ -75,6 +75,7 @@
 	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
 	{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
 	{eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
+	{eModifierType_MeshCache, "MESHCACHE", ICON_MOD_WAVE, "MeshCache", ""},
 	{0, "", 0, "Simulate", ""},
 	{eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
 	{eModifierType_Collision, "COLLISION", ICON_MOD_PHYSICS, "Collision", ""},
@@ -175,6 +176,8 @@
 			return &RNA_SolidifyModifier;
 		case eModifierType_Screw:
 			return &RNA_ScrewModifier;
+		case eModifierType_MeshCache:
+			return &RNA_MeshCacheModifier;
 		default:
 			return &RNA_Modifier;
 	}
@@ -2242,6 +2245,62 @@
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
 }
 
+
+static void rna_def_modifier_meshcache(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna= RNA_def_struct(brna, "MeshCacheModifier", "Modifier");
+	RNA_def_struct_ui_text(srna, "MDD/PC2 MeshCache Modifier", "Displays lighwave mdd cache");
+	RNA_def_struct_sdna(srna, "MeshCacheModifierData");
+	RNA_def_struct_ui_icon(srna, ICON_MOD_SCREW);
+
+	prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+	//RNA_def_property_string_funcs(prop, "rna_MultiresModifier_filepath_get", "rna_MultiresModifier_filepath_length", "rna_MultiresModifier_filepath_set");
+	RNA_def_property_ui_text(prop, "File Path", "Path to external mesh-cache file (*.mdd)");
+	RNA_def_property_string_sdna(prop, NULL, "filepath");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop= RNA_def_property(srna, "start_offset", PROP_FLOAT, PROP_TIME);
+	RNA_def_property_float_sdna(prop, NULL, "start_offset");
+	RNA_def_property_ui_text(prop, "Start offset", "Where to put frame first frame of the cache");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop= RNA_def_property(srna, "time_scale_factor", PROP_FLOAT, PROP_TIME);
+	RNA_def_property_float_sdna(prop, NULL, "time_scale_factor");
+	RNA_def_property_ui_text(prop, "Speed factor", "scale timing");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop= RNA_def_property(srna, "numframes", PROP_INT, PROP_TIME);
+	RNA_def_property_int_sdna(prop, NULL, "numframes");
+	RNA_def_property_ui_text(prop, "Amount of frames loaded", "number of frames");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop= RNA_def_property(srna, "vertcount", PROP_INT, PROP_TIME);
+	RNA_def_property_int_sdna(prop, NULL, "vertcount");
+	RNA_def_property_ui_text(prop, "Amount of vertices in file", "number of verts");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop= RNA_def_property(srna, "use_absolute", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MESHCACHE_FRAME_ABSOLUTE);
+	RNA_def_property_ui_text(prop, "Let me animate the time", "If you want to animate via f-curve only");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+	
+	prop= RNA_def_property(srna, "use_interpolation", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MESHCACHE_INTERPOLATE);
+	RNA_def_property_ui_text(prop, "Interpolate", "Interpolate between frames (good for slow motion and retiming)");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+	
+/*	prop= RNA_def_property(srna, "use_from_memory", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MESHCACHE_FROM_MEMORY);
+	RNA_def_property_ui_text(prop, "To memory", "Load entire File into memory instead reading frames from disk");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+*/
+	
+}
+
+
 void RNA_def_modifier(BlenderRNA *brna)
 {
 	StructRNA *srna;
@@ -2333,6 +2392,7 @@
 	rna_def_modifier_smoke(brna);
 	rna_def_modifier_solidify(brna);
 	rna_def_modifier_screw(brna);
+	rna_def_modifier_meshcache(brna);
 }
 
 #endif
Index: source/blender/makesrna/RNA_access.h
===================================================================
--- source/blender/makesrna/RNA_access.h	(Revision 33344)
+++ source/blender/makesrna/RNA_access.h	(Arbeitskopie)
@@ -291,6 +291,7 @@
 extern StructRNA RNA_MaterialVolume;
 extern StructRNA RNA_Menu;
 extern StructRNA RNA_Mesh;
+extern StructRNA RNA_MeshCacheModifier;
 extern StructRNA RNA_MeshColor;
 extern StructRNA RNA_MeshColorLayer;
 extern StructRNA RNA_MeshDeformModifier;
Index: source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- source/blender/makesdna/DNA_modifier_types.h	(Revision 33344)
+++ source/blender/makesdna/DNA_modifier_types.h	(Arbeitskopie)
@@ -69,6 +69,7 @@
 	/* placeholder, keep this so durian files load in
 	 * trunk with the correct modifier once its merged */
 	eModifierType_Warp,
+	eModifierType_MeshCache,
 	NUM_MODIFIER_TYPES
 } ModifierType;
 
@@ -722,5 +723,22 @@
 #define MOD_SCREW_OBJECT_OFFSET	(1<<2)
 // #define MOD_SCREW_OBJECT_ANGLE	(1<<4)
 
+typedef struct MeshCacheModifierData {
+	ModifierData modifier;
+	float	    start_offset;
+	float	    time_scale_factor;
+	char	    filepath[256];
+	short	    flag, type;
+	int	    numframes, vertcount;
+	int	    offset_internal;
+	
+} MeshCacheModifierData;
 
+#define MOD_MESHCACHE_FRAME_ABSOLUTE	(1<<0)
+#define MOD_MESHCACHE_INTERPOLATE	(1<<1)
+#define MOD_MESHCACHE_FROM_MEMORY	(1<<2)
+
+#define MOD_MESHCACHE_TYPE_MDD		(1<<1)
+#define MOD_MESHCACHE_TYPE_PC2		(1<<2)
+
 #endif
Index: release/scripts/ui/properties_data_modifier.py
===================================================================
--- release/scripts/ui/properties_data_modifier.py	(Revision 33344)
+++ release/scripts/ui/properties_data_modifier.py	(Arbeitskopie)
@@ -695,7 +695,28 @@
         col.prop(md, "width", slider=True)
         col.prop(md, "narrowness", slider=True)
 
+    def MESHCACHE(self, layout, ob, md):
+        #~ split = layout.split(percentage=0.25)
 
+        row = layout.row()
+        row.prop(md, "filepath")
+        
+        row = layout.row()
+        row.label(text= ("Frames: %d" % md.numframes) )
+        row.label(text= ("Vertices: %d" % md.vertcount) )
+        
+        row = layout.row()
+        row.prop(md, "start_offset")
+        #row = layout.row()
+        #row.prop(md, "time_scale_factor")
+        row = layout.row()
+        row = layout.row()
+        row.prop(md, "use_absolute")
+        row.prop(md, "use_interpolation")
+        #~ row = layout.row()
+        #~ row.prop(md, "use_from_memory")
+
+
 def register():
     pass
 
